Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Required Java version of Maven Dependency?

Tags:

I developed and built my Java application using Maven. I need to support Java 1.6, so I use the following properties:

<maven.compiler.target>1.6</maven.compiler.target> <maven.compiler.source>1.6</maven.compiler.source> 

Still, when I run the application I get an "Unsupported major.minor version" error and I suspect that one of my dependency jars is compiled with a Java version newer than the one I need to support.

My questions:

  1. Is this even possible? I thought Maven would take care of this kind of dependency version problems.

  2. Is there an easy way to find out the minor/major version of all my dependencies? (Would be awesome if it could be shown when doing mvn dependency:tree for instance.)

like image 727
aioobe Avatar asked Oct 25 '14 06:10

aioobe


People also ask

Which Java is required for Maven?

1 for LTS) requires Java 8 thus Maven jobs must be launched with a JDK >= 8.

What is the minimum JDK version needed for latest Maven installation?

Additionally, starting from Spring Boot 2.0, Java 8 is the minimum version.

Does Maven work with Java 17?

In case of Maven, we specify the compiler plugin to use Maven with Java 17. The next step is to basically upgrade the dependencies of our application. We can do that, already, on the current version of Java which we're using, and simply upgrade all the dependencies, check if the application still works.

Does Maven work with Java 11?

Chances are that it just runs fine with Java 11. Hint: You can speed up multi-module Maven projects by using parallel builds, e.g. mvn -T 4 compile compiles all modules in parallel on 4 CPU cores.


2 Answers

The problem is that every dependency (maintainer) can decide on it's own which java version is used to compile (1.5, 1.6, 1.7, 1.8 etc) so this is not solvable via Maven. But you can make sure that you don't use dependencies which are using a different Java version than you like to have.

This can be enfored by using Maven Enforcer Plugin by using extra-enforcer-rules:

<project>   [...]   <build>     <plugins>       <plugin>         <groupId>org.apache.maven.plugins</groupId>         <artifactId>maven-enforcer-plugin</artifactId>         <version>1.4.1</version> <!-- find the latest version at http://maven.apache.org/plugins/maven-enforcer-plugin/ -->         <executions>           <execution>             <id>enforce-bytecode-version</id>             <goals>               <goal>enforce</goal>             </goals>             <configuration>               <rules>                 <enforceBytecodeVersion>                   <maxJdkVersion>1.6</maxJdkVersion>                   <excludes>                     <exclude>org.mindrot:jbcrypt</exclude>                   </excludes>                 </enforceBytecodeVersion>               </rules>               <fail>true</fail>             </configuration>           </execution>         </executions>         <dependencies>           <dependency>             <groupId>org.codehaus.mojo</groupId>             <artifactId>extra-enforcer-rules</artifactId>             <version>1.0-beta-5</version>           </dependency>         </dependencies>       </plugin>     </plugins>   </build>   [...] </project> 

This will break your build if you have a dependency which is compiled with a different version of JDK than you want to have.

like image 106
khmarbaise Avatar answered Sep 28 '22 04:09

khmarbaise


To answer your two questions:

Yes, this is possible. Looking at the docs, the <maven.compiler.target> and <maven.compiler.source> properties simply tells Maven which version of javac to use to compile your project. And I quote, for your reference:

Note: Merely setting the target option does not guarantee that your code actually runs on a JRE with the specified version. The pitfall is unintended usage of APIs that only exist in later JREs which would make your code fail at runtime with a linkage error. To avoid this issue, you can either configure the compiler's boot classpath to match the target JRE or use the Animal Sniffer Maven Plugin to verify your code doesn't use unintended APIs.

The magic number after the Unsupported major.minor version error actually tells the version of the JRE the class file is compatible with:

J2SE 8 = 52, J2SE 7 = 51, J2SE 6.0 = 50, J2SE 5.0 = 49, JDK 1.4 = 48, JDK 1.3 = 47, JDK 1.2 = 46, JDK 1.1 = 45 

I don't know if there is an easy way to tell the major/minor version of ALL the dependencies (and transitive dependencies) in a project though.

UPDATE: Though I haven't used it before, I wonder the Animal Sniffer Maven plugin will help to sniff out the major/minor version of your dependencies.

like image 20
ivan.sim Avatar answered Sep 28 '22 04:09

ivan.sim