MIgrating from legacy gwt maven plugin to new generation plugin - java

I'm looking to see if we can migrate from the current legacy (mojo) GWT Maven plugin to the new generation (ltgt) Maven plugin. I've read documentation such as http://www.g-widgets.com/2016/12/02/gwt-tip-working-with-maven-multi-modules-projects/ which outlines how to setup the code as separate maven (POM) modules. Considering we already have the project setup where the application has multiple GWT modules all part of the same POM is there anyway we can work the plugin to compile the code successfully or does each module have to be separated into maven module of its own?

No need to change the structure of your project, though you would be missing out on the clean separation of client and server code via maven modules(not to mix up with the gwt modules).
So said that here is an example of how to use the new GWT maven plugin without having multiple maven modules:
Example Project structure with only one Maven Module: https://github.com/branflake2267/Archetypes/tree/master/archetypes/gwt-basic-rpc
And in case you have multiple GWT modules inside one maven module then you have to specify multiple executions. (not like in the old plugin):
Example Plugin config with multiple GWT modules:
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<executions>
<execution>
<id>compile-module1</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<moduleName>com.example.module1.Module1</moduleName>
<moduleShortName>module1</moduleShortName>
<compilerArgs>
<compilerArg>-localWorkers</compilerArg>
<compilerArg>4</compilerArg>
<compilerArg>-draftCompile</compilerArg>
</compilerArgs>
</configuration>
</execution>
<execution>
<id>compile-module1</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<moduleName>com.example.module2.Module2</moduleName>
<moduleShortName>module2</moduleShortName>
<compilerArgs>
<compilerArg>-draftCompile</compilerArg>
</compilerArgs>
</configuration>
</execution>
</executions>
</plugin>
Also there an little migration guide on the plugin website.
If ever you are interested in how the proper multi module setup would look like see here.

Related

Maven add spring boot project as dependency in another project. why it needs classifier "exec"?

I understand for adding spring boot project as dependency into another project it needs to be repackaged with classifier as "exec". Then it creates following two artifacts and i am able to import Test-project in another project.
Test-project-0.0.2.jar (normal jar)
Test-project-0.0.2-exec.jar (executable jar, put all classes under Boot-Inf)
But if i don't use classifier in spring repackaging goal and only configure "finalName" of artifact as "Test-project", then still it generates following artifacts but it gives compilation error while importing Test-project in another project:
Test-project-0.0.2.jar (same normal jar as above)
Test-project.jar (executable jar, put all classes under Boot-Inf)
Why maven is giving error in second scenario, when Test-project-0.0.2.jar exists and it's exactly same as jar generated in first scenario?
Here is the maven plug in configuration for second scenario:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<finalName>Test-project</finalName>
</configuration>
</execution>
</executions>
</plugin>

Converting Maven dependency to Gradle

I am currently following a tutorial here and saw a POM plugin that I couldn't convert to Gradle, you can find the plugin below. Tried to follow a couple tutorials though they didn't seem to help, the part I am confused about is the executions and what is the general syntax that Gradle expects.
<plugin>
<groupId>com.github.temyers</groupId>
<artifactId>cucumber-jvm-parallel-plugin</artifactId>
<version>5.0.0</version>
<executions>
<execution>
<id>generateRunners</id>
<phase>generate-test-sources</phase>
<goals>
<goal>generateRunners</goal>
</goals>
<configuration>
<!-- Mandatory -->
<!-- List of package names to scan for glue code. -->
<glue>
<package>com.example</package>
<package>com.example.other</package>
</glue>
</configuration>
</execution>
</executions>
</plugin>
As of version 4.x cucumber supports parallel execution. This makes the cucumber-jvm-parallel-plugin for maven obsolete.
You'll will have to create a task that uses gradles JavaExec to call cucumbers CLI directly with --parallel 4.
I don't believe you can use Cucumbers JUnit runner with Gradle to achieve parallel execution because Gradle doesn't install a parallel computer into JUnit but instead forks the the JVM.

How to generate separate jar files for application, source, and documentation (for central.sonatype.org)

