How does rpm-maven-plugin name the generated rpm archive? - rpm-maven-plugin

I've been all over the official documentation without finding an answer. There don't seem to be any parameters for affecting the name of the generated rpm.
I'm doing the rpm:rpm goal on this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.whatever</groupId>
<artifactId>myapp</artifactId>
<version>0.3.5</version>
<name>myapp</name>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.1.4</version>
<executions>
<execution>
<id>generate-rpm</id>
<goals>
<goal>rpm</goal>
</goals>
</execution>
</executions>
<configuration>
<group>Application/Engineering</group>
<changelogFile>src/changelog</changelogFile>
<mappings>
...
</mappings>
</configuration>
</plugin>
and it's generating for me an RPM called
myapp-0.3.5.noarch.rpm-0.3.5-1.noarch.rpm.
I'd expect myapp-0.3.5.noarch.rpm or myapp-0.3.5-1.noarch.rpm.
Why the repeated version number and "noarch.rpm"? What am I doing wrong?
Also, with the above configuration, this RPM is not installed into the local .m2 repository if we execute the install goal.
As an exercise, given the official sample, what name should we expect the generated rpm to have? Documentation doesn't say.
Or maybe I just don't understand what the plugin authors mean by "RPM as Side Effect" in labeling this scenario.
If I change the execution above to
<executions>
<execution>
<id>attach-rpm</id>
<goals>
<goal>attached-rpm</goal>
</goals>
</execution>
</executions>
as described in the "RPM as Secondary Artifact" section then, lo and behold, the plugin does what I was expecting, i.e. it generates myapp-0.3.5.noarch.rpm and puts in in the m2 repository in the expected place.
I guess that's "the answer" to my question, but it's still kinda weird. Based on the description, I'm not surprised that the "secondary" option puts the rpm into the m2 repo, but I don't understand the odd naming. IMHO, the nomenclature and descriptions of these options is lacking something.

Related

Using build-helper-maven-plugin

I have the pom.xml below.
I'd like to pass a tag property to my build, using this command:
mvn clean package -Dtag=test
It should split this property into two others, my.group an my.version, and then use it in a URI to build an XLDeploy package, using the xldeploy-maven-plugin (https://docs.xebialabs.com/xldeploy-maven-plugin/6.0.x/).
My problem is that the regex-properties goal is actually doing the job, as I can see thanks to the maven-antrun-plugin:
[INFO] --- maven-antrun-plugin:1.1:run (default) # myArtifactId ---
[INFO] Executing tasks
[echo] Displaying value of 'my.group' property
[echo] [my.group] group/test
[echo] Displaying value of 'my.version' property
[echo] [my.version] test
But the command grep fileUri target\deployit-working-dir\deployit-manifest.xml show that the vars in Uri does not get replaced:
grep fileUri target\deployit-working-dir\deployit-manifest.xml
<fileUri>http://mynexus.ur/service/local/repositories/my-repo/content/${my.group}/anArtefact/${my.version}/anArtefact-1.0.zip</fileUri>
The POM is the following file:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>myGroupId</groupId>
<artifactId>myArtifactId</artifactId>
<version>1.0</version>
<packaging>dar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>regex-properties</id>
<goals>
<goal>regex-properties</goal>
</goals>
<configuration>
<regexPropertySettings>
<regexPropertySetting>
<name>my.group</name>
<value>group/${tag}</value>
<regex>(asm-[0-9]+)-([0-9]+.[0-9]+)-([0-9]+)$</regex>
<replacement>$1</replacement>
<failIfNoMatch>false</failIfNoMatch>
</regexPropertySetting>
<regexPropertySetting>
<name>my.version</name>
<value>${tag}</value>
<regex>(asm-[0-9]+)-([0-9]+.[0-9]+)-([0-9]+)$</regex>
<replacement>$1-SNAPSHOT</replacement>
<failIfNoMatch>false</failIfNoMatch>
</regexPropertySetting>
</regexPropertySettings>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Displaying value of 'my.group' property</echo>
<echo>[my.group] ${my.group}</echo>
<echo>Displaying value of 'my.version' property</echo>
<echo>[my.version] ${my.version}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.xebialabs.xldeploy</groupId>
<artifactId>xldeploy-maven-plugin</artifactId>
<version>6.0.0</version>
<extensions>true</extensions>
<configuration>
<deployables>
<file.Folder name="file">
<scanPlaceholders>false</scanPlaceholders>
<fileUri>http://mynexus.ur/service/local/repositories/my-repo/content/${my.group}/anArtefact/${my.version}/anArtefact-${project.version}.zip</fileUri>
</file.Folder>
</deployables>
</configuration>
</plugin>
</plugins>
</build>
</project>
I'm not quite sure if the build-helper-maven-plugin wrong, or anywhere else in my POM, or if it's simply lack of replacing properties in the xldeploy-maven-plugin...
Thanks for the help ;)
I checked the source of xldeploy-maven-plugin-6.0.1, and it seems it is the limitation of the current implementation.
The problem is that GenerateDeploymentPackageMojo does not rely on maven to do the substitution of the properties. Instead, it uses a custom AbstractConfigurationConverter named DeployitCIConverter (which delegates to MavenDeployableConverter) to convert the <deployables> node to a list of MavenDeployable)
This boils down to:
you have the access to effective POM
you don't have access to properties defined dynamically via build helper plugin
Of course the properties defined dynamically can be acessed in any mojo:
if you use a parameter
if you evaluate them manually via expression evaluator (check: get mojo parameters in maven plugin)
For the antrun plugin, it uses ExpressionEvaluator explicitely in the echo task.
Informative article:
Properties resolution in Maven and its implications on Antrun plugin
Ideas to fix the problem:
do your group and version parsing in external script and pass the values to mvn command.
create a cutom mojo extending GenerateDeploymentPackageMojo and preprocess deployables in the execute method (not that hard as it sounds).

