Generated project with gwt-maven-plugin : eclipse - gwt-maven-plugin

I created a GWT project with
mvn archetype:generate -DarchetypeGroupId=org.codehaus.mojo -DarchetypeArtifactId=gwt-maven-plugin -DarchetypeVersion=2.5.0
Imported the project in eclipse juno.
First error I get is this :
Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:gwt-maven-
plugin:2.5.0:i18n (execution: default, phase: generate-sources)
In the pom file.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<goal>i18n</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see
gwt-maven-plugin documentation at codehaus.org -->
<configuration>
<runTarget>dashboard.html</runTarget>
<hostedWebapp>${webappDirectory}</hostedWebapp>
<i18nMessagesBundle>com.farheap.jsi.dashboard.client.Messages</i18nMessagesBundle>
</configuration>
Also the code contains a GreetingServiceAsync that can not be found.
private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);

You have two options:
You can add special (non-trivial) org.eclipse.m2e:lifecycle-mapping plugin
configuration to your POM. See here: Why am I receiving a "Plugin execution not covered by lifecycle configuration with GWT" error?
Or mark this issue as to be ignored in Eclipse POM editor, and then call mvn gwt:i18n. You can create a handy short cut launcher for it. Eclipse remembers your decisions what to ignore, it stores it into .settings directory permanently for the project.
In course of typical development localization messages do not change often so the second option is usually more convenient and speeds up build.
This applies for most GWT plugin goals! Even GWT compilation is rarely necessary as DevMode works directly with Java code and not generated JavaScrips. So in practice, you have to call all the goals at least once on the beginning and then live weeks without them; basic Eclipse JDT compilation is sufficient.
If you later decide not to use GWT localization framework in your real app then you can remove goal i18n completely from POM. Calling goal i18n generates file {project}/target/generated-sources/gwt/my/code/client/Messages.java which is required by (vanilla) Sample.java.
Also the code contains a GreetingServiceAsync that can not be found.
Run the build mvn install from command line or Eclipse Run as -> Maven install menu.
In case of command line mvn gwt:generateAsync should be enough. This goal generates {project}\target\generated-sources\gwt\my\code\client\GreetingServiceAsync.java and that is what you missing. Eclipse did not do it for you automatically because it was blocked by previous issue of i18n not being covered by lifecycle configuration. So yes, issues you mention are correlated.

Related

How to disable jar creation in commandline in a maven project?

I have a maven project for which I'm running two separate builds.
In one build I want to save the build time by disabling the jar creation of maven modules in it.(There are 45 maven modules). There is a Maven-Jar-Plugin that is being used to create the jars.
I want to conditionally disable the jar creation at the command line, that is, looking for something similar to -Dskiptests used to skip the unit tests though there is a surefire plugin by default.
The maven-jar-plugin does not provide any skip option.
However, several ways are possible to achieve your requirement.
You may just skip the phase which brings by default (via default mappings) the jar creation, that is, the package phase, and as such simply invoke
mvn clean test
The additional phases would not make sense if you do not create a jar file anyway: package, install, deploy would not have anything to process. Moreover, the additional integration phases may also be impacted depending on your strategy for integration tests, if any.
Alternatively, you can configure your pom as following:
<properties>
<jar.creation>package</jar.creation>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>default-jar</id>
<phase>${jar.creation}</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
As such, the default behavior would still provide a jar creation, while executing maven as following:
mvn clean install -Djar.creation=false
Would instead skip the creation of the jar.
What we are actually doing:
We are re-defining the default execution of the maven-jar-plugin
We are overriding its execution id, as such getting more control over it
We are placing its execution phase binding to a configurable (via property) phase
Default phase (property value) keeps on being package
At command line time you can still change it to any value different than a standard maven phase. That is, -Djar.creation=none would also work.

Maven + AspectJ/SpringAOP + Lombok + Surefire = test broken in a specific scenario

