Eclipse builder incompatible with m2Eclipse and Maven - eclipse

I'm seeing an issue where a given source file built by Maven produces a class file that is different than the one built by Eclipse.
The Eclipse builder is optimising away the following method:
public SomeClass clone() {
SomeClass clone = (SomeClass) super.clone();
return clone;
}
This method is obviously unnecessary but I don't have the option to change the source because it is generated.
Which builder is Eclipse using to compile these classes? I'm using the m2Eclipse plugin which I thought just invoked Maven to perform the build. Why is it that Eclipse then thinks it needs to perform another build with a different builder? Can I disable this Eclipse builder or configure it to prevent optimisation?
Eclipse version: 3.7
m2Eclipse version: 1.0.100.20110804-1717 (configured to use external Maven)
Maven version: 2.2.1
Update
I found an Eclipse bug report that describes what is going on. To clarify, its not actually the Eclipse compiler that is removing anything, it is just not introducing a synthetic 'bridge' method that the standard JDK compiler introduces. The bug report is marked as Resolved- Won't Fix.
I still haven't found a way to prevent the Eclipse builder from running after the Maven builder has run. But our fix is to modify the code generator to add an explicit serialVersionUID to the generated code.

You could try disabling Java Builder if configured for the project. You can check this by clicking on Builders tab in Project -> Properties.
From Eclipse help...
The Java builder builds Java programs using its own compiler (the
Eclipse Compiler for Java) that implements the Java Language
Specification.

I don't have Eclipse 3.7, but I expect that these things haven't changed since 3.6 . If you open Properties -> Builder on your project you should see that the Maven Builder comes last, or at least after the Java Builder. This means that when the Maven Builder sees your Java source files they are already compiled. By the way, the external Maven you configured is only used when you perform Run as -> and not when building with Maven.
All this is to say that what you see is likely do to the fact that when you compile from within Eclipse the internal Java compiler is used, while when you run Maven from the command line I expect that a JDK compiler is used, depending on what you have installed. I don't think there's anything you can do to change this state of things. One thing you could try is to ensure that their behaviour is as close as possible by specifying in your POM which Java version to be compliant to by adding something like
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
To your build section.
I have to say that I expected that the Java compiler was not allowed to remove public methods from classes, even if they are useless.

Related

m2e cannot run nested instances of Eclipse

I'm using the Tycho eclipserun plugin to generate Java source code for an EMF model during build (as opposed to having the sources checked in). Configuring the plugin to run as part of the maven build works fine, but I would also like to configure m2e so that the same goal is executed when building from inside Eclipse. So, I imagined that could get away with just specifying <execute/> instead of <ignore/> in the lifecycle mapping metadata, like so:
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-eclipserun-plugin</artifactId>
<versionRange>[0.21.0,)</versionRange>
<goals>
<goal>eclipse-run</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
But then m2e complains saying
Execution default of goal
org.eclipse.tycho.extras:tycho-eclipserun-plugin:0.21.0:eclipse-run
failed: java.lang.IllegalStateException: Cannot run multiple Equinox
instances in one build. Consider configuring the Tycho build
extension, so that all mojos using Tycho functionality share the same
Equinox runtime.
(org.eclipse.tycho.extras:tycho-eclipserun-plugin:0.21.0:eclipse-run:default:generate-sources)
Ok, so m2e cannot run a nested Equinox instance in the same build, which kind of make sense.
Is there a solution for this? One solution I could imagine would be to execute a standalone Eclipse, but I really like the way the eclipserun plugin allows be to do that just by specifying a remote p2 repo and a bunch of features to include, instead of having to set up a standalone Eclipse more or less manually.
If you are already running in Eclipse, you could execute your EMF generation steps in that runtime directly. So you'd need to configure a builder which does the same steps as the tycho-eclipserun-plugin.
In general, for the case where some build step needs to be executed in Eclipse, but in a different way than in Maven, m2e has the concept of configurators: A configurator could tell m2e what to do when it encounters a certain build plug-in. So in case of the tycho-eclipserun-plugin, the configurator could let the goal run in a forked process instead of in-process. However, I'm not aware of such a m2e configurator, and it remains to decide whether it is really a good idea to fork processes as part of the incremental Eclipse build.

