Maven project dependency against JDK version - java

I have projects that need to be build with a specific version of the JDK.
The problem isn't in the source and target parameters but in the jars of the runtime used during compilation.
In some cases I get a compilation error if I try to compile with the wrong JDK, but sometimes the build is successful and I get runtime errors when using the jars.
For example in eclipse I have the ability to establish the execution enviroment for the project in the .classpath file.
Is there a way to handle such situation in maven?
What I would like to have is the ability to handle JRE dependency like other dependencies of the project in the POM file.
UPDATE:
The accepted solution was the best one when I asked this question, so I won't change it. Meanwhile a new solution to this kind of problems has been introduced: Maven Toolchain. Follow the link for further details.

I've found this article:
http://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${JAVA_1_4_HOME}/bin/javac</executable>
<compilerVersion>1.3</compilerVersion>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>

I have projects that need to be build with a specific version of the JDK.
You can use the Maven Enforcer plugin to enforce the use of a particular version of the JDK:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.5</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
But I'm not sure I really understood the question. If this is not what you want, maybe you could declare your JDK specific dependencies in profiles and use an activation trigger based on the JDK version. For example:
<profiles>
<profile>
<activation>
<jdk>1.5</jdk>
</activation>
...
</profile>
</profiles>
This configuration will trigger the profile when the JDK's version starts with "1.5".

I believe that this can be solved with following plugin in your pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
Here you target version 1.6 , or write your own version

Related

Java google checkstyle Maven

I'm trying to configure my Maven project to use google java check style with the following configuration:
google_checks.xml: https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>checkstyle</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<configLocation>google_checks.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<configuration>
<configLocation>google_checks.xml</configLocation>
<failOnViolation>false</failOnViolation>
<enableFilesSummary>false</enableFilesSummary>
</configuration>
</plugin>
</plugins>
</reporting>
It seems to run mvn checkstyle:check fine at first. But after a few runs I start getting the following error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:2.17:check
(default-cli) on project PROJECT: Failed during checkstyle configuration: cannot initialize
module TreeWalker - Token "METHOD_REF" was not found in Acceptable tokens list in check
com.puppycrawl.tools.checkstyle.checks.whitespace.SeparatorWrapCheck -> [Help 1]
What does that mean? Why does it only happen some times and how do I get rid of it?
Token "METHOD_REF" was not found in Acceptable tokens list in check
com.puppycrawl.tools.checkstyle.checks.whitespace.SeparatorWrapCheck
You are trying to use a newer configuration with an old version of Checkstyle.
The configuration at https://github.com/checkstyle/checkstyle/blob/master/src/main/resources/google_checks.xml is in master which is dependent on the snapshot version of checkstyle.
If you are using google configuration without any modifications, you need to use the one that comes embedded in checkstyle. See https://stackoverflow.com/a/35486365/1016482
Otherwise you can integrate a newer version of checkstyle to work with maven. See https://stackoverflow.com/a/27359107/1016482
I was using version 3.0.0 (which is the newest one right now) of the maven-checkstyle-plugin and I still got the error. I solved it by adding the following dependency to the plugin.
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.11</version>
</dependency>

Spring Boot control target JAR file name

My Spring Boot project has build description:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.18.1</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.app.MainClass</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
I want my JAR file name to be app-1.0-SNAPSHOT.jar in one branch and 1.0-RELEASE.jar in another, controlled by Jenkins (using some kind of mvn settings or JVM argument such as -D..
Can I do this?
So simple, In one branch, you have pom.xml with
<build>
<finalName>app-1.0-SNAPSHOT</finalName>
</build>
In other branch, you have pom.xml with
<build>
<finalName>1.0-RELEASE</finalName>
</build>
You can propagate the version of the project to your build name like this:
<build>
<finalName>app-${project.version}</finalName>
</build>
or the version of your parent project if you have one:
<build>
<finalName>app-${parent.version}</finalName>
</build>
Then you would keep track of you project version rather than the build name.
However, note that managing the build verson in SCM using branches is a pain in the neck and error prone. It is rather recommanded that your code repository woud be agnostic of your build version.
A possible alternative would be to use some release management tool, like maven release plugin, or even more simple maven version.
Example:
Here I'll give and example using maven verion.
Say you're using SCM tool (it could be git) and a build factory (like Jenkins or any other tool). Say you have a job to build and deploy snapshots and another one for releases.
In the snapshot job, you can set-up a pre-build task with the following maven target:
versions:set -DnewVersion=app-1.0-SNAPSHOT
and the following in the release job:
versions:set -DnewVersion=app-1.0-RELEASE
Now doing this is OK, because you are only doing it locally and never have to manage the build version in your code.
Now, you can tag your (release) version after having applied maven version and build successfuly (hopefuly including unit, integration and functional tests). This way you may keep track exactly of the code that has been deployed on each release.
Tip!! Space is money! Do yourself a favour: clean your snapshot repository regularly. Creating a job that does so every once in a while shouldn't be to difficult.
You can specify the artefact-name with the maven boot plugin:
In this case, it will be NewJarName.jar
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<finalName>NewJarName</finalName>
</configuration>
</execution>
</executions>
</plugin>

Check if library will work on a specific verion of Java

What approach can be taken to verify that a library is compatible on a specific version of Java?
Example: Library X was compiled on Java 1.7, therefor it might not work on Java 1.7 or lower.
Thank you.
The best is to check the byte code via an enforcer rule which can be applied to your build by using the maven-enforcer-plugin...
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-bytecode-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<enforceBytecodeVersion>
<maxJdkVersion>1.7</maxJdkVersion>
</enforceBytecodeVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>1.0-beta-4</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
[...]
</project>
compile with the version you want:
javac -target ...
see that: How do i compile a .java with support for older versions of java?
and check jar dependencies: with Jdepend for example
Analyze JAR dependencies in a Java project

How do I set in the pom to not compile tests?

How do I set in the pom to not compile tests in Maven? I've tried:
<properties>
<skipTests>true</skipTests>
</properties>
but in that case, Maven compile the tests but don't run them. I need Maven don't compile my tests.
You have to define maven.test.skip to true.
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
http://maven.apache.org/surefire/maven-surefire-plugin/examples/skipping-test.html
In my case a solution was to put tests in a profile (e.g. runTests), so when I want to run these tests, I add the parameter -PrunTests. Thanks for the replies.
Configure maven-compiler-plugin to skip the compilation.
Once again, I do not recommend it.
<project>
<properties>
<maven.test.skip>true</maven.test.skip>
</properties>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<skip>${maven.test.skip}</skip>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
If you are using the surefire-plugin for executing tests, you can configure it to skip them based on a naming pattern:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14</version>
<configuration>
<includes>
<include>%regex[.*[Cat|Dog].*Test.*]</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
This, however, requires the tests file names to conform to the desired pattern(s). At work we are using this approach, and have our tests end with ..UnitTest or ..IntegrationTest, so that we can easily turn each of them off by modifying the regex in the corresponding build profile.
Take a look at Apache's documentation on the surefire plugin. You may find something more useful or better suited for your case.

FindBugs: How can I run it in Java 5 mode?

When I run FindBugs on my project via Maven, I get lots of these:
Can't use annotations when running in JDK 1.4 mode!
How do I fix that? Couldn't find anything in the manual.
I believe you are missing the targetJdk element in the plugin configuration, like in below snippet.
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.0.1</version>
<configuration>
<targetJdk>1.5</targetJdk>
</configuration>
</plugin>
</plugins>
</reporting>
Make sure your Maven build plugin is compiling to 1.5, and not 1.4.
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>

Categories