Run Maven goal for only one module in multi module project - java

I have a project which has 4 modules. That said, I have a parent project with a parent POM.xml specifying theses modules.
<modules>
<module>Module1-Desktop</module>
<module>Module2-Core</module>
<module>Module3-Web</module>
<module>Module4-EAR</module>
</modules>
The Module4-EAR has Module3-Web and Module2-Core as dependencies (not as modules) and generates an EAR to be deployed to JBoss.
I want to be able to build the Module4-EAR, but building Module3-Web and Module2-Core before it, so it is up-to-date and also deploy it to JBoss. So I'm running the following Maven command in the parent project:
mvn --projects Module2-Core,Module3-Web,Module4-EAR clean install jboss:hard-undeploy jboss:hard-deploy
In the parent POM I've set the jboss-maven-plugin like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jboss-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
In the Module4-EAR's pom.xml I've set the jboss-maven-plugin this way:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jboss-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
<jbossHome>${env.JBOSS_HOME}</jbossHome>
<serverName>default</serverName>
<unpack>true</unpack>
<fileNames>
<fileName>build/Module4-EAR.ear</fileName>
</fileNames>
</configuration>
</plugin>
The problem is that I want only the Module4-EAR.ear to be deployed with to the server, but the Module3-Web.war and Module2-Core are deployed as well. I want to do it in a single command, instead of running 2 mvn commands, one to "clean install" the projects and another to deploy only the EAR. How can I achieve that?

If you only want to deploy the ear then add the jboss-maven-plugin into the pom of Module4-EAR. So the plugin will only work within that module. Adding deployment plugins into a parent pom often leads to executing it into all modules - which is often not what you want.
You can chain the commands so a mvn clean install plugin:goal
The plugin you use seems to be superceded by JBoss AS7 Deployment Plugin: http://docs.jboss.org/jbossas/7/plugins/maven/latest/ (as a side note)
So it would look like mvn clean install jboss-as:deploy
You can also add an execution to the jboss plugin and bind it to the deploy phase so a mvn clean deploy would copy the artifact into a remote repository and deploy the ear into jboss.
An example using the install phase is at: http://docs.jboss.org/jbossas/7/plugins/maven/latest/examples/deployment-example.html

Just had to add this to the only project that I want to execute the jboss:hard-deploy.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jboss-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
<jbossHome>${env.JBOSS_HOME}</jbossHome>
<serverName>default</serverName>
<unpack>true</unpack>
<fileNames>
<fileName>build/cadprev-web-ear-1.0.0.ear</fileName>
</fileNames>
</configuration>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>hard-deploy</goal>
</goals>
</execution>
</executions>
</plugin>
Removed the code below from the parent POM.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jboss-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
And changed the mvn command to:
mvn --projects Module2-Core,Module3-Web,Module4-EAR clean install

Related

How do I deploy files to Artifactory in Maven?

My current pom is configured to deploy a jar to my artifactory.
In addition, there is a bash script that runs the jar and I keep it in my project as well.
I would like to deploy this script as well (separately from the jar) to my artifactory under the same version.
is it possible? and if so what should I add to the pom in order to do this?
You can use deploy:deploy-file goal from Apache Maven Deploy Plugin
<plugins>
<!-- other plugins ...-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
<executions>
<execution>
<goals>
<goal>deploy-file</goal>
</goals>
<phase>deploy</phase> <!-- change this if you need another phase -->
<configuration>
<groupId>${project.groupId}-script</groupId><!-- whatever you want -->
<artifactId>${project.groupId}</artifactId><!-- same groupId as the project, you can choose another one-->
<version>${project.version}</version><!-- same version as the project, but you can choose another one -->
<file><!-- path to your script --></file>
<pomFile> <!-- path to the pom file of the script --></pomFile>
<generatePom><!-- but maybe you don't want a pom file for the script, so set this to false--></generatePom>
<repositoryId><!-- the one configured in your settings.xml and distributionManagement --></repositoryId>
<url><!-- the one configured in your settings.xml and distributionManagement --></url>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

How-to integrate a gradle module into a maven project?