Eclipse JDT and Maven/Tycho do not agree on warnings

This is related to How to avoid Eclipse importing a class when putting the class name in the comments, so that checkstyle does not complain later?, but is a different issue.
I have a bunch of Javadoc references with import statements, as describe in the referenced question. Eclipse does not warn about this, but I still get compiler warnings when building my code with Maven/Tycho. I thought that specifying <compilerId>jdt</compilerId> should make Maven use the same compiler as Eclipse does, and there by generate identical sets of warnings.
I understand that I can use the fully qualified name in the Javadoc tag to avoid the import statement, but what I wonder here is how do I get the same set of compiler warnings when building with Maven/Tycho as when I build in Eclipse?
Tycho uses the JDT compiler by default, so you don't need to set the <compilerId>. However the compiler settings defaults may be different in Tycho and in Eclipse, or you may have changed the default settings in your workspace. You could try to configure the compiler in Tycho via the <compilerArgs> parameter to match your workspace settings, but this may get quite tricky.
With Tycho 0.22.0 (cf. bug 404633) there is much easier way to get the exact same compiler settings in Eclipse and in Tycho:
Enable project-specific Java compiler settings in Eclipse and configure them in the way you want them. This creates a file .settings/org.eclipse.jdt.core.prefs in the project.
Add the following Maven configuration:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<useProjectSettings>true</useProjectSettings>
</configuration>
</plugin>
This makes the JDT compiler in Tycho use the Eclipse project settings whenever they are present.
Note that you need to put the .settings/org.eclipse.jdt.core.prefs files under version control to make your build reproducible.

What's the "right" way to (temporarily) exclude sources from a maven build, and is there an easy way to do it from Eclipse?

