Maven configuration for two projects - maven-2

I am having a project A being built with mvn assembly:assembly which gives me a jar file with dependencies. This project basically gets a file path and converts it to XML.
Now I need to create a new project B which will wrap A by walking a directory and calling several times to A. NOTE: They must be different applications. I am not able to modify A changing it's parameters.
I would like that when B builds, it will first build A and gets it's jar file.
Which is the best way to configure this in a pom file? Should I have two poms?
Same pom but two jars being build?
Thanks for reading!

I would handle this by adding an aggregator POM with A and B as modules. Then you simply build the aggregator each time to have A built before B. This gives you the flexibility to build A and B individually as well as both together.
If you are determined to invoke A's build from within B, it could be done by using the maven-exec-plugin to invoke another Maven instance.
For example:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>mvn</executable>
<!--specified as a property below-->
<workingDirectory>${projectA.path}</workingDirectory>
<arguments>
<argument>clean</argument>
<argument>install</argument>
</arguments>
</configuration>
</plugin>
...
<properties>
<projectA.path>/path/to/project/a</projectA.path>
</properties>

Related

Best way to copy multi module project in maven

I have a maven project in which I would like to unpack all the child modules of a mutli module project. Does anyone know if the best way to approach this? There are over 100 modules in this project and I'm trying to avoid having to copy all this information somewhere else.
First you will need to create a pom.xml file that has all the projects as dependencies.
If there is one submodule that has
all other submodules as
dependencies, then you are in luck, just add a dependency to that submodule.
If not, you will have to write a script or program that gathers the groupIds, artifactIds, versions (and packagings) of all the submodules. And creates a pom.xml with all of them as dependencies.
Then, in this project, you can use dependency:unpack-dependencies to unpack the projects:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-projects</id>
<phase>generate-sources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>com.basegroupId*</includeGroupIds>
</configuration>
</execution>
</executions>
</plugin>
(Set includeGroupIds to a pattern that matches all submodule groupIds)
Now you just have to call
mvn generate-sources
(or any other phase you configure in the execution)

how to control the pom.xml inside jar built by maven?

When maven builds a jar it places a pom.xml at META-INF///pom.xml.
This is the original pom of the artifact.
No variables are expanded or inherited and no inherited dependencies are listed.
This makes the information of the production jar dependent on the build environment.
How can the pom inside the jar be configured ?
Best would be some configuration of the maven-jar-plugin.
I had a similar requirement, as I wanted to get all the information that belongs to the parent pom.xml. In others words, I wanted to have, in addition to the "raw" pom.xml, the effective pom inside the JAR generated.
The idea is to use the help:effective-pom plugin and goal during the generation of the JAR, and put it with the pom.xml. This is done with this configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>effective-pom</goal>
</goals>
<configuration>
<output>${project.build.outputDirectory}/META-INF/maven/${project.groupId}/${project.artifactId}/effective-pom.xml</output>
</configuration>
</execution>
</executions>
</plugin>
(source)

Maven cobertura plugin - one report for multimodule project

