I am using Java 14 as the default Java platform for Netbeans 11.3 (netbeans_jdkhome is set to my Java 14 JDK) and trying to use a preview feature in a simple Java application. I set the source level to 14 and set --enable-preview as a compiler argument. The code compiles without errors.
However, when I try to run it within Netbeans, it complains that the major version of the .class files is 57 while the runtime only plays well with 58 files and preview features. Here's the error:
java.lang.UnsupportedClassVersionError: javaapplicationtest14/JavaApplicationTest14 (class file version 57.65535) was compiled with preview features that are unsupported. This version of the Java Runtime only recognizes preview features for class file version 58.65535
I checked the major version of the .class files and they are indeed 57. Any ideas why my project won't compile into Java 14 level? I am using an Ant build.
As well as setting --enable-preview as a compiler option, it should also be set as a VM Option when running the code:
However, that doesn't fix the problem, and unfortunately this looks like a NetBeans 11.3 bug. I reproduced your problem with a Java with Ant project, and created Bug Report NETBEANS-4049 UnsupportedClassVersionError when running JDK14 code with --enable-preview.
There are a couple of workarounds if you need to use preview features with JDK 14 in NetBeans:
Run your application from the command line (with --enable-preview as an option) instead of within NetBeans. The same code which fails with the UnsupportedClassVersionError in NetBeans runs fine in that environment, which strongly suggests that NetBeans is ignoring the --enable-preview run time option.
Create a Java with Maven project instead of a Java with Ant project. You can then run your code which uses preview features within NetBeans.
Update your question with more details if you still have problems.
Netbeans Project Configuration (Java 14)
Java 14
Netbeans >= 11 (Current: 12.0 LTS)
Optional:
Can use sdkman or set default java path:
/opt/<jdk-install-dir>
C:\Program Files\<jdk-install-dir>
Project 'Run' Configuration
Java Platform
pom.xml
Notes
Check maven.compiler.source / maven.compiler.target
Check build->plugins->plugin->...-> compilerArgs -> arg
<?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>com.mycompany</groupId>
<artifactId>Demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerArgs>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
nb-javac should not be installed (it appears in the plugins).
If it is installed in 11.3, it seems to create classfiles with version 57 not 58, which the runtime then objects to, as above.
I'm trying this with Netbeans 15. I want to use the foreign linker API, and code completion is saying:
MemoryAddress is a preview API and is disabled by default. (use
--enable-preview to enable preview APIs)
This is with both JDK 19 and JDK 20 preview. I put the --enable-preview option in the pom.xml and it doesn't change anything. If I go to project properties / Build / Compile, there are options to choose which JDK but no way to enter JDK options. It seems like --enable-preview is recommended by NetBeans hints but there's no way to actually do it. Is this a bug in NB or am I missing something? Very frustrating because I would like to use some of these features and I'm spending my time trying to get my code editor to work. I think this did work in previous versions of NB.
Related
I have a requirement to compile an app for use under JRE 6.
Initially the app was compiled for use under JRE 8.
So I added:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
to pom.xml
After fixing all the errors caused by unavaiable diamond operator, string in switch statement etc. I ran the app under JRE 6 and got the error.
Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: java/nio/file/Paths
Ok. This class is available only since Java 7. But the question arises: what does the above maven setting exactly? Does it only check the syntax? If so, then it's not quite useful.
What needs to be done to configure maven so that it notifies me about missing classes in particular Java version too?
java.nio.file.Paths was introduced in Java 7. You will have to change the implementation of your code to only use classes available in Java 6.
And yes, the Maven property only tells javac to use Java 6 syntax. That's very useful. Maven will not magically change your code for you. javac started by mvn package will tell you about unresolveable imports.
The purpose is to instruct maven to pass the -source and -target to the javac compile executable. It makes sure you only use language features that are available in the given JRE (the diamond operator is a great example), but it does not prevent use of APIs that only came along later.
Have a read of this
In particular the part at the bottom of the page:
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...
I think it's unfair to say the parameters are not useful they certainly are. But they are not magical tools that know which libraries may be available at runtime.
The Animal Sniffer plugin for maven verifies that classes compiled with a newer JDK/API are compatible with an older JDK/API.
https://www.mojohaus.org/animal-sniffer/
Ok. I figured out how to do it.
You don't have to install the target JDK or JRE. All you need is rt.jar from that JRE.
Then you have to set the path to the jar file in bootclasspath in pom.xml.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<compilerArguments>
<verbose />
<bootclasspath>C:/data/tmp/rt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
I'm running Eclipse 2018-09 (4.9.0) on Windows 10. I'm using Open JDK 11 GA. I have a Maven project that was specified as using Java 8 source code.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
That compiles fine using Maven 3.5.3 on the command line. That also compiles fine using Eclipse Eclipse 2018-09 (4.9.0).
I changed the compile Java versions to Java 11:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
That still builds fine on the command line using Maven 3.5.3. But in Eclipse 2018-09, I get errors all over the place:
'<>' operator is not allowed for source level below 1.7
Constructor references are allowed only at source level 1.8 or above
Default methods are allowed only at source level 1.8 or above
You get the idea.
I've already used Alt+F5 to update my Maven project (and subprojects) in Eclipse. I've done a complete clean and rebuild.
Because this compiles fine with Maven on the command line, this has to be an Eclipse problem, doesn't it? Sure, Eclipse doesn't support all new Java 11 features, yet, but this code has no Java 11 specific features. What's wrong?
It sounds like Eclipse is not picking up the versions from the pom.
I just tested your pom configuration and verified that it works, either by providing compiler source and target properties like in the question or the new release property as described in this answer, using the latest Java 11 Support for Eclipse 2018-09 plugin.
It is important that the the JDK 11 is correctly set up in the Eclipse preferences. Add the JDK 11 on the "Installed JRE" preference page and then match it with the JavaSE-11 on the "Execution Environment" preference page. Otherwise updating the Maven project will result in the default JDK being used, which is likely the issue that you are having.
Update: Java 11 is fully integrated in Eclipse since Version 4.10 (released 2018-12-19), so one do not need to install this plugin anymore.
For some reason you need to install an additional Eclipse Plugin "Java 11 Support for Eclipse 2018-09 (4.9)" (even in Eclipse Photon 4.9)
It seams that the plugin is not available in Eclipse Marketplace anymore. I someone find its install url, please add it here:
Works for Eclipse - STS 4.0.1 (based on Eclipse 4.9) , Maven 3.6.0, with this Maven Compiler Plugin Configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
This problem is fixed in Eclipse 2018-12. Upgrading to that version will resolve your issue.
No need to add any plugin.
You only need to upgrade eclipse such that it can handle jdk 11 compiler like mentioned in the attachment.
You don't need to upgrade eclipse in case you have the option to set the jdk 11 compiler.
**Note: Go to the Java Compiler post selecting the project properties and then Click on Configure Workspace settings to mention JDK 11.
I have an Eclipse Mars 2 Java8, Maven 3.5.4 based workspace.
I build the project files with mvn eclipse:clean eclipse:eclipse, and watch the following maven output:
[INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-**1.7**
The default JRE for the workspace isn't Java 7, it is Java 8, like you can see looking at the following Eclipse config file:
<workspace>\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.jdt.launching.prefs.
that contains the following data:
org.eclipse.jdt.launching.PREF_VM_XML=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>
<vmSettings defaultVM\="57,org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType13,1538040823497*">
<vmType id\="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType">
<vm id\="1431694854640" name\="jdk1.7.0_40" path\="C\:\\Program Files\\Java\\jdk1.7.0_40"/>
<vm id\="1447417000092" name\="jdk1.6.0_45" path\="C\:\\Program Files\\Java\\jdk1.6.0_45"/>
<vm id\="1538040823497" name\="jdk1.8.0_65" path\="C\:\\Program Files\\Java\\jdk1.8.0_65"/>
</vmType>
</vmSettings>
As you may notice by looking at the above configuration, the default VM has the vm id "1538040823497", which is named jdk1.8.0_65, and resides in C\:\\Program Files\\Java\\jdk1.8.0_65.
This VM is correctly registered as Workspace Default in Eclipse Preferences, Java/Installed JREs, is marked as a "perfect match" within the Execution Environment JAVASE-1.8.
I cannot see anything why Maven Eclipse Plugin considers
org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7 as the correct choice, and not JAVASE-1.8.
I already deleted all JREs and registered them newly.
Now there's exactly one 1.6, 1.7 and 1.8 Environment, each with a "perfect match", and 1.8 is checked as default (as you can see above).
I have to manually correct the project each time I generated it (Edit Build Path, change JRE library from 7 to 8), since all files using Java 8 features like streams or lambda functions signal compiler errors unless I assign the correct JRE manually.
I already tried and manipulate org.eclipse.jdt.launching.prefs, redefine all JREs, pray, curse or ask an Ouija board, to no avail, always Java 7 is assigned by the eclipse plugin (version 2.10, by the way).
Any ideas, anyone?
In your pom file, try to use this:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
You may also reference this link:
https://dzone.com/articles/maven-eclipse-and-java-9
Or if all fails, try eclipse oxygen, a newer version (not the newest release but much better than Mars IMO) that has Maven Integration plugin pre-installed, all you need is to add a m2e-connector plugin.
I'm running a Java Maven project on IntelliJ, and I make sure that this project will be compiled by Java 1.8.
I set JRE to version 8 in Run/Debug Configuration
and also in Project Structure:
My pom.xml file also includes java version 8 by the following:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
and
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
I also set Java compiler option to version 1.8.
When I run the project, I get an error:
Failed to execute goal
org.apache.maven.plugins:maven-compiler-plugin:3.0:compile
(default-compile) on project feed_matcher: Fatal error compiling:
invalid target release: 1.8 -> [Help 1]
Do you know how to resolve this issue?
P.S I followed this link: IDEA: javac: source release 1.7 requires target release 1.7 and I still couldn't resolve the problem.
I assume you want to have it in version 8, despite so many comments telling you to set to 7.
You probably missed the setting for the maven runner, this is under Preferences -> Build, Exection, Deployment > Build Tools > Maven > Runner, see attached image. You need to set that to Java 8 as well.
Look in Build Execution, Deployment > Compiler > Java Compiler
Then look for per module bytecode version
Make sure JAVA_HOME is set to JDK7 or JRE7. This is explained in the
following link
Make sure that you open a new shell an run intellij
If this doesnt work, look at at the idea.bat file which is used to run intellij - make sure it uses jdk7/jre7
Make sure the JDKs are defined properly in your project. Look at this link for more information.
Make sure that the source is defined as 1.7 at maven
The above 4 steps always helped me to troubleshoot such issues.
The method java.lang.Long.compare(x, y) exists in Java 7 but not Java 6. So obviously this causes a NoSuchMethodException if code using this method is deployed to a server running Java 6.
However, either Maven nor Eclipse were picking up the error despite having set the source-compliance level to 1.6 in eclipse and the maven compiler source & target to 1.6.
Is there a way to enforce full Java 6 compliance in Eclipse, apart from downgrading my JRE to 6?
This is exactly why the animalsniffer-maven-plugin was introduced:
Animal Sniffer provides tools to assist verifying that classes compiled with a newer JDK/API are compatible with an older JDK/API.
This is what I put in my POM.
<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" >
...
<properties>
<java-version>1.6</java-version>
</properties>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
</project>
Once I have that defined in my POM I right click the project and go to Maven > Update project. This will apply any settings in the pom to the eclipse project which ensures the two are in sync.
In terms of JDK I use the latest JDK but compiled to the lower release. We're currently using JDK 7 but compile to 6. This gives you the best of both worlds in that the compiler will still make use of any optimizations that were introduced with 7 that are compatible with version 6.
There is a way to cross-compile Java source code, but the easiest way is to use the min. required JDK version when creating your artifacts (JARs etc.)/ during development.
-> use JDK 6 during development and releasing.
Note however that Oracle's JDK 6 reached End of Life and it is strongly recommended to upgrade to Java 7 if you don't have special support contracts with Oracle (or using a JDK from a different vendor).
Note: the source-level only makes sure you're using syntax constructs supported by that version and the target-level only makes sure the resulting class file is bytecode compliant to the specified version.