Skip to content

jboss/jboss-parent-pom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

JBoss Parent POM

The parent Maven POM for JBoss community projects.

Maven Central

What is it?

The JBoss parent POM provides default configuration for Maven builds.

  • Recommended/Default versions for the most commonly used Maven plugins

  • Manifest configuration for the jar and assembly plugins

  • Profiles for generating source jars, and enforcing a minimum versions of Java and Maven

  • Distribution Management and other configuration for deploying to the JBoss.org Maven repositories

How to use it?

Start out by adding the parent configuration to your pom.

<parent>
  <groupId>org.jboss</groupId>
  <artifactId>jboss-parent</artifactId>
  <version>40</version>
  <!-- The empty relativePath makes Maven look it up in the repository. Missing tag default is ../pom.xml. -->
  <relativePath/>
</parent>

The pom includes properties which allow various build configuration to be customized. For example, to override the default version of the maven-compiler-plugin, just set a property.

<properties>
  <version.compiler.plugin>3.1</version.compiler.plugin>
</properties>

Or override the default Java compiler release level used in the build. This uses the javac --release argument to compile for the specified Java SE release. Note the default level is 11.

<properties>
  <maven.compiler.release>17</maven.compiler.release>
</properties>

If you need tests compiled at a different level, you can use the maven.compiler.testRelease property. This defaults to the maven.compiler.release property.

<properties>
  <maven.compiler.testRelease>21</maven.compiler.testRelease>
</properties>
Note
If you’re compiling down to Java 1.8, you can still use the maven.compiler.release property. Simply set the value to 1.8 and it the appropriate settings will be configured.

The minimum version of Java or Maven required to run a build can also be set via properties.

<properties>
  <maven.min.version>3.9.0</maven.min.version>
  <jdk.min.version>17</jdk.min.version>
</properties>

If jdk.min.version is not set, it defaults to the version defined by the maven.compiler.release property.

For the full list of properties, refer to the POM itself.

The JBoss Release Profile

The parent POM includes a Maven profile called jboss-release. This profile contains settings for generating a full project source archive, javadoc jar files, and release deployment metadata.

It also includes configuration for automatically deploying to a Nexus 3 server.

If using the Maven release plugin, this profile will automatically be activated during the release:perform step.

If the Maven release plugin is not used during the release process, the profile can be manually activated from the command line during a release build.

To authenticate to the remote Nexus server, a username and password token is generally required. Contact your server administrator to get this information. The correct authentication configuration is determined by the nexus.serverId property, which defaults to jboss. In your settings.xml, you would have a configuration like this:

Example settings.xml snippet for deployment authentication
<servers>
    <!-- ... -->
    <server>
        <id>jboss</id> <!-- this is the nexus.serverId -->
        <!-- these are base64-encoded tokens provided by your admin -->
        <username>xxxxxxxx</username>
        <password>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</password>
    </server>
</servers>

In addition, the release artifacts will be signed. (See The GPG Sign Profile for information on how to customize GPG signing).

The jboss-release profile will by default also produce an extra top-level artifact with the suffix -source-release. This artifact will contain the complete contents of the source tree used to deploy the project. This behavior may be disabled by setting the skipReleaseAssembly property to true.

Usage example for the jboss-release profile
mvn -Pjboss-release deploy

Release profile configuration

The following properties configure aspects of the release profile behavior:

Property Default Description

nexus.serverId

jboss

The server ID used for deployment.

nexus.repository.url

https://repository.jboss.org/nexus

The URL of the Nexus 3 server to deploy to.

nexus.repository.release

releases

The name of the repository where the release artifacts will be written, either during the main build deploy phase or during a subsequent promotion of staged artifacts.

nexus.repository.staging

${nexus.repository.release}

The name of the repository to deploy to. Override the default value if deploying to an intermediate staging repository.

nexus.staging.tag

Tag to associate with all deployed artifacts. An empty string results in a plugin-generated tag.

skipReleaseAssembly

false

If true, the -source-release artifact will not be created.

Staged releases

