Java level issue with Maven compilation - java

I'm facing a weird issue. In Maven I am setting the Java level to 1.8. In my code I have some Java 11 syntax, namely:
final Optional<Stock> stock = stockRepo.findById(id);
if (stock.isEmpty()) {
throw new StockNotFoundException("Stock not found, id: " + id);
}
The code gets compiled just OK, I was expecting it to fail.
In the pom I have:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
...
Maven prints the following logs with -X option
[DEBUG] Command line options:
[DEBUG] -d /Users/user/Desktop/java_dev/projects/stockapp-spring-boot/stockapp/target/classes -classpath /Users/user/Desktop/java_dev/projects/stockapp-spring-boot/stockapp/target/classes:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.6.2/spring-boot-starter-web-2.6.2.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter/2.6.2/spring-boot-starter-2.6.2.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot/2.6.2/spring-boot-2.6.2.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.6.2/spring-boot-autoconfigure-2.6.2.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.6.2/spring-boot-starter-logging-2.6.2.jar:/Users/user/.m2/repository/ch/qos/logback/logback-classic/1.2.9/logback-classic-1.2.9.jar:/Users/user/.m2/repository/ch/qos/logback/logback-core/1.2.9/logback-core-1.2.9.jar:/Users/user/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.17.0/log4j-to-slf4j-2.17.0.jar:/Users/user/.m2/repository/org/apache/logging/log4j/log4j-api/2.17.0/log4j-api-2.17.0.jar:/Users/user/.m2/repository/org/slf4j/jul-to-slf4j/1.7.32/jul-to-slf4j-1.7.32.jar:/Users/user/.m2/repository/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5.jar:/Users/user/.m2/repository/org/yaml/snakeyaml/1.29/snakeyaml-1.29.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-json/2.6.2/spring-boot-starter-json-2.6.2.jar:/Users/user/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.13.1/jackson-datatype-jdk8-2.13.1.jar:/Users/user/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.13.1/jackson-datatype-jsr310-2.13.1.jar:/Users/user/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.13.1/jackson-module-parameter-names-2.13.1.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/2.6.2/spring-boot-starter-tomcat-2.6.2.jar:/Users/user/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.56/tomcat-embed-core-9.0.56.jar:/Users/user/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.56/tomcat-embed-websocket-9.0.56.jar:/Users/user/.m2/repository/org/springframework/spring-web/5.3.14/spring-web-5.3.14.jar:/Users/user/.m2/repository/org/springframework/spring-beans/5.3.14/spring-beans-5.3.14.jar:/Users/user/.m2/repository/org/springframework/spring-webmvc/5.3.14/spring-webmvc-5.3.14.jar:/Users/user/.m2/repository/org/springframework/spring-context/5.3.14/spring-context-5.3.14.jar:/Users/user/.m2/repository/org/springframework/spring-expression/5.3.14/spring-expression-5.3.14.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-security/2.6.2/spring-boot-starter-security-2.6.2.jar:/Users/user/.m2/repository/org/springframework/spring-aop/5.3.14/spring-aop-5.3.14.jar:/Users/user/.m2/repository/org/springframework/security/spring-security-config/5.6.1/spring-security-config-5.6.1.jar:/Users/user/.m2/repository/org/springframework/security/spring-security-core/5.6.1/spring-security-core-5.6.1.jar:/Users/user/.m2/repository/org/springframework/security/spring-security-crypto/5.6.1/spring-security-crypto-5.6.1.jar:/Users/user/.m2/repository/org/springframework/security/spring-security-web/5.6.1/spring-security-web-5.6.1.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-data-jpa/2.6.2/spring-boot-starter-data-jpa-2.6.2.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-aop/2.6.2/spring-boot-starter-aop-2.6.2.jar:/Users/user/.m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-jdbc/2.6.2/spring-boot-starter-jdbc-2.6.2.jar:/Users/user/.m2/repository/com/zaxxer/HikariCP/4.0.3/HikariCP-4.0.3.jar:/Users/user/.m2/repository/org/springframework/spring-jdbc/5.3.14/spring-jdbc-5.3.14.jar:/Users/user/.m2/repository/jakarta/transaction/jakarta.transaction-api/1.3.3/jakarta.transaction-api-1.3.3.jar:/Users/user/.m2/repository/jakarta/persistence/jakarta.persistence-api/2.2.3/jakarta.persistence-api-2.2.3.jar:/Users/user/.m2/repository/org/hibernate/hibernate-core/5.6.3.Final/hibernate-core-5.6.3.Final.jar:/Users/user/.m2/repository/org/jboss/logging/jboss-logging/3.4.2.Final/jboss-logging-3.4.2.Final.jar:/Users/user/.m2/repository/net/bytebuddy/byte-buddy/1.11.22/byte-buddy-1.11.22.jar:/Users/user/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar:/Users/user/.m2/repository/org/jboss/jandex/2.2.3.Final/jandex-2.2.3.Final.jar:/Users/user/.m2/repository/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar:/Users/user/.m2/repository/org/hibernate/common/hibernate-commons-annotations/5.1.2.Final/hibernate-commons-annotations-5.1.2.Final.jar:/Users/user/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.5/jaxb-runtime-2.3.5.jar:/Users/user/.m2/repository/org/glassfish/jaxb/txw2/2.3.5/txw2-2.3.5.jar:/Users/user/.m2/repository/com/sun/istack/istack-commons-runtime/3.0.12/istack-commons-runtime-3.0.12.jar:/Users/user/.m2/repository/org/springframework/data/spring-data-jpa/2.6.0/spring-data-jpa-2.6.0.jar:/Users/user/.m2/repository/org/springframework/data/spring-data-commons/2.6.0/spring-data-commons-2.6.0.jar:/Users/user/.m2/repository/org/springframework/spring-orm/5.3.14/spring-orm-5.3.14.jar:/Users/user/.m2/repository/org/springframework/spring-tx/5.3.14/spring-tx-5.3.14.jar:/Users/user/.m2/repository/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar:/Users/user/.m2/repository/org/springframework/spring-aspects/5.3.14/spring-aspects-5.3.14.jar:/Users/user/.m2/repository/org/springframework/boot/spring-boot-starter-validation/2.6.2/spring-boot-starter-validation-2.6.2.jar:/Users/user/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/9.0.56/tomcat-embed-el-9.0.56.jar:/Users/user/.m2/repository/org/hibernate/validator/hibernate-validator/6.2.0.Final/hibernate-validator-6.2.0.Final.jar:/Users/user/.m2/repository/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar:/Users/user/.m2/repository/org/liquibase/liquibase-core/4.5.0/liquibase-core-4.5.0.jar:/Users/user/.m2/repository/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1.jar:/Users/user/.m2/repository/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar:/Users/user/.m2/repository/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/2.13.1/jackson-module-jaxb-annotations-2.13.1.jar:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.13.1/jackson-annotations-2.13.1.jar:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.13.1/jackson-core-2.13.1.jar:/Users/user/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.13.1/jackson-databind-2.13.1.jar:/Users/user/.m2/repository/jakarta/xml/bind/jakarta.xml.bind-api/2.3.3/jakarta.xml.bind-api-2.3.3.jar:/Users/user/.m2/repository/jakarta/activation/jakarta.activation-api/1.2.2/jakarta.activation-api-1.2.2.jar:/Users/user/.m2/repository/org/springframework/spring-core/5.3.14/spring-core-5.3.14.jar:/Users/user/.m2/repository/org/springframework/spring-jcl/5.3.14/spring-jcl-5.3.14.jar:/Users/user/.m2/repository/org/projectlombok/lombok/1.18.22/lombok-1.18.22.jar:/Users/user/.m2/repository/org/mapstruct/mapstruct-processor/1.3.1.Final/mapstruct-processor-1.3.1.Final.jar:/Users/user/.m2/repository/org/mapstruct/mapstruct/1.3.1.Final/mapstruct-1.3.1.Final.jar: -sourcepath /Users/user/Desktop/java_dev/projects/stockapp-spring-boot/stockapp/src/main/java:/Users/user/Desktop/java_dev/projects/stockapp-spring-boot/stockapp/target/generated-sources/annotations: -s /Users/user/Desktop/java_dev/projects/stockapp-spring-boot/stockapp/target/generated-sources/annotations -g -nowarn -target 1.8 -source 1.8 -encoding UTF-8
Any clue?