Which dependencies do I have to include in a Maven Apache Storm Project?

I am pretty new to Apache Storm and Maven projects, so I tried to follow this "tutorial" (which from my point of view is not a tutorial at all):
http://storm.apache.org/releases/current/Creating-a-new-Storm-project.html
There is a huge pom.xml referenced (https://github.com/apache/storm/blob/v1.1.1/examples/storm-starter/pom.xml) which shall be used as basis for a new project. I tried to figure out what to copy into my project pom.xml. So I decided to start with the apache core dependency first. My pom.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>StormTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>false</includePluginDependencies>
<classpathScope>compile</classpathScope>
<mainClass>${storm.topology}</mainClass>
<cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>StormTest-1.0-SNAPSHOT_dep</finalName>
<archive>
<manifest>
<mainClass>de.arphi.bi.WordCountTopology</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>${basedir}/resources</directory>
<filtering>false</filtering>
<includes>
<include>log4j2.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
This even works when it is about runing maven and building / packaging a jar. The outcome are two jar files (a small one without dependencies and a bigger one with dependencies). I cannot run the smaller one because it says "main manifest not found". But I can run the bigger one by executing the following command:
storm -jar StormTest-1.0-SNAPSHOT_dep.jar
Actually the runs on my locally installed apache storm 1.1.1 (I have some System.out.printlns ...) but I get an exception:
2018-01-02 21:38:31,864 main ERROR Unable to create file C:\Users\Artur\Desktop\Bi\apache-storm-1.1.1\logs/access-web-${sys:daemon.name}.log java.io.IOException: Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch
at java.io.WinNTFileSystem.canonicalizeWithPrefix0(Native Method)
at java.io.WinNTFileSystem.canonicalizeWithPrefix(WinNTFileSystem.java:451)
at java.io.WinNTFileSystem.canonicalize(WinNTFileSystem.java:422)
at java.io.File.getCanonicalPath(File.java:618)
at java.io.File.getCanonicalFile(File.java:643)
at org.apache.logging.log4j.core.util.FileUtils.makeParentDirs(FileUtils.java:134)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:573)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:554)
at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:112)
at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:155)
at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:131) at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:60)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:952)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:892)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:884)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:508) at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:232)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:244)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at org.apache.storm.topology.BasicBoltExecutor.<clinit>(BasicBoltExecutor.java:28)
at org.apache.storm.topology.TopologyBuilder.setBolt(TopologyBuilder.java:215)
at de.arphi.bi.WordCountTopology.main(WordCountTopology.java:22)
It says something about the syntax for creating a directory is wrong. And I know that it is about logging. I played arroung with different other dependencies (log4j, slf4j) and tried ecen to exclude dependecies without any success. I cannot get rid of this error.
Any ideas? I think that I am missing a dependency or that I have to exclude some parts of my pom.xml. But since I am not an Maven expert it is really hard for me to figure out what I have to adapt here.
I agree that storm-starter has gotten pretty big, and we should maybe have more of a minimal example.
First you should set the storm-core dependency to "provided" scope. When you deploy the topology to Storm, your jar will use the storm-core jar present in the Storm installation, so you shouldn't also put it in your fat jar.
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
When your topology runs on Storm, it will use the Log4j2 configuration in the log4j2/worker.xml file in your Storm installation. You shouldn't include your own log4j2.xml. If you need to set specific log levels, you can either modify worker.xml or use the CLI as described at http://storm.apache.org/releases/1.1.1/dynamic-log-level-settings.html.
Other than that your pom looks fine. I don't know why you have exec-maven-plugin in there (Edit: I see it's also in storm-starter, I think it's a leftover from when it was possible to run storm-starter in local mode. You shouldn't need it), and I might replace maven-assembly-plugin with the shade plugin, but I'd expect your topology to work regardless.
Thank Stig Rohde Døssing. Finally I found the origin for my exception base on your hint regarding the log4j2/worker.xml. The issue was not in the worker.xml, but in the cluster.xml which is located in the same directory.
When reading my Exception shown here, you can see that Java complains about creating a system path ("access-web-${sys:daemon.name}.log"). I found the placeholder sys:daemon.name in the cluster.xml and replaced it with something static like "access-web-mysysdaemonname.log". That fixed the issue. I have no idea why this placeholder could not be resolved by the system while there was no trouble with other placeholders.
Thanks for the hints. Topic can be closed.