The jboss-release profile deploys artifacts to the configured Nexus 3 server using the nxrm3-maven-plugin deploy goal. The usual expectation when that goal is used is that the repository to which the artifacts are deployed will be their ultimate location, where typical Maven clients will access them. However, the nxrm3-maven-plugin also supports stage→validate→promote workflows with its deploy, staging-move and staging-delete goals.

All deployed artifacts will have an associated tag, with the value of the nexus.staging.tag Maven property, or a generated value the property is not configured. This tag is later used to identify artifacts to move from the staging repository to their final destination, or to delete them from the staging repository.

Note
This Nexus 3 tag is not the same thing as a git tag.

A typical good practice would be to set the nexus.staging.tag in a child pom to a combination of a unique-to-the-project string and the release version:

Usage example for the nexus.staging.tag property
<nexus.staging.tag>project-foo-${project.version}</nexus.staging.tag>

Deploying to a staging repository

A stage→validate→promote workflow with Nexus 3 requires the availability of two repositories; a staging repository to which artifacts are deployed during execution of the deploy goal, and then the ultimate repository to which the artifacts can be moved.

To deploy to a staging repository, child poms must override the nexus.repository.staging Maven property described above and set it to the name of the staging repository.

Usage example for the nexus.repository.staging profile
<nexus.repository.staging>foo-staging</nexus.repository.staging>

Promoting staged artifacts with the staging-move goal

Once the build that used the jboss-staging-deploy profile is complete, the staged artifacts can be validated. If they are acceptable, they can be moved from the staging repository to the final repository where typical Maven clients will access them.

This move is accomplished by a mvn execution that executes a single nxrm3-maven-plugin goal, with the parent POM’s nexus-move execution specified:

Usage example for the staging-move goal
mvn nxrm3:staging-move@nexus-move

The parent POM’s nexus-move execution configures the nxrm3-maven-plugin to move artifacts associated with the nexus.staging.tag from the nexus.repository.staging repository to the nexus.repository.release repository.

Deleting staged artifacts with the staging-delete goal

If the build that deployed to the staging repository did not complete successfully, or if the deployed artifacts are otherwise not suitable for promotion from the staging repo, they can be deleted from the staging repository.

This move is accomplished by a mvn execution that executes a single mxrm3-maven-plugin goal, with the parent POM’s nexus-delete execution specified:

Usage example for the jboss-staging-delete profile
mvn nxrm3:staging-delete@nexus-delete

The parent POM’s nexus-delete execution uses the nexus.staging.tag property described earlier to determine the tag identifying the artifacts that should be moved.

Important
The staging-delete goal is used to delete artifacts associated with a tag; it does not remove the tag and shouldn’t be used unless deleting artifacts is the intent. Cleaning up unneeded tags is a server-side administrative function.

The GPG Sign Profile

This POM includes a Maven profile called "gpg-sign" which provides a default configuration to generate GPG signatures for the build artifacts.

Note: if the The JBoss Release Profile is used, then GPG signing is automatically enabled, and this profile does not need to be explicitly activated.

Example Maven command line for activating GPG signing
mvn -Pgpg-sign deploy

In order for the gpg plugin to properly create a signature for each artifact, the properties gpg.keyname and gpg.passphrase may be used. These properties can either be set in a build profile, or on the command line.

Example GPG key properties
<properties>
    <gpg.keyname>[email protected]</gpg.keyname>
    <!-- Don't keep passphrase in plain text! -->
    <gpg.passphrase>secret</gpg.passphrase>
</properties>

If no gpg.keyname is given, then the default GPG key will be used. If no default GPG is configured, then the default key will be the first key found in the local secret keyring.

If no gpg.passphrase is given, then the GPG plugin will attempt to acquire the passphrase from a GPG agent. If that fails, it will attempt to read the passphrase from the console.

To prevent the passphrase from being read on the console, set the gpg.pinEntryMode property to error.

Multi-Release JARs

Starting with version 30, the JBoss Parent POM provides a framework for multi-release JAR build and test.

Functional overview

The multi-release JAR support works in two parts: compilation and testing.

Compilation

