I have a scenario wherein my project needs to be compiled in different JDKs and the resulting artifact name should be different based on the JDK used. For example if the project name is MyProject and I call mvn install then it needs to be compiled in JDK 1.4 as well as JDK 1.5, and finally I get two jars of the same project (MyProjectJDK14-1.0 and MyProjectJDK15-1.0). Is is possible to achieve this?
A Build profile is a set of configuration values, which can be used to set or override default values of Maven build. Using a build profile, you can customize build for different environments such as Production v/s Development environments. Profiles are specified in pom.
groupId – a unique base name of the company or group that created the project. artifactId – a unique name of the project. version – a version of the project. packaging – a packaging method (e.g. WAR/JAR/ZIP)
During the build of a project, Maven, without toolchains, will use the JDK to perform various steps, like compiling the Java sources, generate the Javadoc, run unit tests or sign JARs. Each of those plugins need a tool of the JDK to operate: javac, javadoc, jarsigner, etc.
In Maven terminology, an artifact is an output generated after a Maven project build. It can be, for example, a jar, war, or any other executable file. Also, Maven artifacts include five key elements, groupId, artifactId, version, packaging, and classifier.
The Maven way to do this is not to change the finalName
of the artifact but to use a classifier. For example:
<project> ... <build> <plugins> <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <classifier>${envClassifier}</classifier> </configuration> </plugin> </plugins> </build> ... <profiles> <profile> <id>jdk16</id> <activation> <jdk>1.6</jdk> </activation> <properties> <envClassifier>jdk16</envClassifier> </properties> </profile> <profile> <id>jdk15</id> <activation> <jdk>1.5</jdk> </activation> <properties> <envClassifier>jdk15</envClassifier> </properties> </profile> </profiles> </project>
The JAR artifact will be named ${finalName}-${envClassifier}.jar
and included as a dependency using the following syntax:
<dependency> <groupId>com.mycompany</groupId> <artifactId>my-project</artifactId> <version>1.0</version> <classifier>jdk16</classifier> </dependency>
You'll have to call the Maven build twice to produce both jars (a decent CI engine can do that).
What you can do is to define two profiles, one per JDK used. Each profile will be activated regarding which JDK is used:
<profiles> <profile> <id>profile-for-jdk1.4</id> <activation> <activeByDefault>false</activeByDefault> <jdk>1.4</jdk> </activation> <build> <finalName>myBuild-jdk1.4</finalName> </build> </profile> <profile> <id>profile-for-jdk1.5</id> <activation> <activeByDefault>false</activeByDefault> <jdk>1.5</jdk> </activation> <build> <finalName>myBuild-jdk1.5</finalName> </build> </profile> </profiles>
Then, in each profile, you define a specific <finalName>
, which will be used to name the generated JAR file.
Thus, if you build your application using JDK 1.4, the generated JAR will be named myBuild-jdk1.4.jar
.
If your final package is built using an assembly, you can simply change the <build>
block inside profiles to configure the assembly plugin (for example to <finalName>
).
Regarding your comment: Indeed, this procedure will need two separate builds on Maven, as you have to recompile the whole project when changing the JDK version. One of the Maven2 convention is that one project = one artifact. What you want is to have one project with two artifacts.
Eventually, one solution is to use Hudson to build your application, and especially the matrix feature of this tool, which allows you to run multiple builds with various parameters, in your case the JDK.
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