We have maven parent project with 2 maven modules. Now we need a new maven module, but the building process depends on a gradle build. The problem is, that the new module is a plugin for third-party software and they only provide a gradle plugin for a proper build. Also we need the other modules as dependcies, which isn't a big deal, but we want to have it in the same code repository. My question is now, is it possible to integrate gradle in a maven project. Maybe with the maven plugin, which generates the pom, so that it looks like a maven-module, but we can also use the gradle plugin, if we need so.
We use maven v3 and it's a java project if these informations are relevant.
You can try to use the Maven "exec-maven-plugin".
With this plugin you can run cmd Commands.
So add the plugin and let it execute your Gradle build
<project>
...
<build>
<plugins>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.2.1</version>
<executions>
<execution>
<id>Gradle Executor</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>Your Gradle Executable</executable>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
This should work, give it a try.

Maven: Why does adding test source via build helper not work when generating eclipse project?

Our maven pom.xml specifies to add an additional source and test-source folder if a certain profile (here "java8") is activated. The corresponding part of the pom looks like the following
<profile>
<id>java8</id>
....
<build>
<plugins>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals><goal>add-test-source</goal></goals>
<configuration>
<sources>
<source>src/test/java8</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
According to http://mojo.codehaus.org/build-helper-maven-plugin/usage.html this appears to be the correct specification.
Running mvm install -P java8 I see that the additional tests are performed as expected.
However, running mvm eclipse:eclipse -P java8 the additional test source folder does not appear in eclipse .classpath.
Question: How do I have to configure maven to add the test source folder to the eclipse configuration? Is the above behavior a bug or a misconfiguration?
Having spent some time experimenting with this, I can give a partial answer to my own question (hopefully saving some time of other developers):
If one uses
<phase>generate-sources</phase>
<goals><goal>add-test-source</goal></goals>
instead of
<phase>generate-test-sources</phase>
<goals><goal>add-test-source</goal></goals>
then the test source folder is added to the eclipse .classpath (and it is added as a test folder). I.e. I am executing "add-test-source" in a different phase now.
In other words the profile looks like this:
<profile>
<id>java8</id>
....
<build>
<plugins>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-sources</phase>
<goals><goal>add-test-source</goal></goals>
<configuration>
<sources>
<source>src/test/java8</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
This looks like a "workaround". It still contradicts the specification on http://mojo.codehaus.org/build-helper-maven-plugin/usage.html
rather than using eclipse:eclipse, you can use the http://www.eclipse.org/m2e/ plugin to open maven pom.xml projects.
Once you install that plugin in maven you will be able to take advantage of the m2e maven plugin, which can map any maven phase into the eclipse build life cycle.
in our example you will need to add something like this to your pom.xml:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>add-test-source</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Important
this will only work if you install the m2e plugin and use it to open maven projects.
The way I see it, the plugin is working as expected.
When you run mvn install -P java8, you are invoking the phase install. In effect, maven executes all the phase prior to install, including generate-test-sources phase and test phase... before it really executes install. Because your plugin's goal is bound to generate-test-sources phase, that's why in this case you see your tests added in the class-path and run.
When you run mvn eclipse:eclipse -P java8, however, you are invoking a plugin's goal (in particular, eclipse goal of eclipse plugin), not a build life-cycle (phase). According to the eclipse plugin's documentation, only the generate-resources phase will be invoked. Be noted that generate-resources doesn't not "include" generate-test-sources (see more here), so in this case, your build-helper plugin does not get called.
If I guess correctly, you're trying to run your test in Eclipse with the profile java8 enabled. In that case, one way to do it (without having to work around) is right click on your project, click Maven, in the Active Maven Profile input box type in java8 ->OK. Now right click in your project and choose Run As -> JUnit Test (or whatever test framework you're using). Make sure you use the latest Eclipse version (Kepler 4.3.1 as of now) as it has a built-in m2e plugin which has improved a lot from the original m2e.
I'm experiencing the same issue as you Christian Fries and I came to the same conclusion as you about binding the add-test-source goal to the generate-sources phase instead of the generate-test-sources phase.
The problem is that when we run mvn eclipse:eclipse, we are actually directly calling a plugin so only that plugin will run. The reason the generate-sources phase is executed is explained in the plugin's doco (http://maven.apache.org/plugins/maven-eclipse-plugin/eclipse-mojo.html):
Invokes the execution of the lifecycle phase generate-resources prior to executing itself.
What we want is to be able to tell the plugin to execute the generate-test-sources phase before itself and then run. Note that maven will run all the phases up to and including the one you specify (http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) so we don't need to say run generate-sources AND generate-test-sources because simply specifying the latter is enough. Anyway, we can test this situation by running (the order matters):
mvn generate-test-sources eclipse:eclipse
...and for me, this did exactly as we expected. You can see from the output that the build-helper-maven-plugin is run to add the test sources and THEN the maven-eclipse-plugin runs and picks it up.
Now we have a new problem because AFAIK you can only bind a plugin to a phase (so it runs when the phase is run) and not the other way around.
The (sort of) solution is to bind the build-helper-maven-plugin and the maven-eclipse-plugin (in that order, so define the plugins in your POM in that order) to the generate-test-sources phase and then instead of running mvn eclipse:eclipse, run:
mvn generate-test-sources
So we have a POM that looks like:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<directory>src/test/java8</directory>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<phase>generate-test-sources</phase>
<goals>
<goal>eclipse</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I know it's not perfect because people will still run mvn eclipse:eclipse and cry when it doesn't work. Also, the maven-eclipse-plugin will run as part of anything that runs the generate-test-sources phase (i.e. mvn clean install) which isn't so bad if it doesn't steamroll custom settings people have but if it is a problem you could move this stuff into a profile, bind it to a different phase that doesn't run as part of a build (like clean) or create a new lifecycle phase.