Sonatype has a repository that I want to deploy a jar file to, and they ask for separate files for application, sources, and javadocs:
Example:
example-application-1.4.7.pom
example-application-1.4.7.jar
example-application-1.4.7-sources.jar
example-application-1.4.7-javadoc.jar
In Scala SBT, I have a command called "package" that generates the jar file for the project, but that only generates "example-application-1.4.7.jar".
Question: What should I do to generate the other two jar files?
In Maven, in order to get the additional -sources and -javadoc artifacts, add to your POM file the following:
<build>
<plugins>
<!-- additional plugin configurations, if any.. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note the snippet above:
We are invoking the Maven Source Plugin to create an additional jar files for sources
We are invoking the Maven Javadoc Plugin to create an additional jar files for javadoc
Executing
mvn clean package
You will find these two additional jars in the target folder.
The .pom file instead is generated during the install phase, but it is not placed under the target folder. Basically, it is a copy of your pom.xml file, with a different extension and used by Maven during the dependency mediation process to check which transitive dependencies are required by the concerned artifact.
Executing
mvn clean install
Maven will install the artifact in your local cache (in your machine), under path_to_cache/.m2/repository/your_groupId/your_artifactId/your_version/. In this folder, you will also find the .pom file, which normally you don't need to distribute (it is created automatically by Maven).
Further note: you probably don't want to generate these additional jar files at each and every build, so to speed up normal builds and have them only on demand, you could wrap the snippet above in a Maven profile.
You can achieve this by removing the snippet above from your build section and add a further section at the end of your pom:
<profiles>
<profile>
<id>prepare-distribution</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
So that normal builds would not create these jars anymore, but when executing the following:
mvn clean install -Pprepare-distribution
You would instead get them back. the -P option is actually activating on demand the profile defined with the id prepare-distribution.
With Maven 3 a default profile already comes as part of the super pom which perform exactly the same actions (sources and javadoc artifact), hence no need to add anything to your existing project. Simply run:
mvn clean install -Prelease-profile
Or, to activate it via a property
mvn clean install -DperformRelease=true
However, as also specified in the super pom, this profile may be removed in future releases (although there since first Maven 3 version till version 3.3.9 so far)
NOTE: The release profile will be removed from future versions of the super POM
The main reason behind this warning is most probably to push for the usage of the Maven Release Plugin, which indirectly makes use of this profile via the useReleaseProfile option of the release:perform goal.
As highlighted by comments, if you are not familiar with maven (especially via console) I would definitely recommend to
Go through the official Maven in 5 minutes documentation for a quick but worthy look.
Play with Maven from the command line, is there where Maven gives you its best. IDE integrations are great, but command line is the real turning point.
Then play with the POM customization above, to get familiar with some concepts and behaviors, first directly as part of your default build, then moved to a profile.
Then, and only then, move to the Maven Release Plugin usage. I recommend it as last step because you would already have acquired more confidence and understanding and see it as less magic and more reasonable approach.

Managing JAXB-generated classes in a Maven project

