If the Java version is to old then Java produce such very cryptic error message: UnsupportedClassVersionError... . Although we have the necessary Java version in the release notes, many customers contact the support with this error message.
Is there a simple solution to show the users a better error message?
We use Gradle for the building. How can I compile a small set of files with a lower class file version? In this files we can do a version check to display the error message.
Of course we can't change the class file version of the completely project.
How can I compile a small set of files with a lower class file version?
Use the -source and -target options of the javac command (see the reference documentation), or since you're using Gradle, use the appropriate corresponding settings in the Gradle build file for the part that you need to be able to run on an older Java version.
For Gradle you can use the sourceCompatibility and targetCompatibility properties, see Table 47.8 in the Gradle documentation.
I've created a small library called use-newer-java which you can use to perform the version check:
Include use-newer-java as a dependency in your project
Set the Main-Class: field in the manifest of your built jar to
use.newer.java.Version8 or use.newer.java.Version9, etc as appropriate.
Set the Main-Class-After-UseNewerJava-Check: in your jar manifest to the normal main class of your app - Use Newer Java will follow this setting, and invoke this code after making it's check.
https://github.com/rtyley/use-newer-java
Distribute your application via JWS. It ha provisions for ensuring that the required JRE version is installed.
Related
My build.gradle uses a custom task, which I defined in the buildSrc/src/main/java directory using Java 11. Now, I need to build on a different machine which only has Java 8 installed, so the Gradle build cannot even configure because it complains of errors in my custom task. Of course, I could install Java 11 in my home directory (since I don't have root privileges on this machine) and run Gradle with a custom JAVA_HOME, but is there a way that Gradle could automate this process. That is, could I somehow declare the Java version required for buildSrc so that Gradle will download and use that version?
Gradle toolchains looks somewhat promising, but it is not obvious how this should be applied to buildSrc.
For my project I want to use SymJava. The README there requires me to install the Java Operator Overloading support. Since I am using Intellij IDEA (Version 2019.1.2), I tried to follow the directive given. However, I am confused by the second step:
Add javac8-oo-plugin.jar as compile or processor library.
What is meant by "compile or processor library"?
Also a note: I did the first step before. This made Intellij IDEA ask me to restart the IDE. When I did that, a fatal error initializing the plugin occured when re-opening the IDE and my project:
What may be my misunderstanding in the process? I am using Java 15.0.1 here. Is that the problem perhaps, since it says something about using Java 8? I assumed it should work with later versions nevertheless.
Since I need to use this newer Java version, is it impossible for me to use SymJava then? And if so, can you recommend an alternative library similar to this (which is a Java counterpart to SymPy)?
Add javac8-oo-plugin.jar as compile or processor library.
Means that you need to add this jar to the module classpath by adding it as a module library. This will add it to compile classpath and to processor path if you have the Settings (Preferences on macOS) | Build, Execution, Deployment | Compiler | Annotation Processors | | Obtain processors from project classpath option enabled.
a fatal error initializing the plugin occured when re-opening the IDE and my project:
Double check the plugin zip archive file is not corrupted and is compatible with this IDE version. Btw I was unable to download it from github from the README instrucitons. You may need to better contact the repository author about this.
I finally came to the conclusion that SymJava is not suitable for any Java version above Java 8. This is, because SymJava uses the "java-oo" library. Since java-oo only supports Java 8, it's not possible to use SymJava, either.
The current solution is to use a different library, like Symja, which contains similar features while also supporting Java versions later than Java 8.
Does Gradle requires JDK to compile Java source files?
or it is using its own internal compiler?
Thanks in advance
Short version: JRE for installing and running, Groovy build script compiled by Gradle own compiler, JDK for Java source code compilation.
Long version: There are multiple points of interest:
1) Installing & running
In order to install Gradle and run Gradle build you need a JDK or JRE which version is at least 7.
Gradle uses mainly Groovy as a language but it comes with its own library and ignores any other Groovy library that is installed. Therefore the compiler is the Groovy compiler of the Groovy library that Gradle comes with.
As a side note, you can also use Kotlin for scripting builds as described here. Which of course involves a Kotlin compiler.
You can check the JVM version by running gradle -v.
This means that during installation the runtime configured in JAVA_HOME will be used.
Also the same happens for running a build, unless you are explicitly overriding JAVA_HOME in gradle.properties using the following property org.gradle.java.home. This property and others are defined here.
JAVA_HOME can point to a JDK or JRE. In this case does suffice to have only a JRE installation.
2) Source Code Compilation
To remove any confusion, source code, means that you have your project sources, written in a language, which need to be compiled into bytecode. At previous point the code being written is the actual build script code which is a separate thing, compiled and handled by Gradle.
Source code is being compiled using Gradle plugins, being it java, groovy, kotlin, or anything else.
You can compile your JAVA source code by using the java plugin or the newer java-library plugin. The two are similar.
The JDK being used will be the one configured in JAVA_HOME or can be explicitly defined in gradle.properties using the following property org.gradle.java.home.
JAVA_HOME needs to point to the JDK not a JRE for this case.
As stated above, Gradle can only run on Java 7 or higher. But it can be configured to compile, run, test, javadoc for Java 6 by following these steps. Therefore this advanced customization can be used to handle some corner cases which may not have a resolution in simply changing gradle.properties.
The two plugins provide also two properties:
sourceCompatibility - Java version compatibility to use when compiling Java source
targetCompatibility - Java version to generate classes for.
These are related to the source language version used as input and the target bytecode version to be generated.
Hi I wanted to upgrade android-apt in my project from version 1.4 to 1.7
Currently I'm using Google auto-service 1.0-rc2, so all what I had to do is putting #AutoService(Processor.class) annotation in my annotation processor class.
After updating android-apt to 1.7 version my annotation processor stopped working. It seem it is not called during build.
I thought that auto-service may be the issue. So I made resources/META-INF/services/javax.annotation.processing.Processor file with content
pl.edu.radomski.navigator.NavigatorAnnotationProcessor
Sadly it didn't helped at all.
If you want to see the code with android-apt 1.4 and auto-service 1.0-rc2 it is available here
Is there any simple way to upgrade android-apt and keep the processor working?
Is this auto-service 1.0-rc2 fault or something is wrong with android-apt?
In 1.7 a change was made to not automatically build a dependent project that is set as apt, due to unwanted side effects affecting build order.
In 1.8 I'll probably have a better way to support it, but in the mean time you can configure the apt block to specify that your processor should be run like this:
apt {
processor "pl.edu.radomski.navigator.NavigatorAnnotationProcessor"
}
Note that is only needed in the case your processor is in the same project as your app or library. The reason is that the file in META-INF/services is not read by javac in this setup because the project isn't packaged at that point. Explicitly adding a processor statement will add the processor that javac otherwise would not discover.
I am running Eclipse Luna (4.4.1) under Ubuntu 14.10 (Utopic Unicorn) and have a project that uses annotation processing to validate certain forms in the code and generate utility code. In eclipse the code is not being generated.
First, the processors work perfectly with javac. Second the processors DO run in Eclipse. If I alter them to throw exceptions Eclipse reports that. Also if I provide the processors with malformed code (such as a getter/setter pair with different types) it reports the error properly (red squiggles, proper error message, whole nine yards).
No code appears in .apt_generated nor are class files generated.
I've tried disabling them and re-enabling them, starting a new project, tried it on a fresh install of Eclipse, changing the project version from 1.7 to 1.8 and back again, tried batch mode and not batch mode, changing the .apt_generated directory, double checked the permissions on .apt_generated, probably a few other things that I can't recall.
At this point I'm just running javac separately and thinking about making this our first Apache Ant or Maven project if that would help but I'd rather not quite at this juncture.
Anyone have any luck with code generation within Eclipse? Anything else to do or check?
Verify your project is set to actually use APT, as shown in https://www.eclipse.org/jdt/apt/introToAPT.php. Be aware those are project settings, not workspace preferences.
Make sure your potentially generated code is not deleted by some other part of your workflow. E.g. a second processor cleaning the directory that a first processor generated into.
Check that you are using a JDT and not a JRE both for running Eclipse as well as building your project.
Verify that org.eclipse.jdt.apt.core is part of your Eclipse installation, as that is the actual annotation processor integration for the JDT.
Verify your processor has a correctly filled file META-INF/services/javax.annotation.processing.Processor, pointing to the right class implementing the processor. Eclipse may ignore it otherwise.
That being said, I have used different annotation processors (like butterknife for Android) in Eclipse over the years and didn't run into such problems.
I had a similar problem with the AutoValue annotations not being processed with Eclipse 2019-3 with OpenJDK 11 as target runtime. In the Eclipse "Error Log" panel I saw this error:
java.lang.Exception: java.lang.UnsupportedClassVersionError:
javax/lang/model/element/ModuleElement has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
Eclipse was running on an old Java 8 installation as indicated by Help -> About Eclipse IDE -> Installation Details -> Configuration. In my case, Eclipse found the JRE to run on on the PATH environment variable, see here. I forced Eclipse to use the OpenJDK 11 installation by adding the -vm argument to the Eclipse.ini:
-vm
"C:\path\to\OpenJDK\bin\server\jvm.dll"