m2e cannot run nested instances of Eclipse - 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.

Related

Eclipse and Tycho - ${tycho-version}

Looking at Tycho tutorials and answers here at Stackoverflow a lot of then contain the variable ${tycho-version} example:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
What is nowhere described is who is responsible for resolving this variable. Is it done automatically by Eclipse/M2Eclipse plugin or does this variable means the developer is responsible for specifying the version?
If the developer is responsible where to get the list of versions?
This is a standard idiom for ensuring all Tycho plug-ins are from the same version: if plug-ins from multiple versions clash, it can result in very hard to debug issues. If this is the only place you enter a tycho version, this might seem unnecessary, but if you have to provide configuration for multiple elements, this will be responsible.
In other words, the build configuration should include a value for this property (or it should be set via the -D property syntax, e.g. mvn clean install -Dtycho-version=1.0.0).
In order to find out the possible versions, you could execute a search on maven central; where you can see the latest version as of today (3rd Apr, 2017) is 1.0.0.

wro4j & m2e Eclipse not compiling LESS

I am trying to setup my developer env so that I can use maven to compile my LESS files for formal builds, but also have Eclipse compile the LESS for incremental builds so I dont have to keep kicking of maven tasks every time I make a LESS change. Having looked around - it seems like wro4j & the maven plugin & the m2e-wtp plugin should provide all that.
My setup is as follows: I have just installed the latest stable Eclipse (Java EE package, that includes the WTP stuff - v4.3) and I have installed the m2e plugin and the m2e-wtp plugins.
pom.xml:
<plugin>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>1.4.5</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<targetGroups>roa-all</targetGroups>
<destinationFolder>${project.build.directory}/${project.build.finalName}</destinationFolder>
<cssDestinationFolder>${project.build.directory}/${project.build.finalName}/css/</cssDestinationFolder>
<jsDestinationFolder>${project.build.directory}/${project.build.finalName}/js/</jsDestinationFolder>
<wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
</configuration>
</plugin>
wro.properties:
preProcessors=cssImport,semicolonAppender
postProcessors=lessCss,cssMinJawr
wro.xml:
<groups xmlns="http://www.isdc.ro/wro">
<group name="roa-all">
<css>/less/*.less</css>
</group>
</groups>
Inside my /less/ folder are basically a few css files that I have renamed .less files, and one where I have actually added some LESS syntax with a few colour variables set. This mostly works, as I make changes to my LESS, the plugin detects and rebuilds my uber css file, however, rather critically, it doesn't seem to be compiling the LESS - it combines the files, and minifies, but my #variables are all still in LESS syntax.
I also noticed that the maven plugin was up to v 1.7.0 so tried upgrading to that to see if that was the problem, but that just does nothing at all (nothing gets built at all and I have no uber css etc)
Anyone had any experience setting this up or know anything I have missed in the setup?
The problem was because I had some invalid LESS in one of my files - this basically meant the compile step was failing, so the other LESS files were not being compiled to CSS (which resulted in the LESS variables being output in my file) - With the Eclipse incremental build, this failure was not being reported so I didn't see it.
I discovered it by explicitly running the maven command, and then got the normal maven logs which included details of the compilation failure.
That aside, the eclipse incremental build for LESS is working really nicely since!
As mentioned in the comments above, I wrote up how to set it all up here:
Eclipse & LESS - Better development time with incremental builds

Maven/Eclipse - Quick iteration acceptance Testing a project packaged as a WAR file

Eclipse makes working with multi module maven projects easy because you don't have to re-build and re-install a module before dependent modules will see changes to it. So you just change the code and eclipse updates the dependencies magically in the background.
I want to achieve this behaviour for acceptance testing as well.
I have
storage-service
storage-service-war
storage-service-acceptance-tests
If I use embedded jetty or tomcat to test inside the storage-service-war project then obviously code changes are immediately viewable in the tests, but I cannot see any way to achieve the same quick iteration of testing when testing from storage-service-acceptance-tests.
Every way I look at it it seems that I have to build storage-service-war and then use the artefact generated from that, but it seems like overkill when you only want to change one line.
Does anyone have a good method for doing this?
Cheers
Piers
So answering my own question :D The solution I came up with will not work on CI it will likely only work when doing a local build as it makes use of the relative paths of the projects. At the bottom I outline a more robust but more complex approach that should satisfy eclipse and CI.
I was looking at setting attachClasses to true for the war plugin configuration of the war project.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
You can then reference the jar in the dependent project as follows
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>storage-service-war</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
</dependency>
Then I was thinking I could run my tests from within the acceptance test module using embedded jetty or tomcat and pointing them to the web.xml defined in the war project using a relative path.
This works fine with maven via the commandline but fails in eclipse :(
The problem with this is that the jar produced by attach classes is not picked up by the eclipse m2e integration see -https://bugs.eclipse.org/bugs/show_bug.cgi?id=365419 unfortunately it wont be fixed.
So My solution for the moment is to manually add the storage-service-war project to my acceptance test project build path in eclipse. Its not great but it works
The above solution is a bit hacky but the alternative outlined is a bit more involved.
By splitting the project into the following I think it would be possible to have correct eclipse integration and projects that work on CI
storage-service
storage-service-core
storage-service-war
storage-service-acceptance-tests
storage-service-config
The core project contains the logic and source of the webapp and is of type jar, the config contains the web.xml and any other config files and is also of type jar. Then the acceptance-tests and war project are both of type war and serve merely to package the core project into a war and extract the config to the webapp/WEB-INF dir so that they may share a common setup.

m2e lifecycle mapping: delegating plugin execution

According to m2e wiki:
m2e matches plugin executions to actions using combination of plugin
groupId, artifactId, version range and goal. There are three basic
actions that m2e can be instructed to do with a plugin execution --
ignore, execute and delegate to a project configurator.
Further I can read that to ignore a plugin I need to do:
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<versionRange>[2.0.5,)</versionRange>
<goals>
<goal>process</goal>
</goals>
</pluginExecutionFilter>
<action>
<delegate />
</action>
</pluginExecution>
So it seems logical that to delegate execution I should do the same but with:
<action>
<delegate />
</action>
But it doesn't work. I'm getting following error:
No enum constant org.eclipse.m2e.core.lifecyclemapping.model.PluginExecutionAction.delegate
So what is the way to delegate plugin execution? Should I just omit pluginExecution element for plugins that I want to delegate?
Regarding to the M2E compatible maven plugins. There are only
1. <ignore/> mapping
2. <execute/> mapping
There is no mentioned tag for delegate.
If I understand correctly, It is a default configuration without any required configuration. It's just let the Eclipse M2E / M2E extension to decide. Please note, for me, I'm using the "m2e project configurators for Eclipse WTP" from JBoss for working with the web project. You may need to use some M2E extension which is matched with your requirement.
I always use the ignore for managing the customized resources and it work correctly.
Update:
At the Eclipse, please click menu Windows ---> preferences --> Maven ---> Discovery. Then click the "Open Catalog" button. The system will give you a list of extension (m2e connector) for installing. For example, there are the Android connector, antlr, AspectJ and so on. I hope that there may be an extension which will help you to achieve the requirement.

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