#Override not working in Maven project - java

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.

Related

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

Java Maven build source and targe is not working

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

Can't build JBox2D duplicate class(es)

I'm interested in learning JBox2D, but I seem to have stumbled at the first hurdle - building the library.
The Quick-start instructions specify the following simple steps:
Check out the project through Subversion:
Import to your IDE as a Maven project (using the pom.xml descriptor in the root folder)
Run the org.jbox2d.testbed.framework.TestbedMain class
I've checked out the code and imported the project in to IntelliJ IDEA (12.1.4), however, when I try to run the TestbedMain class (and it subsequently compiles the code) I get the following errors:
java: duplicate class: org.jbox2d.common.PlatformMathUtils
java: duplicate class: org.jbox2d.common.Timer
What am I doing wrong/have I missed?
Thanks
Looking at the POM for the jbox2d-library module, I see that there is a build section which explicitly ignores the classes under the gwtemul package:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/gwtemul/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
It seems to me that I should probably be building this library through MVN and attaching the built JAR as a dependency for the jbox2d-testbed module.
However, I found that modifying the package declaration for these classes also solves the problem:
package org.jbox2d.gwtemul.org.jbox2d.common;
/**
* A GWT-compatible implementation of the platform math utilities.
*/
class PlatformMathUtils {
public static final float fastPow(float a, float b) {
return (float) Math.pow(a, b);
}
}
And since they would have been ignored by the build anyway, I don't see that it causes any harm.
Once I did this, I was able to run the org.jbox2d.testbed.framework.TestbedMain class and I get the expected GUI:

Maven complains about #Override annotation first time but compiles successfully next time

I run command like this:
mvn tomcat:redeploy
as see a lot of errors like "...of type ImageDaoImpl must override a superclass method"
But after this I do nothing, just run this command again and this time it compiles ok!
Could anyone tell me how to fix that?
Every odd compilation time I get this error, it's quite annoying..
I can't immediately tell you why the issue goes away, but typically this compiler error indicates that you're attempting to compile Java 6-compliant code (which allows #Override on implementations of interfaces) with a compiler set to Java 5 compliance (which only allows #Override when overriding a concrete method from a super class).
I've just resolved my issue)
I have two plugins:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<source>1.5</source>
<complianceLevel>1.5</complianceLevel>
</configuration>
...
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
The first plugin was configured for 1.5 java the other was configured by ${jdk.version} which is 1.6
It's still a mystery for me why it compiles at all, but after setting 1.5 to 1.6 my issue has gone.

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