I'm using maven cobertura plugin to report code coverage in my multimodule project.
The problem is that I don't know how to generate one report for all modules in project.
So far I have generated separate reports for every module, but it would be nice to have one report for whole project.
My parent pom configuration:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.4</version>
<inherited>true</inherited>
<executions>
<execution>
<phase>test-compile</phase>
<goals>
<goal>clean</goal>
<goal>cobertura</goal>
</goals>
</execution>
</executions>
</plugin>
The plugin has been updated since this question was asked (and last answered) to now enable aggregated reporting, via the aggregate configuration property in the parent POM.
This produces the aggregated coverage report at target/site/cobertura/index.html which will include all modules.
(Each module will also have it's own report produced, if that is of any use.)
Parent pom.xml
<modules>
<module>moduleA</module>
<module>moduleB</module>
<module>moduleC</module>
<modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.6</version>
<configuration>
<check/>
<formats>
<format>html</format>
<format>xml</format>
</formats>
<aggregate>true</aggregate>
</configuration>
</plugin>
...
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
</plugin>
</plugins>
...
</build>
To my knowledge, this is currently not supported, see MCOBERTURA-65. But the issue has a patch attached, maybe try it. But my suggestion would be to use something like Sonar to aggregate metrics.
I have been using Hudson as a Continuous Integration tool.
The Cobertura plugin allows me to see code coverage of all of the child modules when checking on the parent.
The Jenkins Cobertura plugin aggregates the report automatically but if you are interested in the coverage file itself for some other reasons you can do by following below procedure:
Download Cobertura from here
Go to your project workspace -> find all the .ser files and rename them
(i=0; find . | grep cobertura.ser$ | while read line;do echo $line; cp -i $line cobertura$i.ser;i=$(($i+1));done;)
use cobertura-merge.sh to generate global .ser file
~/cobertura-2.0.3/cobertura-merge.sh --datafile cobertura.ser cobertura*.ser
use cobertura-report.sh to generate report on global .ser file
~/cobertura-2.0.3/cobertura-report.sh ./cobertura.ser --destination ./ --format xml
You will have the global coverage.xml generated in the current directory.
You can use it for any kind of processing further.

Copy dependencies maven war

When I try to use the plugin "maven-war-plugin", it copies all libraries to / WEB-INF/lib, how to copy to another directory? Example: "/ libtest"
I'm not sure to understand why you need to do this but I see two points here:
Avoiding dependencies to get copied into WEB-INF/lib (if not, then just skip the part related to 1.)
Getting them copied to another directory.
For 1. I'm assuming you need the dependencies (because you want to compile against them) but if you don't want the Maven War Plugin to copy them in WEB-INF/lib, you'll have to play with their scope, for example by declaring them as provided.
For 2. the Maven Dependency Plugin will be helpful here and I think you could use dependency:copy-dependencies, for example during the pre-package phase. Use it like this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>pre-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- configure the plugin here -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
And configure the outputDirectory (and other parameters you could need).
Use the maven-dependency-plugin.

Maven-2: avoid default packaging?

My project uses many assemblies, hence I'm interested only in the assemblies.
On executing mvn install apart from the assemblies, I'm getting the default packaged .jar.
How can I avoid this?
I have a pom.xml similar to the one you have provided.
On executing mvn install, I'm getting App1.jar, App2.jar, and snapshot jar containing all contents
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<id>assemblyone</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App1</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/report.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>assemblytwo</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App2</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/src.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I avoid this snapshot (not sure of the exact term) jar and ensure that only assemblies are created?
I can read your question two ways, I've outlined answers for both below. If neither is correct, can you modify your question with a bit more explanation please.
1) Do you mean you have a project with default (jar) packaging, and you want to avoid the creation of the jar when no assembly is defined? If this is the case, what is the build achieving if no assembly is defined?
2) Do you instead mean that you are running mvn assembly:assembly to generate the assembly and want to know how to get that assembly when running the install goal?
For option 2, you can bind the assembly-plugin to a lifecycle phase to ensure it is always run, if you specify that <appendAssemblyId> should be false, then the assembly will replace the default jar.
For example, this configuration will invoke the assembly plugin during the packaging phase and replace the default jar:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/archive.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
For option 1, this is actually quite tricky to do. The best I can think of is to specify that the project has pom packaging and configure the project with the executions normally bound to the jar lifecycle in a profile. The lifecycle bindings you'd need to configure are listed in the introduction to the build lifecycle
I'm not sure that you can really do that in a really simple way.
A solution is to call the clean plugin once the build is achieved, by doing that:
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<executions>
<execution>
<id>auto-clean</id>
<phase>package</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
This way, the JAR created in the target/ directory will be deleted at the end of the Maven2 execution.
However, you will have to define another directory to store the assemblies created by Maven2. Otherwise, it will be deleted by the call of the clean plugin... If you want to store them in the directory assemblies-target/, you can add that in the pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
...
<!-- Copy the ZIP in target/ of the ROOT directory. -->
<outputDirectory>assemblies-target</outputDirectory>
</configuration>
...
I think it would be much more clear if you showed us your whole POM and the artifacts that are being built. I can only guess as to what the problem is because your terminology is not what I am familiar with. This is my guess as to the problem: you have a POM configured to generated two assembly JARs, but you get a third JAR for the POM itself. In other words, if your POM's artifactId is MyApp, you are getting a MyApp-1.0.0.jar or similar in addition to the two JARs you actually want.
If that is the case, the problem boils down to that you are using Maven to create multiple artifacts from a single module. Maven is designed to produce only one primary artifact from each module. What I would do is change your POM to have a packaging type of "pom" and give it two modules in a <modules> section named App1 and App2. Create sub-directories under your module, one for each App. Give them each a POM configured for a single assembly, with a packaging type of "jar". Move the code/files/etc. as appropriate into each sub-module so there aren't any remaining in the parent module.
With Maven, if you find yourself generating two artifacts from one module (which you are), you should first consider that you are probably violating a Maven best-practice and rearrange things so you only produce one artifact per module.
Please let me know if this doesn't make sense and I will try to clarify.