There is no specific Java 11 syntax in the provided code. There is a use of an API not present in JDK8, so if you try compiling this with JDK8 it will fail. But you are probably compiling with JAVA_HOME set to JDK11+.
The syntax difference would be something like:
final var stock = stockRepo.findById(id);

Related

Determine the actual java version used in maven build

Complementary to this question, how to determine actual java version used in mvn compile?
I am compiling FasterXML/jackson-databind as follows, but can't be sure of the java version:
$ git clone https://github.com/FasterXML/jackson-databind.git
$ cd jackson-databind
$ mvn compile
$ javap -verbose ./target/classes/com/fasterxml/jackson/databind/PropertyNamingStrategy.class | grep "major"
major version: 52
So according to this post, the java version is 1.8.
But when I grep the pom.xml I don't see that:
$ grep -wn "source" pom.xml
245: <id>add-test-source</id>
248: <goal>add-test-source</goal>
252: <source>src/test-jdk14/java</source>
265: <source>14</source>
I only see java 14 (?) What am I missing?
It's in the new release tag, not the source or compile -
You can reference it using the maven user property
NB Release overrides source and target values -
e.g. having source = 1.8, and target = 1.8, with release = 14,
compiles and releases in JDK 14
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<release>${maven.compiler.source}</release>
The parent POM is jackson-base which does set the java version : https://github.com/FasterXML/jackson-bom/blob/e60567a0e778f749d9e39e2c245486a44fbc52f9/base/pom.xml
<javac.src.version>1.8</javac.src.version>
<javac.target.version>1.8</javac.target.version>
<maven.compiler.source>${javac.src.version}</maven.compiler.source>
<maven.compiler.target>${javac.target.version}</maven.compiler.target>
You can inspect the fully evaluated POM with all the parents/dependencies/plugins/properties/etc using mvn help:effective-pom
The version that is used by maven can be found in POM file like:
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
or alternatively
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>

