Jenkins Maven compilation fails due to JDK features unsupported? [duplicate] - java

This question already has an answer here:
Maven - use -source 5 or higher to enable... while building the project
(1 answer)
Closed 8 years ago.
Whenever I deploy a Jenkins build with Maven, it says that I have the 1.3 JDK, even though I have 1.7 installed.
Here is a picture of the error log I get when using an enhanced for loop:
http://gyazo.com/d1c7e297199dbf8a8b6ba23efa5733ba.png
However, I clearly have 1.7 JDK installed.
http://gyazo.com/27b85ba9ea25579aa714b0e2586fd618.png
If anyone knows why this issue occurs and how to fix it, please post below.
Sorry I don't have a ton of formatted information, but I have no idea why this could possibly be happening as I do not have such an outdated JDK and have the most recent updates from Oracle. Maven and Jenkins are also updated completely.
Thanks.

The complaint of maven is not about your jdk version, but about the -source parameter of the compiler. Older Maven versions use a version of the maven-compiler-plugin, which uses -source and -target 1.3 by default.
So, what you need to do is configure you project to use higher source and target levels in order to use your for each loop:
(taken from https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html)
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>
Note that simply setting the version of the maven-compiler-plugin would actually be sufficient, since for version 3.1 the default is 1.5, however it is good style to explicitly include the source and target version in your master pom.

You have the project set to compile with the default jdk according to your stack trace. Your default is your %JAVA_HOME% environment variable on the server which is probably set to an older jdk. In order to compile with the 1.7 jdk you have to specify this in your project config. Change jdk : (Default) to your 1.7 name.. which is jdk.
Or you can just go to the maven jdk and change it from (inherit from project) to jdk.
There is already an issue ticket open with jenkins related to this: https://issues.jenkins-ci.org/browse/JENKINS-755

Related

Compiling for execution under JRE 6 with Maven

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>

Is there a Azure Service Bus version combatible with Java 7?

The Docs of Azure Service Bus have in example picture:
https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-java-how-to-use-queues#configure-your-application-to-use-service-bus
that it uses java 8. Also code samples use Java 8 syntax and functions. I have an environment of java 7 and I am unable to get it work supposedly because java is too old.
Does anyone know a working combination of the Azure Service Bus with Java 7? I would need either the version that works for sure or answer that no version does so.
I test with newest 1.2 version available of Azure Service Bus.
I checked the maven repository list of Azure ServiceBus, these versions after 0.9.8 are all built by Java 8 via check the pom.xml file, the version 0.9.8 is built by Java 1.6. Therefore, there is not any released jar files compiled by Java 7 or other ealier Java version for the latest version 1.x.x.
A workaround way for yours is manually to download the source codes of Azure ServiceBus from GitHub repo to compile it in maven by yourself. You can use JDK 7 to do it, even use JDK 8. The only changes you need is use 1.7 instead of 1.8 for the configuration of maven-compiler-plugin in pom.xml, such as below.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
<configuration>
<source>1.7</source> <!-- 1.8 -->
<target>1.7</target> <!-- 1.8 -->
<optimize>true</optimize>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
Note: If using JDK 8 to do this above for compiling with the javac parameter -target 1.7 -source 1.7, you must make sure there is not any code of using Java 8 features which will cause compiler error, such as error: lambda expressions are not supported in -source 1.7 for JDK 8. However, I roughly checked its source codes that there seems not to be. For more details about -target or -source for Javac 8, please see https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html.

Eclipse project: Maven Eclipse Plugin set wrong JRE class path container

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.

`class file has wrong version` after Jenkins upgrade

