Java Maven build source and targe is not working - java

I have JDK 7 and 8 installed in my PC.
I try to set JAVA_HOME to JDK 8 and in the maven pom file, I set to 1.7 as below:
<properties>
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>
</properties>
I got the error below during maven build:
incomparable types: boolean and java.lang.Object
The source code is:
Map mapData = (LinkedHashMap)it.next();
if(true == mapData.get("isTrueOrFalse")){ // java 8 doesn't allow this, it have to be [true == (boolean)mapData.get("isTrueOrFalse")]
xxx
}
I can't change the source code, so I change my JAVA_HOME to JDK 7 and maven pom remain as 1.7. Then I can successfully build via Maven.
My understanding is, by setting the source and target, it should allow me to compile onto lower compatible Java version, but it is not. Can anyone help to explain this?

Apache Maven page says that:
Merely setting the target option does not guarantee that your code actually runs on a JRE with the specified version (...) In the same way, setting the source option does not guarantee that your code actually compiles on a JDK with the specified version
You could try first configuring the plugin directly (instead of what you have on pom.xml):
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable><!-- path-to-javac --></executable>
<compilerVersion>1.7</compilerVersion>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
Lastly, you can try Compiling Sources Using A Different JDK

After so many of searching of Java compatibility post, I found two possible reasons why this is happening:
1) this is a bug in JDK 7, it should not allow JDK 7 to compile this as the type is not match. This is fixed in JDK 8, so even we use the -source=1.7 and -target=1.7, it is not allowed to go through. JDK 1.7 breaks backward compatibility? (generics)
2) this might due to the Java implementation return type not compatible, while using JDK 8 compile to -source=1.7 and -target=1.7, the build path (bootstrap classes) will be still pointing to JDK 8, as so the implementation of Java Map may return different type which cause issue above. Issue about java 8 backward compatibility: new methods in JDK

Related

Clear/unset a system property maven.compiler.release so that is is no longer present

I have a project with complicated build setup (parent POM's with parent POM's) and so it happens that my compiler plugin executes with maven.compiler.release=8.
This prevents me from setting source/target to Java 11 and I can't set release to 11 since I need to specify some --add-exports.
Is there a way to remove a system property in a profile so that it will not appear and my source/target switches would work? The best I could think of is setting maven.compiler.release to empty value but it won't work with compiler plugin.
How do I clear the system property in a profile? Alternatively, is there a way to trace who actually set it in the first place?
I had similar problem. Here is how to delete release property from parent POM and use --add-exports.
Use the combine.self="override" attribute like this
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release combine.self="override"/>
<compilerArgs>
<arg>--add-exports</arg>
<arg>jdk.compiler/com.sun.tools.javac.api=ALL-NNAMED</arg>
</compilerArgs>
...
et, voila!

Java 11 with Powermock - Are they compatible?