How can I override maven property values set by properties-maven-plugin's read-project-properties goal?

In one of our projects, we use the properties-maven-plugin's read-project-properties goal to read property values from a file which are then used for filtering resources. See this post for a discussion on the general purpose of this procedure.
We would like to override some of the values found in the file using a suitable profile defined in the developer specific settings.xml (the same way we override properties set in the POM).
This, however, does not work for the properties set by the properties-maven-plugin.
How can we achieve our goal?
As a work around, we are currently registering an additional, developer specific file with the properties-maven-plugin to achieve this effect but it would be much more convenient to use the regular way (profiles).
In more general terms, the question is: How do properties set by properties-maven-plugin's read-project-properties goal tie into the property definition precedence hierarchy of maven, which is described in this very helpful blog post.
I extracted the relevant elements of our POM into a toy project that demonstrates my issue. Here is the POM of the toy project:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>xxx</groupId>
<artifactId>MavenTest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Test</name>
<description>A maven project to test filtering and the maven-properties-plugin</description>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<!-- Read properties from a file -->
<execution>
<id>load-filter-properties</id>
<goals>
<goal>read-project-properties</goal>
</goals>
<phase>initialize</phase>
<configuration>
<files>
<file>filters/filterTest.properties</file>
</files>
<quiet>false</quiet>
</configuration>
</execution>
<!-- The following execution is for debug purposes only -->
<execution>
<id>write-project-properties</id>
<inherited>false</inherited>
<goals>
<goal>write-project-properties</goal>
</goals>
<phase>package</phase>
<configuration>
<outputFile>filters/project.properties</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12-beta-1</version>
</dependency>
</dependencies>
</project>
I think you will find the answer here:
Modifications of project properties that happen during project lifecycle have no effect on the effective pom – it is just too late. Examples of such modifications include groovy scripts (via gmaven-plugin) and properties loaded from external files via maven-properties-plugin. So, why do we need them at all? Since they can be used by other plugins in runtime, when they are read directly from properties collection during plugin invocation.
Since the properties are read after the usual resolution they just override whatever was set in profiles.

Maven: how to use POM elements from within assembly descriptor

I need to assemble several sets of resources. These sets of resources are related to each other. So, I decided to put them all under the same project and use the assembly plugin to achieve my goal.
I have ended with a POM and a descriptor file for each set of resources.
Let's assume that my project is as follows:
src/main/resources/set1 : contains resources for the first set
src/main/resources/set2 : contains resources for the second set
src/main/resources/set3 : contains resources for the third set
descriptor1.xml : the assembly descriptor for the first set
descriptor2.xml : the assembly descriptor for the second set
descriptor3.xml : the assembly descriptor for the thord set
pom.xml
The content of descriptor1.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>set1</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${project.basedir}/src/main/resources/set1</directory>
</fileSet>
</fileSets>
</assembly>
The content of descriptor2.xml and descriptor3.xml is similar to the content of descriptor1.xml except that set1 (in "/assembly/id" and "/assembly/fieldSets/fieldSet/directory") is replaced by set2 and set3 respectively.
The content of pom.xml is as follows:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sample</groupId>
<artifactId>sample.assembler</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<properties>
<maven-assembly-plugin.version>2.4</maven-assembly-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
<executions>
<execution>
<id>set1</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor1.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>set2</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor2.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>set3</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>descriptor3.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The above config gives the expected result. However, there are a lot of descriptor files to maintain.
I have read in the documentation that descriptor files are interpolated using project properties, POM element values, user properties, ... before being used.
My question is : is there a way to reference the id of the current execution (some thing like project.build.execution.id)? In such a case, all my three descriptors with be replaced by only one file.
Thank you in advance.
I don't think you can achieve what you want within single run.
But you can create a profiles where earch of the profile will define different properties and you can run your build three times with different profiles to get 3 different file sets.
I do use such approach for generating configuration for different environments. I activate the environment profile and the output is the environment configuration. The configuration is generated by single descriptor which is driven by the profile properties.
EDIT:
Here is a workaround using per-execution propeties which may solve your problem. In the moment I'm not entirely sure if these filters will be used for filtering resources only or you can reference them in the assembly itself for defining lets say <finalName> ...
See: http://olafsblog.sysbsb.de/per-assembly-filtering-with-the-maven-assembly-plugin/