A couple of days ago, I upgraded Jenkins to version 1.643. Before, we were using Jenkins 1.593. Starting with Jenkins 1.612, Jenkins requires Java 7, see changelog, announcement and issue. Our Jenkins server has Java 8.
I have a Maven project consisting of submodules.
In the job configuration in Jenkins, I have configured the build to use JDK 1.6.
When looking at the build environment, it's indeed 1.6:
JAVA_HOME=/var/lib/jenkins/tools/hudson.model.JDK/1.6
One of the submodules fails to build on Jenkins, with this error:
[ERROR] /var/lib/jenkins/<REDACTED>.java:[15,-1] cannot access java.lang.Object
bad class file: java/lang/Object.class(java/lang:Object.class)
class file has wrong version 52.0, should be 50.0
According to what I can Google, class file version 52.0 is JDK 1.8 while the compiler is expecting version 50.0, which is JDK 1.6. I assuming that class file 52.0 refers to rt.jar (Java Runtime) which contains java.lang.Object (see also pom.xml snippet below).
I have found this SO question (and others that are duplicate of it), but they are all in the context of someone building from their IDE (IntelliJ) or from command prompt, and after reading them, I don't see how I could apply the suggested solutions. They involve setting $JAVA_HOME, which is already done by Jenkins.
My question is different because the issue is in the context of Jenkins (and Maven), and only occurred after the Jenkins upgrade. When I execute mvn clean install on my own desktop (with JDK 1.8), the error does not occur. If I execute the file command on the offending class file, but on the desktop where compilation succeeded, I get compiled Java class data, version 50.0 (Java 1.6). For me, this confirms that my pom.xml is (probably) still correct and it's (probably) a Jenkins configuration issue.
That specific submodule has this in the pom.xml, which may or may not be relevant:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}/lib/rt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
So, as you can see, it takes rt.jar from the current $JAVA_HOME so it can cross compile with a target of 1.6.
I'm a bit lost about the origin of this Java 8. Before the Jenkins upgrade, we were already using Java 8 on the server and cross compiling with a target of Java 6. What am I missing here?
EDIT
Do I even need this? If I comment out
<compilerArguments>
<verbose />
<bootclasspath>${java.home}/lib/rt.jar</bootclasspath>
</compilerArguments>
in pom.xml, I can still cross compile on my desktop and the class files are still version 50.0.
EDIT
When I take that part out, the build does not fail any more.
Which means I solved it myself.
I want to change the question to: why did it fail in the first place? And why didn't it fail before on Jenkins 1.593?
I changed my pom.xml to exactly how it is described in this SO answer: Maven release plugin: specify java compiler version
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
<bootclasspath>${java.home}/lib/rt.jar</bootclasspath>
</configuration>
</plugin>
</plugins>
</build>
As you can see:
I explicitly set the groupId
I explicitly set the version to the latest version, 3.3
The configuration parameters are formatted a bit differently.
My educated guess is that the Maven on the Jenkins server didn't pick up configuration inside compilerArguments and was only happy when it is directly inside configuration. I leave it to the comments to explain how and why, but for me the issue is solved.
I think you have a few errors in your assumptions.
compilerArguments is deprecated. It's been superseded by compilerArgs.
Like you can see from compiler plugin documentation, compilerArguments/compilerArgs is meant to be used only for arguments not supported by configuration section itself. As bootclasspath is supported, using it in compilerArgs/compilerArguments section is generally incorrect.
compilerArgs/compilerArguments is only used if fork is set to true, which was not correct for your configuration.
The third point was probably the most important reason why it didn't work for you. Using configuration section for your use case there should be no issues, and indeed based on your question/answer, this seems to be the case.
Also note that java.home is not JAVA_HOME. I've expanded on that on my other answer here. I'd guess that is related to why you see changes between Jenkins versions.

Errors regarding Jdk5 in intellij even though pom.xml explicitly sets source to 7

I have opened a maven project in Intellij (14.1.4 Ultimate) and the JDK is not being recognized. When attempting to run one of the programs the following error occurs - and in any case the file has a bunch of "red"s in it when viewed in the IDE:
Error:(55, 50) java: diamond operator is not supported in -source 1.5
(use -source 7 or higher to enable diamond operator)
This is strange because the normal settings are in place to use java7:
In pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
In the project - JDK level is set to 7:
Likewise in the Module:
But we get all sorts of issues when attempting to compile (even after reimporting maven projects):
Note: this project does build/run on command line using maven.
Also note: I have already tried blowing away the Intellij project and rebuilding from scratch. No change in behavior.
Update The following is a result of following (accepted) answer from #Peter Lawrey. We can see that the jdk got mysteriously set to 1.5. I have updated it to 1.7 manually.
Sometimes IntelliJ gets confused though I don't know why. The setting you need is
File -> Settings -> Build, Execution, Deployment -> Compiler -> Java Compiler
Find your module and change it to version 1.7 instead of 1.5.
I have projects with many modules and the same parent pom which sets this and sometimes just one of the many modules will think it's 1.5 when the rest are 1.8. i.e. the same configuration across many modules.

Categories

Resources