Best way to copy multi module project in maven - maven-2

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)

Related

How to publish features and bundles to existing p2 repository with category?

I could install features and bundles to locally existing repository:
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-p2-extras-plugin</artifactId>
<version>${tycho.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>publish-features-and-bundles</goal>
</goals>
<configuration>
<append>true</append>
<sourceLocation>${project.build.directory}/repository</sourceLocation>
<metadataRepositoryLocation>existingRepo</metadataRepositoryLocation>
<artifactRepositoryLocation>existingRepo</artifactRepositoryLocation>
</configuration>
</execution>
</executions>
</plugin>
It worked well.
However, installed features are not categorized in destination repository.
How can I fix it?
You need to set up a Tycho build which
References you published repository as layout=p2 repository in the POM, and
Includes a module with packaging eclipse-repository and a category.xml file with your categories.
For this build, you can put all configuration into one pom.xml; you don't even need to set up a parent POM. However this build needs to be triggered separately from the build that calls the publish-features-and-bundles goal.

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)

How to wrap an Ant build with Maven?

We use maven for our large-ish product. All of our artifacts are deployed to a shared archiva repository using the maven deploy goal. I am now integrating a third party product that has an ant build. I know how to call ant targets from maven using the antrun plugin, but I'm not sure how to setup the pom in this instance. I don't want maven to actually generate an artifact, but I do want it to pull the artifact that was built by ant when the maven deploy goal is run.
I am planning on having the pom adjacent to build.xml. The pom will use the antrun plugin in the package goal to call the ant target at the appropriate time to build the .war artifact.
Questions:
a) I am creating a .war file but it is created via ant, not Maven, so having a war packaging type in the pom doesn't make sense. What should my packaging type be?
b) How do I cause maven to pull the artifact from my ant output directory for the deploy goal?
c) If there are no good answers to A and B, then are there ant tasks that replicate the maven deploy functionality for getting my .war artifact into the shared repository?
You can use the maven-antrun-plugin to invoke the ant build. Then use the build-helper-maven-plugin to attach the jar produced by ant to the project. The attached artifact will be installed/deployed alongside the pom.
If you specify your project with packaging pom, Maven will not conflict with the ant build.
In the example below, the ant build.xml is assumed to be in src/main/ant, have a compile goal, and output to ant-output.jar.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<ant antfile="src/main/ant/build.xml" target="compile"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>add-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/ant-output.jar</file>
<type>jar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
You can actually wrap an ANT project with Maven by using multiple ant run goals as I wrote in a different question. Assuming your existing ant project has clean and build tasks, this might be a useful way of wrapping the project so you can use maven goals and have it map to existing ant code.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>install-library</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>x.x</groupId>
<artifactId>ant-out-atifacts</artifactId>
<version>${project.version}</version>
<file>ant-output.jar</file>
<packaging>zip</packaging>
</configuration>
</execution>
</executions>
</plugin>
Refer this: Why you should use the Maven Ant Tasks instead of Maven or Ivy
And specifically, how to invoke a Maven goal from Ant can be found in this example:
http://code.google.com/p/perfbench/source/browse/trunk/perfbench/grails-gorm/build.xml
With the information above you should be able to achieve what you need. Let me know if you have any questions.

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.

Maven configuration for two projects

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>