Generating POM files

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.

Customizing the POM file

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>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.21.158