How to deploy the sources file with the jar using deploy:deploy-file

I have the following plugins for creating a -sources.jar and deploying a specific named jar to a repository.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.5</version>
<configuration>
<version>${project.version}-r${buildNumber}</version>
<classifier>${env}</classifier>
<packaging>jar</packaging>
<file>${project.build.directory}/${project.build.finalName}.jar</file>
<url>${artifactory.url}/libs-release-local</url>
<repositoryId>artifactory.digiterre.com</repositoryId>
<pomFile>${project.basedir}/pom.xml</pomFile>
</configuration>
</plugin>
I wish to deploy the *-sources.jar at the same time. I have tried adding a second file entry and even a second deploy plugin. I seem to get one or other file deployed.
Is it possible to deploy both in one pass using deploy:deploy-file or will I have to set up a second team city build just to deploy the sources?
When you use maven-source-plugin, the generated jar will automatically attach to project artifact (default setting for this parameter is 'true') and if you execute deploy it will be deployed along with it. Alas, no need for separate configuration of deploy plugin.
Unfortunately, you cannot add classifier (${env} in your case) to sources jar. That is why I'd use the following configuration:
...
<artifactId>com.pie.mash.repo.mince-${env}</artifactId>
<version>1.18-r${buildNumber}</version>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Also, I've found this question on SO. You can use the workaround suggested there.
We can use deploy:deploy-file to upload multiple JARs (sources, tests, docs) along side main JAR artifact. We just need to supply that additional piece of information to deploy:deploy-file plugin call. The additions are indicated in bold in below command:
mvn deploy:deploy-file
-Dfile=helloWorld.jar
-Durl=https://localhost/nexus/content/repositories/snapshots/
-DrepositoryId=snapshot
-Dfiles=helloWorld-6.4.1.3.SNAPSHOT-sources.jar,helloWorld-6.4.1.3.SNAPSHOT-tests.jar
-Dtypes=jar,jar -Dclassifiers=sources,tests
-DgroupId=com
-DartifactId=helloWorld
-Dversion=6.4.1.3.SNAPSHOT
-Dpackaging=jar
-Dpomfile=pom.xml
We need to specify list of files separated by commas.
We need to specify the types of those additional files.
We need to add classifier information for those additional files.
mvn deploy:deploy-file only deploys a single artifact. Instead you can use mvn deploy (which invokes mvn deploy:deploy) to deploy the artifact, its pom along with the attached artifacts (like source and javadoc). Refer to the goals overview of maven deploy plugin.

Force Maven clean

I have a project with 2 profiles, because UAT and PROD use different versions of the same jar.
I have noticed that if i don't explicitly call mvn clean ... the deployed EAR will have BOTH UAT and PROD jars.
Is there a way in the POM to specify that Maven should always clean before any building?
Use the maven-clean-plugin with the initialize phase as given here
http://maven.apache.org/plugins/maven-clean-plugin/usage.html
<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>initialize</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
Sure. Visit the Maven clean plugin usage page, they provide an example how to run the plugin automatically during build.
Please read up on the maven lifecycle
especially the package lifecycle.
The maven clean plugin you use will probably allow you to define a clean goal at a particular pahse.
You can also execute for example mvn clean install -P profile

Categories

Resources