I'm new to maven, and I don't have a whole lot of experience with Eclipse either.
To exclude java files from building in Eclipse, I right click the files and choose Build Path -> Exclude. This works great for the "on-save" compilation in Eclipse, but it does not propagate to the maven project, so when I build my project with mvn install, it tries to compile the excluded sources.
I've done a few searches and the results point me to the compiler plugin and the <excludes> functionality, but editing maven project files in order to temporarily exclude a file from the build seems a bit awkward.
What's the "right" way to (temporarily) exclude sources from a maven build, and is there an easy way to do it from Eclipse, via the m2eclipse plugin or otherwise?
You could use the <excludes> parameter in Maven Compiler plugin to temporarily exclude files from compilation.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<excludes>
<exclude>**/model/*.java</exclude>
</excludes>
</configuration>
</plugin>
If you are using M2Eclipse plugin and run Maven->Update Project Configuration, the excluded files in the pom should automagically get excluded from eclipse compilation as well.
if you choose maven as project management, then you really have to do it the "maven way".
Eclipse builds the project based on the classpath specified in project properties and it doesn't relate to classpath of maven compiler plugin. "mvn compile" is driven only by configuration of compiler plugin.
Usually these "temporary" changes are dealt with by JVM parameters appended to the maven goal (maven plugin/Mojo goal that you are running from cmd), that you create (custom one) and save in "Run as" > "Run configurations". I use commandline (shell) rather than m2eclipse for maven. changing parameters is quicker for me.
To find out what parameters you can use, you can either specify the particular Mojo (maven plugin) in you maven dependencies (just temporarily) and look at its sources right in eclipse, you can see parameters that can be specified via "-D" JVM parameters. Or you can check the documentation.
In compiler plugin there is a parameter private Set<String> excludes = new HashSet<String>(); but unfortunately collection parameters cannot be specified as JVM parameters... So the only option left is configure the plugin declaration in pom.xml.
Then there are also profiles, but they are not useful for this case.
To summarize it, your requirement is rather rare, excluding a java class from compilation is not a usual requirement.
I hope it helps

I have build errors with m2eclipse but not with maven2 on the command line - is my m2eclipse misconfigured?

I installed m2eclipse to build a java project in Eclipse.
I imported the project as follows:
Import->
Maven->
Existing Maven Projects->
Import Maven Projects->
- Select root directory
- Select pom file
- Click Finish
To be sure m2eclipse was actually building the project, I deleted the target directory and made sure it was re-created by m2eclipse and it was. But unlike with the command-line version of maven which built everything perfectly, m2eclipse leaves a large number of build errors in the source code.
Is it possible that I did not configure m2eclipse properly? How would I check this?
This is a github link to the project I'm trying to build. I'm getting the #Override build errors at this line. It says "The method createNewToken must override a superclass method".
Update: The problem is the same as the one described in ‘Must Override a Superclass Method’ Errors after importing a project into Eclipse and here is what the accepted answer says:
Eclipse is defaulting to Java 1.5 and you have classes implementing interface methods (which in Java 1.6 can be annotated with #Override, but in Java 1.5 can only be applied to methods overriding a superclass method).
Changing the compiler level to Java 1.6 would make the problem go away. To do so, modify the compiler plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
And update the project configuration (right-click on the project then Maven V Update Project Configuration) does solve the problem under Eclipse.
Or stick with 1.5 but remove the problematic #Override annotations.
I don't know how Taylor got things working with a Java 1.5 compiler level. And my guess is that the project wouldn't build on the command line with a JDK 5.
But unlike with the command-line version of maven which built everything perfectly, m2eclipse leaves a large number of build errors in the source code.
Hard to say what is happening exactly without seeing those "errors" (are them really errors?). Please provide some traces.
Is it possible that I did not configure m2eclipse properly? How would I check this?
One difference is that m2eclipse uses by default a embedded version of Maven 3 which is probably not the same version that you use on the command line. You can change that through Window V Preferences V Maven V Installation (and add your own installation):
But while I would recommend to use the same version under Eclipse than on the command line, this is very likely not the root cause of the problem, Maven 2 builds should run on Maven 3 without problems.
I checked out the code. I have exactly the same problem. The code seems to be just broken.
Edit: It definitely is. Look at the class com.jappstart.service.auth.UserDetailsServiceImpl. It wants to override the method public final UserDetails loadUserByUsername(final String username) but this method doesn't exist in the interface the class implements and is has no superclass.
Edit: Ok, that doesn't explain why it builds with maven standalone. This also works for me. Very strange. It seems that there is something going on with the build that doesn't work with m2eclipse.
Edit: I'm pretty sure the code works because the bytecode is modified by the datanucleus plugin. When I run the project as maven build (right-click->Run->maven package) it sucessfully creates the war with m2eclipse. So my guess is that the problem is with the m2eclipse Maven Builder.
The override errors will appear if eclipse is configured to use java 1.5 instead of 1.6. Check the project properties.

maven - use generics in a eclipse's maven project

I have a maven website project generated by archtype plugin with eclipse IDE. The problem is when i need to use generics or any thing of java 5 or 6, i changed the project compiler to 1.6 and i got a error mark on the project icon in the package explorer but everything is fine. I think it is cause by maven but I dont know how to get rid of it.
Thank you
Don't forget to configure the maven-compiler-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- Lock down plugin version for build reproducibility -->
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
I second with what Mike has said.
Even after changing the entries in pom, i was still getting the compiler error.
and it worked onlt after deleting the project and importing it again in the workspace
You need to make sure Eclipse is compiling with the Java 1.6.
Go to your project-specific settings: Project > Properties. Type "Java Compiler" in the text box to the left.
Ensure that all those drop-downs under "JDK Compliance" are set to 1.6. Otherwise check the box to 'Enable project-specific settings' and manually set them to JDK 1.6.
You may also want to enforce this through Windows > Properties, Java > Compiler, Compiler compliance level > 1.6, for global default settings.
Also make sure that the version of the JDK on your build path is the one you want. Hope this helps.
This is kludgy, but I've run into similar issues and worked around them by deleting the project (and not the sources obviously). Then I would import the maven project into my workspace.
m2eclipse ends up resolving the project again and sets up the project correctly.