An important part of a Maven publication is the POM file. We already saw that Gradle added a generatePom<publicationName>
task to our project. Furthermore, we can define some properties of the POM file inside a publication configuration. Gradle also offers a hook to customize the generated POM file even further.
Gradle uses the project's version
, group
, and name
properties in the generated POM file. We create a new example build file where we define the project properties so that they are included in the POM file. The following code shows this:
apply plugin: 'maven-publish' apply plugin: 'java' // Defined project properties, that are // used in the generated POM file. // The name of the project is by default // the directory name, but we can // change it via a settings.gradle file // and the rootProject.name property. version = '2.1.RELEASE' group = 'book.gradle' repositories { jcenter() } dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' } publishing { publications { sample(MavenPublication) { from components.java } } }
Now we execute the generatePomFileForSamplePublication
task. The pom-default.xml
file is created in the build/publications/sample
directory. If we open the file, we can see that the groupId
, artifactId
, and version
elements are filled with the values from our Gradle build file. This is shown in the following code:
<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>book.gradle</groupId> <artifactId>sample</artifactId> <version>2.1.RELEASE</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> <scope>runtime</scope> </dependency> </dependencies> </project>
We can override the values for groupId
, artifactId
, and version
inside a publication configuration. We use the groupId
, artifactId
, and version
properties to set values other than the default values taken from the project properties. In the next example build file, we will use these methods to set the values:
apply plugin: 'maven-publish' apply plugin: 'java' version = '2.1.DEVELOPMENT' group = 'book.gradle' repositories { jcenter() } dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' } publishing { publications { sample(MavenPublication) { groupId = 'book.sample.gradle' artifactId ='bookSample' version = '2.1' from components.java } } }
Upon executing the generatePomFileForSamplePublication
task again, we can see the new values in the generated POM file. The following code shows this:
<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>book.sample.gradle</groupId> <artifactId>bookSample</artifactId> <version>2.1</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> <scope>runtime</scope> </dependency> </dependencies> </project>
You may already have noticed that the generatePomFile<publicationName>Publication
task also added a dependencies
element in the generated POM file. The dependencies of our project are added as runtime dependencies in the POM file. This happens because we use the from
method with the components.java
value inside our publication configuration. The Java software component not only adds the jar
archive tasks as an artifact, but also turns the project dependencies in to Maven runtime dependencies. If we use an archive task to define an artifact, the dependencies
element is not added to the POM file.
In the following example build file, we use the artifact
method to define the publication:
apply plugin: 'maven-publish' apply plugin: 'java' // Defined project properties, that are // used in the generated POM file. // The name of the project is by default // the directory name, but we can // change it via a settings.gradle file // and the rootProject.name property. version = '2.1.RELEASE' group = 'book.gradle' repositories { jcenter() } dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' } publishing { publications { sample(MavenPublication) { artifact jar } } }
When we run the generatePomFileForSamplePublication
task from the command line, the POM file is generated. The contents of the POM file are now as follows:
<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>book.gradle</groupId> <artifactId>sample</artifactId> <version>2.1.RELEASE</version> </project>
In the next section, we will learn how we can customize the POM file using a hook. We can then, for example, also change the Maven dependency scope for our project dependencies.
To add some extra elements to the generated POM file, we must use the pom
property that is a part of MavenPublication
. This returns a MavenPom
object, and we can invoke the withXml
method from this object to add extra elements to the POM file. We will use a closure with the withXml
method to access an XmlProvider
object. With the XmlProvider
object, we can get a reference to a DOM element with the asElement
method, a Groovy node object with the asNode
method, or the StringBuilder
object with the asString
method to extend the POM XML.
In the following example build file, we add the organization
and issueMangement
elements to the generated POM file:
apply plugin: 'maven-publish' apply plugin: 'java' version = '2.1.RELEASE' group = 'book.gradle' repositories { jcenter() } dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' } publishing { publications { sample(MavenPublication) { from components.java pom.withXml { asNode() .appendNode('organization') .with { appendNode('name', 'Gradle') appendNode('url', 'http://www.gradle.org') } asNode() .appendNode('issueManagement') .with { appendNode('system', 'Jenkins') appendNode('url', 'http://buildserver/') } } } } }
If we generate the POM file, we can see our newly created elements in the XML version. This is shown in the following code:
<?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>book.gradle</groupId> <artifactId>sample</artifactId> <version>2.1.RELEASE</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> <scope>runtime</scope> </dependency> </dependencies> <organization> <name>Gradle</name> <url>http://www.gradle.org</url> </organization> <issueManagement> <system>Jenkins</system> <url>http://buildserver/</url> </issueManagement> </project>
In the previous section, we already learned that, if we use the from
method with the components.java
value, all project dependencies are added as runtime dependencies in the generated POM file. This might always not be what we want. Using the withXml
method, not only can we add new elements, we can also change values.
Let's add a hook where we change the runtime scope for dependencies to compile the scope. In the next build file, we will implement this:
apply plugin: 'maven-publish' apply plugin: 'java' version = '2.1.RELEASE' group = 'book.gradle' repositories { jcenter() } dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' } publishing { publications { sample(MavenPublication) { from components.java pom.withXml { asNode() .dependencies .dependency .findAll { dependency -> // Find all with scope runtime. // Could be more specific if we would // have more dependencies. For example // check group, name and version. dependency.scope.text() == 'runtime' } .each { dependency -> // Set scope value to compile. dependency.scope*.value = 'compile' } } } } }
The generated POM file now has the following contents:
<?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>book.gradle</groupId> <artifactId>sample</artifactId> <version>2.1.RELEASE</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> <scope>compile</scope> </dependency> </dependencies> </project>
Another solution would be to configure the publication, not with the from
method but with the artifact
method. Then, dependencies
is not added to the POM file because Gradle cannot determine the dependencies for an artifact. Using the withXml
method, we can add it ourselves based on the project dependencies.
In the following example build file, this solution is implemented:
apply plugin: 'maven-publish' apply plugin: 'java' version = '2.1.RELEASE' group = 'book.gradle' repositories { jcenter() } dependencies { compile 'org.springframework:spring-context:4.1.4.RELEASE' } publishing { publications { sample(MavenPublication) { artifact jar pom.withXml { // Create dependencies element. def dependencies = asNode() .appendNode('dependencies') project .configurations['compile'] .allDependencies ?.each { dependency -> // Add a dependency element with // groupId, artifactId, version and scope, // to the dependencies element. dependencies.appendNode('dependency').with { appendNode('groupId', dependency.group) appendNode('artifactId', dependency.name) appendNode('version', dependency.version) appendNode('scope', 'compile') } } } } } }
When we invoke the
generatePomFileForSamplePublication
task, we get the following POM file:
<?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>book.gradle</groupId> <artifactId>sample</artifactId> <version>2.1.RELEASE</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> <scope>compile</scope> </dependency> </dependencies> </project>
3.144.21.158