Compilation works by providing extra executions of the compiler plugin in order to build the additional JAR layers. The base layer is built by the standard default-compile execution. After that, Maven profiles are activated based on the presence of extra layer source directories (e.g. src/main/java12, src/main/java16 etc.). These profiles contain additional executions of the compiler plugin which compile the sources in the layer directory, while putting the output of the previous step on the class path.

Each present layer is in turn compiled with the results of all the previous layers on the classpath in the correct order. The additional layer class files are output under the target/classes directory in the appropriate location for multi-release JAR layers.

In order to select the correct class files for the given Java version, the <release> property is used. This prevents accidental usage of APIs which are only present in later versions than the one being compiled.

Testing

Testing using maven-surefire-plugin is supported by running the project unit tests on every supported Java version. In order to do so, it is expected that the following system property or properties are set as needed:

  • java11.home: this property must be set to the location of a Java 11 JDK installation

  • java17.home: this property must be set to the location of a Java 17 JDK installation

  • java21.home: this property must be set to the location of a Java 21 JDK installation

In order to simplify development, it is recommended to project maintainers to set these properties in your personal Maven settings.xml file.

Extra unit tests are run for a given platform whenever a newer version than that platform was used to build the project and the appropriate control file is found (see Build control files reference).

Configuration

To configure a multi-release JAR, you need the following pieces of information:

  • The minimum (oldest) version of Java that will be supported by the project

  • The maximum (newest) version of Java for which your project has sources

Step 1: Base layer version

Choose your base layer version. This can be Java 11 or anything later. Set the maven.compiler.release property to your desired version and this will configure the maven-compiler-plugin with the release version.

Step 2: Highest layer version

Configure the jdk.min.version property as described above to match either:

  • The maximum (newest) Java version for which sources exist in your project, or

  • Some Java version higher than that

This is the version of Java that will build all of your layers, so it necessarily must be able to compile every version of Java sources from oldest to newest.

Step 3: Source directories

The sources for your base layer continue to reside in src/main/java and src/test/java.

Additional layers are in directories whose names correspond to the version of Java that is targeted by that directory. For example, sources which are specific to Java 13 and later would be in src/main/java13, whereas sources which are specific to Java 16 and later would be in src/main/java16.

If you have a class that needs an alternative implementation for a given Java version, you only need to provide the replacement source file in the directory corresponding to the oldest version that supports the alternative source. It is not necessary to copy identical classes into more than one layer; doing so will increase the size of the resultant artifact needlessly.

There are restrictions on these directories. You may only provide sources that correspond to sources that exist in the base layer - that is, it is a violation of the MR JAR specification to provide sources that introduce new APIs only in later Java versions. The JDK does enforce this at run time. In addition, providing additional public members in later versions is generally not recommended.

Using MR JAR functions with GitHub Actions

Using this functionality with GitHub Actions is relatively simple. It entails adding the additional JDK version(s) by way of a setup action, and then passing the location of each additional JDK to the build.

As an example, for a project that is built on Java 17 but must also be tested against JDK 11 your build.yml might look something like this:

jobs:
  build:
    runs-on: ubuntu-latest
    name: Build using Maven

    steps:
      - uses: actions/checkout@v2
        name: Checkout

      - uses: actions/setup-java@v3
        name: Set up JDKs
        with:
          distribution: temurin
          java-version: |
            11
            17

      - name: Build
        run: mvn -B verify --file pom.xml "-Djava11.home=${{env.JAVA_HOME_11_X64}}"

Note that this configuration causes the default JAVA_HOME environment to be set to JDK 17.

Build control files reference

These build control files are tested only for their presence. They do not need to have any content (i.e. they can be zero-sized).

File name Purpose Reference

build-test-java11

Run tests for Java 11 when java11.home is set and JDK 12 or later is used.

Testing

build-test-java17

Run tests for Java 17 when java17.home is set and JDK 18 or later is used.

Testing

build-test-java21

Run tests for Java 21 when java21.home is set and JDK 22 or later is used.

Testing

Where to get more information?

The github wiki provides some additional examples. For questions/suggestions about the jboss-parent-pom, head to the JBoss Community Build space on the jboss.org site. Issues related to the jboss-parent-pom can be submitted to the JBoss build jira project

About

JBoss Parent POM

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 36