After switching to Java 11, all the powermock related tests (annotated with #RunWith(PowermockRunner.class) and #PowerMockIgnore) are failing.
Is this known issue? I read a relevant SO post which was posted a year ago, and the latest release of Powermock was 2 months ago. I don't see any difference in behaviour with JDK 11.
For better clarity, it would be great if you could specify the powermock API version, what i can think of the probable clause of the exception would be PowerMock classloader reloads XML11Configuration but without specifying module/or ignore module of the class. As result the unnamed module is autogenerated.
I can suggest another workaround. If it works then my guess is correct. Could you try to
use this option #PowerMockIgnore({"com.sun.org.apache.xerces.", "javax.xml.parsers.",, "javax.xml.", "org.xml."})
It should work.
The existing "mvn hpi:run" command will not work correctly on Java
11 unless Java modules are downloaded and passed to the environment.
List item If you use Mockito/PowerMock in your plugin tests, you may need to update to the recent versions with Java 11 support-
You may also need to add test annotations to workaround PowerMock
Issue #864. Example for the Jenkins Core
Adding byte buddy dependency helped me to run PowerMock tests in java 14.
As mentioned above PowerMock reflection access internal packages java.xml/jdk.xml, a workaround consist in allowing access to those internal packages :
if you are using maven to build your project you should add the JVM argument :
--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
for example :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--add-opens java.xml/jdk.xml.internal=ALL-UNNAMED</argLine>
</configuration>
</plugin>
If use reflect in JDK11, you might see some warning like 'An illegal reflective access operation has occurred', because reflect JDK inner API is illegal since JDK9, still you can use it with a warning above.
To fix the problem temporary, try to use --add-exports or --add-opens in your argLing.
For example: --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<argLine>
#{argLine} --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
For more infomation, watch --add-opens introduce

Error while committing and pushing Java application from Eclipse to Openshift server (String in switch not supported)

BUILD FAILURE
Hi,
I successfully set up everything to apply changes to my application located on Openshift server. Suddenly I decided to use some of my Java classes from other project and when I try to commit changes I get this error.
I am really hopeless with the error as I was researching for about a day and google just go blank on me with this and related questions. The problem is that I can't figure out what the "-source 7" stands for and if it related to the "-source 1.6" that is mentioned in the line above it in the error message.
Error message:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler- plugin:2.3.2:compile (default-compile) on project organizer: Compilation failure: Compilation failure:
[ERROR] /var/lib/openshift/56c42c687628e1f0a2000073/app-root/runtime/repo/src/main/java/organizer/DataOperations.java:[185,9] error: strings in switch are not supported in -source 1.6
[ERROR] (use -source 7 or higher to enable strings in switch)
This error is repeated for every instance of using String in switch statement.
EDIT: I am looking for a solution not only explanation. Trying to configure pom file atm.
I appreciate any help at all..
Thank you,
Ondrej
As noted above, String in Switch statements are only supported in Java 7+.
Looking at the error message you should update your POM to include the following i.e. explicitly compile against Java 7.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins?
</pluginManagement>
<build>

#Override not working in Maven project

I have several override methods like this:
#Override
public int compareTo(Property p) {
return getText().compareTo(p.getText());
}
As a Java project, it works fine, but as a Maven project, it returns the following error:
The method compareTo(Property) of type Property must override a superclass method
After researching into this, I think I'm suppose to include my JRE System Library (jdk1.6_u25) as a dependency in my POM file, or is this a completely different problem all together?
Many thanks.
You don't need another dependency. But by default, maven uses Java 5 language level, where #Override wasn't allowed for implementing interface methods. That was introduced in 6.
So you must configure the compiler plugin to use language level 6 like this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
compareTo is a generic method. Generics are not used so compareTo(Object) is the only method you can override.
Please check that:
Maven uses a java to compile that supports generics.
Source-Level is >= 5.
execute mvn -V to see what version of java maven uses to compile.
Regards
Thank you all for your comments, a lot of you stated that Maven used Java 5 by default and could be the cause of the issue, and as a result, I was able to determine the problem through this answer:
Why is javac failing on #Override annotation
The JDK compiler's compliance level was set to 1.5 by default; once I set it to 1.6, the errors were removed.
Many thanks.

Setting the -source and -target of the Java Compiler with Maven - doesn't work

I have set my pom file to ask Maven to compile my source code to be version 1.5 compatible using the source and target config params. Here is 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">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
And I have a simple main class like this:
package com.user;
public class Test
{
public static void main(String[] argv)
{
System.out.println("".isEmpty());
}
}
String#isEmpty() was introduced since Java 1.6. However, compiling my code with mvn compile works, while I would have expected it to fail because I have set Maven to compile my code to Java 1.5 and String#isEmpty was introduced in Java 1.6. Could anyone please suggest what I might have done wrong? What is the correct way to force Maven to use a particular Java version when compiling?
For information, I am using Apache Maven 2.2.1 and javac 1.6.0_19.
Thanks.
From the note at the bottom of the compiler-plugin 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 which would make your code fail at runtime with a linkage error. To avoid this issue, you can either configure the compiler's boot classpath to match the target JRE or use the Animal Sniffer Maven Plugin to verify your code doesn't use unintended APIs
This means that although you're generating 1.5-level bytecode, you can still (unintentionally) call a 1.6 API method. To flag these invalide API calls, use the plugin they mention.
You need to compile with a lower version of Java if you want it to not find String.isEmpty(). The source level controls language-level features you can and can't use, such as #Override on interfaces requiring compilation with source level 1.6. The target level controls the compatibility of the bytecode that compilation produces. Neither have anything to do with available APIs... that's all based on the classpath you use when building, which in your case includes Java 1.6.

Categories

Resources