I have an interesting problem in a project where all of the technologies mentioned in the title are used. I've been able to track it down up to the diagnosis (the test classpath prepared by Surefire), but I don't understand whether it can be fixed and how. It's not a showstopper, indeed it's a minor issue for me, but I'd like to solve it anyway.
First a rough description.
The problem is related to executing tests in a specific module of the project, and only in a specific way.
Everything works (tests pass) when I run from the master pom level:
cd ${projHome}
mvn install
Everything works (tests pass) when I run:
cd ${projHome}/modules/CoreImplementation/
mvn test
That means that I can build and test with no problems, the same for my Jenkins, and NetBeans can run tests from the IDE when I need them.
But that module fails testing when I run from the master pom level:
cd ${projHome}
mvn test
with this error:
java.lang.NoSuchMethodError: it.tidalwave.northernwind.profiling.RequestProfilerAspect.aspectOf()Lit/tidalwave/northernwind/profiling/RequestProfilerAspect;
at it.tidalwave.northernwind.frontend.ui.spi.DefaultSiteViewController.processRequest(DefaultSiteViewController.java:82) ~[classes/:na]
at it.tidalwave.northernwind.frontend.ui.spi.DefaultSiteViewControllerTest.must_call_some_RequestProcessors_when_one_breaks(DefaultSiteViewControllerTest.java:161) ~[test-classes/:na]
Running mvn test as a second pass (after a mvn install -DskipTests) happens to be the way Drone.io and Travis do their job. While I could change their configuration, I'd like to stay with the standard configuration and fix the problem if possible.
The diagnosis in short and my question.
Now, the question in short (details are further below). I was able to track down the problem to different ways in which Surefire prepares the classpath to execute the tests.
When I run mvn install the classpath is:
${repo}/org/apache/maven/surefire/surefire-booter/2.16/surefire-booter-2.16.jar
${repo}/org/apache/maven/surefire/surefire-api/2.16/surefire-api-2.16.jar
${projHome}/modules/CoreImplementation/target/test-classes
${projHome}/modules/CoreImplementation/target/classes
${projHome}/modules/Core/target/it-tidalwave-northernwind-core-1.1-ALPHA-37-SNAPSHOT.952b0c8bdc77.jar
${repo}/it/tidalwave/thesefoolishthings/it-tidalwave-role/3.0-ALPHA-1/it-tidalwave-role-3.0-ALPHA-1.jar
${projHome}/modules/Profiling/target/it-tidalwave-northernwind-core-profiling-1.1-ALPHA-37-SNAPSHOT.952b0c8bdc77.jar
${repo}/org/apache/commons/commons-math3/3.0/commons-math3-3.0.jar
…
When I run mvn test (from the project home) the classpath is:
${repo}/org/apache/maven/surefire/surefire-booter/2.16/surefire-booter-2.16.jar
${repo}/org/apache/maven/surefire/surefire-api/2.16/surefire-api-2.16.jar
${projHome}/modules/CoreImplementation/target/test-classes
${projHome}/modules/CoreImplementation/target/classes
${projHome}/modules/Core/target/unwoven-classes
${repo}/it/tidalwave/thesefoolishthings/it-tidalwave-role/3.0-ALPHA-1/it-tidalwave-role-3.0-ALPHA-1.jar
${projHome}/modules/Profiling/target/unwoven-classes
${repo}/org/apache/commons/commons-math3/3.0/commons-math3-3.0.jar
…
The different portions are the indented ones. In the former case, SureFire uses the classes directory (forget for a moment that in my case they are named unwoven-classes) only for the module under test, and the installed jar files for every dependency. In the latter case, it seems to be using classes for all dependencies in the reactor.
The reason for which this difference in the classpaths gives me troubles is explained below in the "Gory details" section. In short, that unwoven means that they contain bytecode not augmented by AspectJ, hence the methods that can't be found at runtime.
I'm running with SureFire 2.16, but I've also tried the latest 2.19 with no changes. Being able to force SureFire to always use jar files for dependencies would fix my problems. If you have the answer, you can stop reading my post here.
Gory details (just for curiosity).
The faulty module artifactId is it-tidalwave-northernwind-core-default and it depends on aspects available in it-tidalwave-northernwind-core-profiling - that's where the offending RequestProfilerAspect is. The aspect library dependency is both in the regular dependencies of the faulty module and in the configuration of the aspectj plugin:
<dependency>
<groupId>it.tidalwave.northernwind</groupId>
<artifactId>it-tidalwave-northernwind-core-profiling</artifactId>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<aspectLibraries combine.children="append">
<dependency>
<groupId>it.tidalwave.northernwind</groupId>
<artifactId>it-tidalwave-northernwind-core-profiling</artifactId>
</dependency>
</aspectLibraries>
</configuration>
</plugin>
</plugins>
</build>
AspectJ integration is by means of the following profile in a Super POM, which is activated in the build, whose relevant part is:
<profile>
<id>it.tidalwave-aspectj-springaop-v1</id>
...
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<configuration>
<outputDirectory>target/unwoven-classes</outputDirectory>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<configuration>
<outputDirectory>target/unwoven-test-classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
...
The aspectj plugin is configured in the profile to statically weave binaries in the unwoven-test-classes directories. The reason for this approach is that it's the only feasible solution AFAIK to have both Lombok and AspectJ work together.
Now, back to the two classpaths described above: the fact that SureFire is using unwoven-classes means that it's pointing to bytecode that has not been augmented with AspectJ methods, hence the error.
References
The project is a FLOSS one and can be found at
https://bitbucket.org/tidalwave/northernwind-src
or
https://github.com/tidalwave-it/northernwind-src
A changeset where the problem can be reproduced is f98e9a89ac70138c1b6bd0d4570a22d59ed71be6. JDK 1.8.0 is required to build the project (even though it doesn't use Java 8 code yet).
The SuperPOM can be found here:
https://bitbucket.org/tidalwave/thesefoolishthings-superpom-src

GWT-Maven only compile gwt.rpc

I have a situation where I am debugging via -noserver and it forces me to recompile my gwt application everytime one of my RPC objects changes or I get a serialization error (This is well described in the GWT documentation and I understand why it is happening).
That being said, our project is getting quite big and the compile takes a while to complete, which is slowing down our development process. I have optimzed this as much as I can (Using -draftCompile, only doing a single permutation, and skipping all tests) but it's still pretty slow and I have a pretty beastly computer.
This led me to wonder if a better option here would be to get the compiler to only output the necessary files to make serialization work correctly.
Anyone know if this is possible?
Thanks!
You can do it using maven goals.
In Eclipse "run configurations" I have a specific configuration for that.
Goals: gwt:generateAsync gwt:i18n gwt:css
Profiles: dev-ff
The gwt:generateAsync goal is for generating your RPC. This is a standard goal with gwt-maven-plugin (assuming you are using it, of course).
Profiles: dev-ff ensures I'll only generate the code for Firefox.
Here is a part of the maven plugin config. Notice the goals definitions. You'll at least need the servicePattern attribute to tell the plugin where are your RPC interfaces.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwt-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test</goal>
<goal>i18n</goal>
<goal>css</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<!-- Plugin configuration. There are many available options, see gwt-maven-plugin
documentation at codehaus.org -->
<configuration>
<servicePattern>**/*RPC.java</servicePattern>
</configuration>
</plugin>
After doing this kind of operation, I often had to open my generated async files to get them in sync with Eclipse. Afterwards we found out we could just delete the gwt-unitCache/ folder in the target/ folder to force the application to use the new RPC classes.
More information about the plugin is available here.

Maven: Bind plugin execution to the execution of another plugin, not to a lifecycle phase

Note regarding the accepted answer: I accepted the answer because of strong circumstantial evidence. Nonetheless, this is circumstantial evidence, so take it with a grain of salt.
How can I have a plugin be triggered when the user runs a plugin goal, not a lifecycle phase? (This has been asked before, but the answer was to use a lifecycle phase.)
Case in point: I need release:branch to invoke regex-plugin to generate a branch with the current version as its name, minus the -SNAPSHOT suffix. This is what I have, which requires the developer to activate a profile and invoke the verify phase. I need the developer to simply invoke release:branch, which in turn should cause regex-plugin to run. In a bit of a marriage to Gitflow.
<profile>
<id>Release Branch</id>
<build>
<plugins>
<!-- On validate, compute the current version without -SNAPSHOT. -->
<!-- Put the result in a property. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<value>${project.version}</value>
<regex>^(.*)-SNAPSHOT$</regex>
<replacement>$1</replacement>
<name>project.unqualifiedVersion</name>
</configuration>
</execution>
</executions>
</plugin>
<!-- Also on validate, run the branch plugin, and use -->
<!-- the non-SNAPSHOT version thus computed in the branch name. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>branch</goal>
</goals>
<configuration>
<branchName>release/${project.unqualifiedVersion}</branchName>
<updateWorkingCopyVersions>true</updateWorkingCopyVersions>
<updateBranchVersions>false</updateBranchVersions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
The intent is for release:branch to move the current snapshot version (say, 1.0.5-SNAPSHOT) into a new branch, which should be named after the version but without the superfluous -SNAPSHOT suffix (1.0.5). The current branch should then take on a new snapshot version (1.1.0-SNAPSHOT, not 1.0.6-SNAPSHOT, because we want release 1.0.x to have room for hotfixes, so we reserve it for the branch) (I don't have the automatic computation of the next snapshot version figured out yet, so, if you run the Maven configuration above with validate, you will have to enter it at a prompt).
The evidence presented so far is rather circumstantial. I've done some research of my own, so it's best I share it here. The below are either more of the same "it's not possible", or the building blocks for alternatives.
jetspeed:mvn plugin --- run a specified sequence of plugins; the configuration to run can be varied via a system property; IDE integration concerns
Executing goals before plugin runs (StackOverflow) --- same question answered in the context of a custom Mojo
Make Mojo run other goals (StackOverflow) --- again, from the context of a custom Mojo
Configuring default Mojo executions --- Maven page describing how Mojos run - more circumstantial evidence
Triggering phases before goal execution (StackOverflow) --- roundabout solution to my problem, unfortunately answered in the negative
INTERESTING: Guide to Ant plugin development --- appealing to me, because, while it requires writing a custom plugin, it's all Ant + Maven configuration, no code to compile; presumably a lower barrier to entry
Creating a parallel lifecycle --- appealing approach, because I could fully control the contents of the lifecycle to where it would use Gitflow verbs; unclear how IDEs would integrate this; learning curve and adoption barrier concerns exist
No, you can't bind to a plugin to another plugin. Only to a phase.
In Maven-internal terms, a "Mojo" is the thing that does work. A "plugin" is a collection of mojos wrapped up so you can reference them from the POM. Mojos bind to phases only.
From the plugin development documentation:
Each Mojo specified inside a plugin descriptor must provide the following
...
phase ... Defines a default phase to bind a mojo execution to if the user does not explicitly set a phase in the POM. Note: This annotation will not automagically make a mojo run when the plugin declaration is added to the POM. It merely enables the user to omit the <phase> element from the surrounding <execution> element.
For further confirmation, see the source of MojoExecution (the JavaDoc for this class isn't helpful) and notice that there are two possible sources of execution enumerated:
An execution that originates from the direct invocation of a goal from the CLI
and
An execution that originates from a goal bound to a lifecycle phase
No other way to kick off an execution means you're out of luck (barring extraordinary measures like rolling your own plugin that combines the effects of the two plugins you want to link and then using your custom plugin).

Providng maven build output as a plugin dependency

I have a custom factory implementation I'd like to provide to wro4j maven plugin through a string parameter. Trouble is the factory is built in the same project as the plugin so the plugin doesn't get passed the output from the build and i get a nice ClassNotFoundException.
I'm aware that there is an annotation I could attach to the wro4j mojo to make it aware of the build output but that would require patching and building wro4j from source which doesn't sound smart. I'm also not keen on creating a whole different artifact just to contain my 5 line factory implementation. It feels like there should be an easier way, so the question is
Is there a way to pass build artifacts to a plugin in the same pom WITHOUT editing the mojo?
Have to guess what the issue is without an actual plugin configuration. But generally, if you need to add dependency (or class) to some of your plugins, you will have to wrap that class into its own artifact, i.e. move it into a separate project.
Fundamentally Maven does plugin dependency resolution before kicking in the rest of build cycle, so your classes may haven't been compiled yet at that point.
Try instructing the wro4j plugin to execute in the process-classes phase instead of the compile phase, when your factory class is compiled (process-classes happens right after compile):
<plugin>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>${wro4j.version}</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<wroManagerFactory>...</wroManagerFactory>
</configuration>
</plugin>

Resources