maven-compiler-plugin broken on linux?

I have a maven project. In the pom.xml file the following is stated:
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
...
</plugins>
</build>
...
AFAIK this is correct, it should build against JDK 7.
I run a Debian based Linux dist and when I do mvn clean install it seems to always build against the javac version I have set in my os.
I've tried reading up on what the plugin exactly does https://maven.apache.org/plugins/maven-compiler-plugin/, but it doesn't really state how.
An example is I have javac 8 running on my os. When I invoke mvn clean install, the project compiles against JDK 8 and not JDK 7 as stated in the pom.xml. Why is this?
By default the maven-compiler-plugin uses %JAVA_HOME%/bin/javac to compile, unless:
you set the executable-parameter to a different location
you use Toolchains, which seems to match your requirements, i.e a different Java Runtime for Maven compared to the JDK for the maven-compiler-plugin.
Source and target settings are just passed to the javac compiler as parameters. The javac installed on the machine is used.

maven compiler UTF 8 error when changing to executable

I am experimenting with using an executable for the maven compiler plugin instead of the basic declaring source/target. I am running into an issue with the encoding when I do this and am curious why it is happening. I know that setting the encoding to cp1252 fixes the issue when using an executable, but can't figure out why utf-8 is fine when not using an executable.
Executable:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<fork>true</fork>
<executable>D:\Java\jdk1.7.0_79\bin\javac</executable>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
Note: D:\Java\jdk1.7.0_79 is also my JAVA_HOME in the env
Breaks compilation for both maven compiler versions 3.1 and 3.5.1:
[ERROR] D:\Projects\testproject\src\main\java\com\test\service\TestService.java:
[467,70] error: unmappable character for encoding UTF-8
Orig:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
Still compiles successfully either way, but this is in the logs:
maven compiler plugin version: 3.5.1
[ERROR] /D:/Projects/testproject/src/main/java/com/test/service/TestService.java
[467,85] unmappable character for encoding UTF-8
maven compiler plugin version: 3.1
[WARNING] /D:/Projects/testproject/src/main/java/com/test/service/TestService.java
[467,85] unmappable character for encoding UTF-8
The args passed from both logs: -g -nowarn -target 1.7 -source 1.7 -encoding UTF-8.
I noticed on the maven compiler plugin home page:
The Compiler Plugin
is used to compile the sources of your project. Since 3.0, the default
compiler is javax.tools.JavaCompiler (if you are using java 1.6) and
is used to compile Java sources. If you want to force the plugin using
javac, you must configure the plugin option forceJavacCompilerUse.
Is there a way to make the executable use the same instead of javac if that is causing the issue?
Any help is greatly appreciated.

setting JAVA_HOME for Maven ONLY regardless of my code java

I am running different java projects. Understanding that changing java_home system environment each time I switch between them is a bad idea, I'm starting to set JAVA_HOME specifically for each one of them independently.
When I set JAVA_HOME for maven (version 2) runtime (the java maven uses to run, being a java application)?
To my understanding, JAVA_HOME for maven should not affect how my code is compiled and run (which are supposed to be configured using maven-compiler-plugin source and target). Right?
When I set JAVA_HOME in mvn.bat:
#REM Maven2 Start Up Batch script
set JAVA_HOME=C:\dev\tools\jdk-1.6
And my maven-compiler-plugin is configured this way:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
I receive this error:
[ERROR] BUILD ERROR
[INFO] --------------------------------------
[INFO] Fatal error compiling
Embedded error: invalid target release: 1.7
Why does JAVA_HOME specified for maven runtime affect my code compilation? How to separate between the two?
Maven will use the JRE specified in JAVA_HOME
By default it will use the JDK from the same folder for compiling .java files
However you can change it in maven-compile-plugin configuration
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable><!-- path-to-javac --></executable>
<compilerVersion>1.3</compilerVersion>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>

How to use Java 8 for JMH?

I wrote a benchmark using JMH and when building I get the following a compilation failure
lambda expressions are not supported in -source 1.6
[ERROR] (use -source 8 or higher to enable lambda expressions)
JAVA_HOME is set to jdk1.8_40.
I have tried changing target and source in the pom.xml in jmh source folder jmh-core :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerVersion>1.8</compilerVersion>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
But I still get the same error
Are you using a Mac? If so, java 6 is already installed. I recommend just removing it from /System/Library/Java/JavaVirtualMachines/ .
Regardless, check java -version to see what jdk version is being used. Then type mvn -version on the command line. Is it pointed to java 6? If so, add the following to your ~/.mavenrc:
export JAVA_HOME=/Library/Java/JavaVirtualMachines/{jdk-version}/Contents/Home
Where jdk-version would be your version of java 8

Categories

Resources