I have a Maven-based project, in which I trying to add some JAXB classes automatically generated by the "jaxb2-maven-plugin" Maven plugin. However, my first cut has me in a circular dependency loop:
Because these JAXB classes aren't generated yet, my other sources which reference them have compilation errors.
Because those other sources have compilation errors, these JAXB classes don't get generated.
It seems like there are two obvious possibilities for solving this:
Comment-out the broken references, so that the project builds and the JAXB classes are automatically generated. Then copy those generated sources from /target into /src/main/java, so that references to them won't cause compilation errors.
Create an entirely separate project, consisting of nothing but the JAXB stuff. Include it as a dependency in my main project.
Am I missing something here? Option #1 seems flat-out ridiculous... that just can't be the manner in which people use JAXB. Option #2 seems more rational, but still rather inefficient and cumbersome. I really have to take on the overhead of an entirely separate project just to use JAXB?
Are there any more elegant approaches that developers use to reference JAXB-generated classes in the same project where the Maven plugin generates them?
UPDATE: By request, here is the relevant portion of my POM:
<build>
<plugins>
<plugin>
<!-- configure the compiler to compile to Java 1.6 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- The name of your generated source package -->
<packageName>com.mypackage</packageName>
</configuration>
</plugin>
</plugins>
</build>
When I run mvn clean package, I DO see my JAXB sources being generated beneath the /target subdirectory. However, those generated sources are not being automatically added to the classpath for the compile phase.
POST-RESOLUTION UPDATE: It turns out that my compilation issues had more to do with the fact that I was running in Eclipse, and its Maven integration has some issues with "jaxb2-maven-plugin". See this StackOverflow question for more detail on that issue and its resolution.
How did you configure your jaxb maven plugin? Normally it runs in the generate-sources lifecycle, which comes before the compile lifecycle. So your JAXB generated classes should already be there when your own code gets compiled, Maven puts them in target/generated-source and puts that folder on the classpath.
Edit:
This is my code we use at work (and which works as expected):
<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/<companyname>/xsd</schemaDirectory>
<includeSchemas>
<includeSchema>retrieval.xsd</includeSchema>
<includeSchema>storage.xsd</includeSchema>
</includeSchemas>
</configuration>
</plugin>
Apparently we use yet another jaxb plugin... (see also this thread: Difference of Maven JAXB plugins).
i would suggest you to split jaxb-generated classes (api) and your BL classes (implementation) to 2 maven projects with separate pom.xml for each, and the main root pom.xml with the compilation order. that way, you will be able to build api.jar, then maven will install it inside the local repo, and after that you can use it as the dependency of your implementation. so it will looks like:
-API\
--pom.xml - for api, jaxb generation
-IMPL\
--pom.xml - for impl, api dependency is here
pom.xml - main pom.xml with references to the projects above
Maybe try using the maven-jaxb2-plugin instead:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.2</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
The answer from dfuse is correct, though. Either plugin should generate sources before compiling, and the result of the source generation will be on the classpath. I tested this with both plugins. Is it possible for you to post your schema, or at least the schema for the type that your code is failing to pick up on the classpath?

How to install Grails plugins through Maven pom.xml?

I'm building a Grails project with Maven, which is the required way of building at my company.
On my local machine, I have installed a Grails plugin in the usual way grails install-plugin foo. Of course, when the project is built by Maven on the build server, it knows nothing about this plugin.
I've seen that the following can be useful for the case where the plugin is available in the plugins directory of Grails:
<plugin>
<groupId>org.grails</groupId>
<artifactId>grails-maven-plugin</artifactId>
<version>1.1</version>
<extensions>true</extensions>
<executions>
<execution>
<id>create plugins folder</id>
<phase>validate</phase>
<goals>
<goal>install-plugin</goal>
</goals>
<configuration>
<pluginUrl>${env.GRAILS_HOME}/plugins/grails-hibernate-1.1.zip</pluginUrl>
</configuration>
</execution>
</executions>
</plugin>
but suppose the plugin was not on the machine at all? What would the pluginUrl be in the case where Maven or Grails will need to go to the internet to find the plugin?
Edit:
I've found that the pluginName and pluginVersion tags are useful, and I've added the following execution to the grails-maven-plugin:
<execution>
<id>Hibernate plugin</id>
<phase>validate</phase>
<goals>
<goal>install-plugin</goal>
</goals>
<configuration>
<pluginName>hibernate</pluginName>
<pluginVersion>1.3.7</pluginVersion>
</configuration>
</execution>
This almost works. If I check out my code in a new directory, and delete the contents of my plugins directories, Maven is able to build the project, successfully finding all plugin dependencies.
Yet it still doesn't work on the build server. Any ideas?
Try adding this dependency to your pom.xml
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>fields</artifactId>
<version>1.3</version>
<type>zip</type>
<scope>runtime</scope>
</dependency>
when you recompile your App maven will download and install the plugin
You need to use Grails Maven plugin, so the pom will get updated with changes to the plugin list. Have a look at Grails documentation describing Maven integration, especially the section on "mavenizing" the project.

Categories