I have a Gradle project which uses Spring's dependency management plugin to define a list of dependency versions. I am also using the Maven plugin to deploy the project to a Maven repository.
I would like to be able to deploy this as a Maven bill of materials (BOM) so that I can use it in other Gradle projects to define my dependency versions. I have been able to get this to work so long as I also deploy a JAR file. However, the JAR is completely empty and superfluous. My goal is to generate and deploy just the POM file, like I would be able to do if this were a Maven project with a "pom" packaging.
If I manually exclude the JAR from the list of artifacts to be published, then nothing gets installed, not even the POM file.
This is a test build to demonstrate the issue:
group 'test'
version '1.0.0-SNAPSHOT'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.1.RELEASE' //Matches the Spring IO version
}
}
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven'
dependencyManagement {
dependencies {
dependency 'cglib:cglib-nodep:3.2.4'
dependency 'junit:junit:4.12'
}
}
////Uncommenting this causes nothing at all to be deployed:
//jar.enabled = false
//configurations.archives.artifacts.with { archives ->
// archives.removeAll { it.type == 'jar' }
//}
The above correctly produces and installs the following POM file into my local Maven repo:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>gradle-pom-packaging-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.2.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
However, it also installs a JAR file that is empty save for the MANIFEST.MF file.
I was able to successfully get this working using the maven-publish
plugin. However, I'm also making use of the Gradle Sonatype Nexus plugin to publish the artifact to a Nexus instance. As this builds upon the maven
plugin, the maven-publish
plugin will not work for my needs. The following is all I needed to add to get it working with the maven-publish
plugin:
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
}
}
}
Is there a way to generate and deploy just the POM file using the maven
Gradle plugin, like I would be able to do if this were a Maven project with a "pom" packaging?
Gradle ships with a Maven plugin, which adds support to convert a Gradle file to a Maven POM file. It can also deploy artifacts to Maven repositories. The plugin uses the group and the version present in the Gradle file and adds them to the POM file. Also, it automatically takes the artifactId from the directory name.
Maven's dependency management includes the concept of a bill-of-materials (bom). A bom is a special kind of pom that is used to control the versions of a project's dependencies and provides a central place to define and update those versions.
You can name the task createPom to anyTaskName as you like. Then just run gradle clean or grale build or simply gradle createPom . This will generate it as pom. xml in the root of the project.
In the end, what you choose will depend primarily on what you need. Gradle is more powerful. However, there are times that you really do not need most of the features and functionalities it offers. Maven might be best for small projects, while Gradle is best for bigger projects.
In Gradle 6+ versions, we can use Gradle Java Platform Plugin to publish a maven-bom without many configurations and scripting.
group 'test.platform.simple.bom'
version '1.0.0-SNAPSHOT'
repositories {
maven {
mavenCentral()
}
}
apply plugin: 'java-platform'
apply plugin: 'maven-publish'
javaPlatform {
allowDependencies()
}
dependencies {
constraints {
api 'junit:junit:4.12'
api 'cglib:cglib-nodep:3.2.4'
// runtime 'org.postgresql:postgresql:42.2.5' <-- runtime constraint
// api project(":core") <-- constraint from local project
}
// api platform('com.fasterxml.jackson:jackson-bom:2.9.8') <-- constraint from another platform
}
publishing {
publications {
maven(MavenPublication) {
from components.javaPlatform
}
}
}
Dependencies to be managed can be defined under dependencies as api or runtime constraints. Constraints can be utilized to manage dependencies from a local project as well as from another platform/bom. Please note that we need to configure a Maven publication that uses the javaPlatform component to get it published as a maven bom artifact.
Tha acdcjunior's answer can be improved a little.
Dependencies in the build.gradle
can by declared in the standard dependencies
section. Also, in pom.xml
of a BOM versions should be declared in dependencyManagement
section:
plugins {
id 'java-library'
id 'maven-publish'
}
group = 'com.example'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
api 'org.apache.commons:commons-lang3:3.9'
api 'org.postgresql:postgresql:42.2.11'
}
publishing {
repositories {
maven {
url = "$nexusUrl"
credentials {
username = "$nexusUsername"
password = "$nexusPassword"
}
}
}
publications {
maven(MavenPublication) {
groupId = "${project.group}"
artifactId = "${project.name}"
version = "${project.version}"
pom.withXml {
asNode().children().last() + {
resolveStrategy = Closure.DELEGATE_FIRST
name 'My BOM'
description 'My Bill of Materials (BOM)'
dependencyManagement {
dependencies {
project.configurations.each { conf ->
conf.dependencies.each { dep ->
dependency {
groupId "${dep.group}"
artifactId "${dep.name}"
version "${dep.version}"
}
}
}
}
}
}
}
}
}
}
The resulting pom.xml
can be published to Nexus with the command
./gradlew clean build publish -i
or to a local Maven repo (~/.m2/repository
)
./gradlew clean build pTML -i
This notation is not only shorter but also allows processing dependencies. For example, perform vulnerabilities scanning using OWASP Dependency-Check plugin:
plugins {
//...
id 'org.owasp.dependencycheck' version '5.3.0'
}
dependencyCheck {
failBuildOnCVSS = 9 //Critical Severity
}
check.dependsOn dependencyCheckAnalyze
You could have a build.gradle
such as:
apply plugin: 'maven-publish'
apply plugin: 'signing'
publishing {
repositories {
maven {
def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username ossrhUsername
password ossrhPassword
}
}
}
publications {
maven(MavenPublication) {
groupId = 'com.example.id'
artifactId = 'my-artifact-id'
version = '1.0.0'
pom.withXml {
asNode().children().last() + {
resolveStrategy = Closure.DELEGATE_FIRST
name 'My Lib Name'
description 'My Lib Description'
url 'https://example.com/id/lib'
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
scm {
connection 'scm:git:[email protected]:acdcjunior/lib/id.git'
developerConnection 'scm:git:[email protected]:acdcjunior/lib/id.git'
url '[email protected]/id.git'
}
developers {
developer {
id 'someone'
name 'Someone Name'
email '[email protected]'
}
}
dependencies {
dependency {
groupId 'com.example.other'
artifactId 'some-dependency'
version '1.0.0'
}
dependency {
groupId 'org.apache.commons'
artifactId 'commons-lang3'
version '3.9'
}
}
}
}
}
}
}
signing {
sign publishing.publications.maven
}
Example of a project using this: https://github.com/acdcjunior/domain-id/blob/master/domain-id-all/build.gradle
You should consider that plugin which has a DSL to create BOMs the gradle way :
https://github.com/xvik/gradle-pom-plugin
Julien
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With