Maven multi-module project - copying all "package" JARS from submodules into parent/target/

I have a maven project with quite a few submodules. What I am looking for is a way to get all the .jar files produced by the sub-modules included in the aggregating POM's /target/ directory, so they can be conveniently used afterwards.
They don't need to be merged. Preferably not, but if they must be then that is ok.
Don't care about dependancies
This is primarily for convenience, at this point
A basic version of what I am looking at doing:
Prj1/pom.xml => prj1/target/proj1.jar (and classes/generated-sources/etc)
Prj2/pom.xml => prj2/target/proj2.jar
Main/pom.xml =>
main/target/proj1.jar
main/target/proj2.jar
... classes/generated-sources not needed at all,
... but they could be combined here. I assume they will be
I've been reading, and using some suggestions from SO as well. So far I haven't found a way to do this, but I'm sure it is there.
edit:
I've given up on getting this to work in a simple way, for all included subprojets. The best answer I have so far is using the dependancy plugin to manually specify (again), each and every sub-module to be included. The idea was to be able to configure the POMs easily for the dozens of clients, simply including the modules necessary and then having it magically stick all the sub-modules's jars in one location. Maven is pretty nice, when you don't do much with it, but the angle bracket tax is incredible when you try.
I still find it odd that such standard-seeming tasks (judging from the questions asked on SO, and what any normal project would do) are so difficult. Is maven3 better?
You could try the maven-dependency-plugin:copy plugin:goal.
You will have to add this to the pom of all submodules that you want to copy.
EDIT: Or just in the parent pom (see comments).
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-artifact</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>../Main/target/dependencies</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
If you do put this in the parent pom, keep in mind that it will work nicely only if your whole project is one module deep. Meaning that if the the modules under the parent module have their own submodules, they will not end up in the desired folder. Your folder structure will look like this:
- Parent
- Module 1
- Sub module 1
**Main**
- Module 2
**Main**
To prevent this, create a dedicated module with above configuration, and specify manually each module that you want to copy. This way all modules, no matter how deep they are will end up in one folder.
I have spent the entire day trying to solve this... and finally it works, so even though I am on a tough schedule, I will share it here, if I can only save someone's frustration in the future...
Step 1. Create an additional Maven project that will be a parent of all the projects that you want to copy together. Let's call this project parent.
This project is needed to tell Maven, which projects to build together. Also, you will declare in your other projects that their parent is parent, so they will see the MyDir property that you define here.
<groupId>com.your.domain</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<properties>
<MyDir>/your/path/to/copy/to</MyDir>
</properties>
<modules>
<module>../project1</module>
<module>../project2</module>
<module>../project2</module>
</modules>
Step 2. For every project that you want to be copied to the same location, specify that it's parent is the parent project (make sure you specify correct groupId and artifactId and version of your parent project):
<parent>
<groupId>com.your.domain</groupId>
<artifactId>parent</artifactId>
<version>0.0.1</version>
<relativePath>../parent</relativePath>
</parent>
And also, for each of these projects, also specify the jar and dependency plugins settings, like so:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<outputDirectory>${MyDir}</outputDirectory>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.your.domain.Program</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${MyDir}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Then just run mvn install on the parent project. Bam!
P.S. The above assumes all projects are located in the same directory (parent project next to children), but you can change relative paths as you wish.
One way to achieve this would be to use the moduleSet option of maven assembly plugin.
You could create an assembly descriptor like this (a variation of the example in the link) and use it in assembly plugin declaration in the pom.
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bin</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<moduleSets>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<binaries>
<outputDirectory>/</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
</assembly>

Resources