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

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.

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!

OpenClover - Getting to work with AspectJ

I'm trying to use Openclover with a project that uses AspectJ and that instruments aspects into its code.
The pom.xml has these dependencies with relation to AspectJ:
...
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
And these plugins:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.openclover</groupId>
<artifactId>clover-aspectj-compiler</artifactId>
<version>1.0.0</version>
</plugin>
<plugin>
<groupId>org.openclover</groupId>
<artifactId>clover-maven-plugin</artifactId>
<version>4.2.0</version>
<executions>
<execution>
<id>clover</id>
<phase>verify</phase>
<goals>
<goal>instrument</goal>
<goal>clover</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
I'm using two plugins to do this: clover-maven-plugin which is a code coverage tool and clover-aspectj-compiler, a wrapper for AspectJ compiler which allows code instrumentation using OpenClover.
The errors I get are the following:
[ERROR] QueryAspect.java:48:0::0 The type QueryAspect is already defined
[ERROR] LogAspect.java:35:0::0 The type LogAspect is already defined
The documentation about this is just too little (or better, none) and I can't seem to make AspectJ work with OpenClover, and there isn't much help on the web.
Thank you
As discussed in our comments, you can just use AspectJ Maven instead of Clover AspectJ. You just need to take a few precautions in order to get it to work:
I like to put AspectJ Maven executions into the process-sources phase in order to make sure the AspectJ compiler kicks in before the normal Java compiler kicked off by Maven Compiler plugin. You could also deactivate Maven Compiler instead as Ajc is a full replacement for Javac. Actually that phase used to be the default in older plugin versions, but it has been changed long ago, which is also mentioned in an answer on SO. See also MASPECTJ-13 for why it was changed and MASPECTJ-92 for why the change was a bad idea.
There is a problem in Maven Compiler, namely the switch useIncrementalCompilation seems to have reversed logic. This is why you need to set it to false in order to make it work. Otherwise it tries to recompile stuff already compiled by AspectJ, breaking aspect weaving. See MCOMPILER-209 and MCOMPILER-194, I explained the problem and its solution there in my posts.
Now the only issue actually related to OpenClover (OC): AspectJ (AJ) does not know anything about OC adding source code to each method in order to enable code coverage. Unfortunately OC also does not know about AJ and also adds code to annotation-style pointcuts defined as empty methods with a #Pointcut annotation. As OC needs to do its magic before AJ compiles, the AJ compiler complains about unexpected code found in the pointcut and stops compilation with an error. There are at least two ways to avoid that:
You can either inline all pointcuts into the respective #Before, #After, #Around etc. advices using them, which usually works, but is not always an option in cases where you need argument binding in pointcuts in order to implement a wormhole pattern like execution(pointcutA()) && cflow(execution(pointcutB(myArgument))).
Or you can exclude all aspects from OC instrumentation, which is easiest if they reside in one package where there are no other Java classes which need to be instrumented. Then you can use a simple exclusion like in your case <exclude>codeaspects/**</exclude>. This is what I was doing in my pull request when fixing your project.
The easiest way is to just rename all aspects from *.java to *.aj, which is the canonical way of naming them anyway. I just tried in your project, and it works beautifully. AspectJ Maven looks for those files anyway, but OC will ignore them, not even calculating their lines of code for missing coverage. You can also get rid of the <exclude> mentioned above, see this commit.
Maybe all of this is automatically taken care of by Clover AspectJ, I never tried. Maybe the author of that compiler wrapper should actually explain what it does and how it works in the documentation, especially how to use it with Maven. Otherwise it does not make much sense to use it.

#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.

maven appears to be not compiling in order - symbol not found

I just converted a project from ant to maven and have am getting an error building a jar that behaves like the source files are not being compiled in the correct order. I have an enumerated type that looks like this:
public enum LmsError implements ILmsError {
UC0001() {
#Override
public String msg() {
return this.getClass().getName() + "-" + this + ": constructor failed: ";
}
},
The interface looks like this:
public interface ILmsError {
public abstract String msg();
}
... and this is an example of the code that uses it. The 'throws' line is the one the error message below is complaining about, but if I comment out the statement it just gets a similar error the next time the msg() method is referenced. It doesn't matter which element of the enum is being used.
} catch (Exception e) {
throw new RuntimeException(LmsError.UC0001.msg() + "Unable to construct status based on " + codeEnumeration + ":" + e.getMessage(), e);
}
mvn clean compile
[compiler:compile]
Compiling 129 source files to C:\bsaastad\workspaces\theportaltree\redirect\redirect-ejb\target\classes
-------------------------------------------------------------
COMPILATION ERROR :
-------------------------------------------------------------
com/theportaltree/redirect/status/RedirectStatus.java:[156,58] cannot find symbol
symbol : method msg()
location: class com.theportaltree.lms.LmsError
1 error
If I compile again without the clean, I get something similar to this (sometimes it takes two additional compiles to get through all the files):
[compiler:compile]
Compiling 89 source files to C:\bsaastad\workspaces\theportaltree\redirect\redirect-ejb\target\classes
[resources:testResources]
A clean compile.
If I look at the output directory after the failure I see that none of the generated enum classes are present, which explains the error. As soon as I get a successful compile, the enum classes are there as expected.
This is all in the same project, so I don't believe it is a dependency issue. I just converted this from an ant build to maven (maven newbie), where it has been compiling without issues for a couple of years. Here's the plugin section from the pom.xml. Is there something missing? Wrong version of something? I'm stumped:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<!-- put your configurations here -->
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<!-- javadoc configuration options here -->
</configuration>
</plugin>
</plugins>
</build>
Any help/ideas would be greatly appreciated.
Are you running an IDE at the same time as executing the command-line Maven build?
I've found that sometimes if your IDE is Maven-aware (e.g. Eclipse with the m2Eclipse plugin) you might get an undesired interaction between the two "racing" Maven engines.
If closing your IDE results in reliable clean builds, check its configuration options - it may be polling the filesystem for changes, which will in turn kick off a (clean?) build.
Try to run maven from the command line (the same mvn clean compile as you're running now).
BTW does the interface ILmsError, enum LmsError and the code that throws a runtime exception and uses the message reside in the same module?
Maybe its just lack of 'dependency' ?

enabling UTF-8 encoding for clojure source files

I'm working on a project which involves maven, java and clojure. The problem I'm facing is this, I have some UTF-8 chars in my clojure source files because of which my source code is not interpreted correctly by the java compiler, I kinda got it working by setting the environment variable JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8, but what I want is to pass this property through MAVEN.
I have already tried setting MAVEN_OPTS=-Dfile.encoding but this doesn't seem to work.
I have also tried setting configuration for the compiler plugin of maven... something like this:
<configuration>
<compilerArgument>-Dfile.encoding=UTF8</compilerArgument>
</configuration>
This doesn't work either.
I'm I doing something wrong, or is there another way.
thanks,
RD
Ok, Here's some more detail.
This is my parent pom,
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>UTF-8</encoding> <! also tried <encoding>UTF8</encoding>
</configuration>
</plugin>
Nothing interesting in the child's pom except...
<resources>
<resource>
<directory>src/main/clojure</directory>
</resource>
</resources>
;; clojure code snippet which causes problems
(let [char "대"]
(not (empty? (filter #(s/contains? % char) <some-list>)))
;; The list is always empty because I never find a match if I do not set the env. variable
Did you try passing compiler options? [-encoding UTF-8]
Update: Based on your comments, this is a runtime, not a compile issue. As a workaround, you could try escaping the character as unicode.
i.e. change the character to '\uXXXX' in the clojure file, where XXXX is the Unicode point in hexadecimal.
If your problem is happening in your unit tests. You can configure the surefire plugin by setting the argLine property. This allows you to set arbitrary JVM options on the command line.
Did you set the parameter through Compiler Plugin like this?
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgument>-Dfile.encoding=UTF8</compilerArgument>
</configuration>
</plugin>
</plugins>
Given the fact that Clojure actually hardcodes the expected encoding of input files to UTF8 (see src/jvm/clojure/lang/Compiler.java, loadFile-method), I'm surprised that using file.encoding does have any effect at all.
Try adding this property to your pom
UTF-8
For me, this code works without problem in cider REPL in Emacs.
;; returns sequence ("대")
(filter #(= % "대") ["대" "한" "민" "국"])
Can you provide code which emits error?

Categories

Resources