On my mac I have 2 java versions installed, On checking with Java -version
command I get 17 version, but when I am checking mvn -version
it is showing java version as 22. I want java version 17 for maven as well. What I might be missing that should be corrected?
You can easily use the latest Java version to build (22) and run your app while compiling your code for an earlier version of Java (17).
Here is a simple little app.
public class App
{
public static void main ( String[] args )
{
System.out.println( Runtime.version( ) );
System.out.println( "Hello World!" );
// ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor( ); // Compiler error: Cannot find symbol.
}
}
When run:
22.0.1+10
Hello World!
We can see that:
Runtime.version
.Executors.newVirtualThreadPerTaskExecutor
line, we get a compiler error, Cannot find symbol
. That feature was added in Java 21.As we write code, IntelliJ and the compiler is preventing us from accessing any classes bundled with version of Java after 17. The classes exist in the Java 22 running the compiler, but those newer classes are out-of-reach since we designated an older version of Java.
To make this work, you must set some settings within your IDE. In IntelliJ, we must set:
File > Project Structure… > Project Settings > Modules > Language Level
to 17 - Sealed types, always-strict floating-point semantics
Settings > Build, Execution, Deployment > Build Tools > Compiler > Java Compiler > Per-module bytecode version > Target bytecode version
to 17
.And we must specify the version within the Maven POM file. Here is an example. I started with the Maven archetype named QuickStart. I then revamped its long outdated version numbers.
The crucial part is the <maven.compiler.release>17</maven.compiler.release>
element that tells Maven to run the compiler in such a way as to output bytecode for Java 17.
With modern versions of Maven, we can use this single ".release" element rather than a pair of ".source" & ".target" elements.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>work.basil.example</groupId>
<artifactId>ExJava17On22</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ExJava17On22</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>4.0.0-M9</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.5.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
While I do not have Maven installed separately, I can invoke man -version
on the Maven bundled within IntelliJ IDE.
/Users/basil_dot_work/Applications/'IntelliJ IDEA Ultimate.app'/Contents/plugins/maven/lib/maven3/bin/mvn -version
Result:
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /Users/basil_dot_work/Applications/IntelliJ IDEA Ultimate.app/Contents/plugins/maven/lib/maven3
Java version: 22.0.1, vendor: BellSoft, runtime: /Users/basil_dot_work/.sdkman/candidates/java/22.0.1.fx-librca
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "14.4.1", arch: "aarch64", family: "Mac"
So we can see that Maven 3.9.6 is running on my installation of the Liberica JDK 22.0.1 from BellSoft.
On my Mac …
Nothing above is Mac-specific.
But, by the way, a tip: SDKMAN! is an excellent little command-line tool for finding, downloading, installing, and uninstalling JDKs and other kits of software. This bundle of shell scripts works quite well on Unix-oriented operating systems such as macOS.
sdk list java
sdk install java whatever
sdk uninstall java whatever
The only limitation is that SDKMAN! knows only about JDK products whose vendors choose to submit data. This includes multiple vendors of JDK/JRE offerings, but not all vendors.