How to execute gradle plugin with different version of java - java

I am running into an issue with my gradle build script, build.gradle, for my java project. In this script I need to compile the application with Java 6 in order to comply with the application specifications. However, I am also using a gradle plugin that performs code analysis that needs to be run under a Java 8 JVM. What do I need to do in build.gradle or other gradle settings in order to get this plugin to use a separate Java JVM?
I need to do something like this as gradle tasks fail because the plugin is reporting a Unsupported major.minor version 52.0 Error.
Research
I have done some invesitigation and I did see the following mentioned:
options.fork = true
options.forkOptions.executable = System.getenv('OTHER_JAVA')
Where OTHER_JAVA is an environment variable to the other version of Java. However, I have not been able to get this to work for the plug-in and after some more research, it looks like this may be more limited to compiling with a separate version of java, not executing.
See: How do I tell Gradle to use specific JDK version?

You've pretty much answered your question yourself:
it looks like this may be more limited to compiling with a separate version of java, not executing
Run Gradle under the Java 8 (that would mean specifying your JAVA_HOME as JDK 8), and fork the compiler for your app with Java 6 (as per your research).

Related

Why would Gradle attempt to use Java 8 when I told it to run Java 14?

I'm learning how to use Gradle to build projects in IntelliJ. I want to build a project involving OpenJFX. However, I encounter this error.
java.lang.UnsupportedClassVersionError: org/openjfx/gradle/JavaFXPlugin has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
> org/openjfx/gradle/JavaFXPlugin has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
From what I can figure out, Gradle is using Java 8 to run a Java 11 plugin. However, I put this in gradle.properties:
org.gradle.java.home=/C:/Users/<my user>/.jdks/openjdk-14.0.1
The reason it's in .jdks is because IntelliJ downloaded it earlier. The thing is, I told Gradle to use Java 14, yet it gives me an error as if it's being run by Java 8. What's wrong here?
According to the docs org.gradle.java.home property…
…specifies the Java home for the Gradle build process. The value can be set to either a jdk or jre location, however, depending on what your build does, using a JDK is safer. A reasonable default is derived from your environment (JAVA_HOME or the path to java) if the setting is unspecified. This does not affect the version of Java used to launch the Gradle client VM
So, this value is only used for build process (like compiling or running app or tests). Gradle spins up a child process for that, so the VM that performs tasks and the VM that runs the build script may not be the same.
It looks like you're using a Gradle plugin compiled with Java 11 (55.0), but your Gradle VM is Java 8 (52.0), so it cannot load and use plugin's class. You must use Java 11+ for Gradle VM itself.
Try running you build like JAVA_HOME=C:/Users/<my user>/.jdks/openjdk-14.0.1 gradlew.bat clean run.
I found out how to change Gradle's JVM. In IntelliJ, go to Preferences (Ctrl-Alt-S); then Build, Execution, Deployment; then Build Tools > Gradle. There's a little menu that lets you choose between the JVMs it recognizes.

Does Gradle require JDK to compile Java?

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.

Update Legacy Project from JVM 1.6 to 1.8

I have to update my legacy project from JVM 1.6 to 1.8. Obviously, I'll need to make some changes like install JVM 1.8 on the server that the code will run.
My project is Java based.
What tasks do I need to do to accomplish this?
What risks or complications should I be aware of and plan for?
I'm using Maven. Do I have to make changes to my pom files?
do I have to make changes to my startup bash scripts?
what do I need to do to ensure that the code is compiled under 1.8?
links:
Upgrading existing Java Project from Java 1.6 to 1.8
Just compile using jdk 1.8 and check for any warnings about
deprecated methods.
Java 8 introduces lots of features like lambda streams..etc, try to enhance your code wherever required. (its not mandatory though)
Always good to use latest dependencies
No changes are required to start bash scripts
Since youare migrating from java 6 to java , you could use try with resource feature which is introduced in java 7.
Try to enhance your code wherever it is applicable. Good luck

Execution environment setting in run configuration

When creating a launch configuration you can specify an Execution environment, how is that more specifically used? I assume it ends up as a parameter to Java?
What are the consequences if we have a plugin built with JavaSE-1.8 execution environment, and run an application using that plugin and run it with execution environment JRE-1.1?
Explanation:
It won't run. Execution environment says the code is intended to be executed in a certain Java implementation. This affects both: the bytecode version your sources get compiled into and Java Class Library you're code is intended to use. The setting is used by IDE (not sure all IDEs use it - Eclipse does) to make sure you only write code possible to execute in a give EE.
Bytecode incompatibility example:
Java 8 added lambda support - if you use it your bytecode will have labmda related instructions and it will not execute in older JVMs.
JCL incompatibility example:
Java 8 introduced URLPermission class. If you refer to it in your code and try to run it against older Java Class Library you'll get an exception. Even if you compile your code into older bytecode version. The class is simply not accessible in older JCL.
Links:
Eclipse community has a lot of resources on Java Execution Environments - read about it here.
1.8 to 1.1? so much of discord in versions? Anyways, launch configuration has data about path of jre, depenedency jars and location of files where parameters needed by program are stored.
if you change env, your code may not be source compatible or you may get errors like 'file not found /class not found'.

How to force Gradle to re-compile all subprojects sources?

I have a multi-modules Gradle project.
I compiled everything with Java 8 just to find out that my project does not work in Java 8 (some Groovy or Swing issue), so I changed my java back to Java 7, but now when I try to run, even after doing gradle clean run which I thought would re-compile everything (run depends on jar), I get Unsupported major.minor version 52.0 which from experience means my class files were compiled with a Java version higher than I am trying to run it with (or some class files were compiled with incompatible java versions).
Looks like the only way to force Gradle to recompile a subproject is to change some source file... but as I have quite a few subprojects, this is too inconvenient. Is there some way to force Gradle to re-compile everything even without any changes?
It turns out it was something else causing my problem... I had changed my Java version using update-alternatives --config java, but unfortunately this does not change JAVA_HOME which Gradle seems to use for compilation... but the plugin I was using to run the code does not care about JAVA_HOME and just uses the system java... as JAVA_HOME and /usr/bin/java have different versions, that's what was causing my issue!
Sorry if anyone wasted any time on this... but hope this might actually help anyone else in the future :)

Categories