Maven package phase: how to depend on package artifacts from other projects - maven

I have this Maven project structure:
-- top
-- a
produces a.jar and a-capsule-fat.jar
-- b
produces b.jar and b-capsule-fat.jar
-- pkg
produces all.tar.gz, which contains a-capsule.jar and b-capsule.jar
I am using the capsule-maven-plugin to build fat jars in a couple of projects, as shown above. Normally capsule is run during the package phase. I then want to assemble the capsule jars into a tar.gz for deployment purposes. I am using the maven-assembly-plugin in project pkg to make the tar.
But the maven-assembly-plugin also normally runs during the package phase, and it's running before the capsule jars are created.
Can I specify a assembly dependency or ordering that will force maven to create the capsule jars first? Alternatively I could build the assembly in a later phase, but there are no really suitable later ones (in install? there is no post-package).
POST-ANSWER: I am including some pieces of the working code for posterity:
dependencies in pkg/pom.xml:
<dependency>
<groupId>thegroup</groupId>
<artifactId>a</artifactId>
<version>theVersion</version>
<type>jar</type>
<classifier>capsule-fat</classifier>
</dependency>
<dependency>
<groupId>thegroup</groupId>
<artifactId>b</artifactId>
<version>theVersion</version>
<type>jar</type>
<classifier>capsule-fat</classifier>
</dependency>
assembly plugin settings in pkg/pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>build-tar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/main/assembly/pkg.xml</descriptor>
</descriptors>
</configuration>
</plugin>
pkg.xml (referenced above):
<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>ustc-archive-pkg</id>
<formats>
<format>tar.gz</format>
</formats>
<dependencySets>
<dependencySet>
<includes>
<include>*:jar:capsule-fat</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

Make sure the definition for the capsule-maven-plugin appears before the maven-assembly-plugin. When there are executions bound to the same phase, Maven uses the order of the plugin definitions in the POM to break the tie.
---- edit ----
Make sure the dependencies on a and b include a classifier:
<dependency>
<groupId>theGroup</groupId>
<artifactId>a</artifactId>
<version>theVersion</version>
<classifier>capsule-fat</classifier>
</dependency>
See if that does it.

Related

Groovy and Maven: Stuck in compiling and testing a very simple

I am stuck trying to compile and test a extremely simple project. It's a beginner project in order to understand how all of this works, and I am currently stucked.
My main objective is to understand how to handle resources files that are located outside of the standard folder structure.
I have a main class, with two methods. One load a resource file which is on the standard folder structure (src\main\resources). Another one load a resource which is in a custom folder, outside of the standard structure (resources).
There is one junit file that simply verify that the resource is correctly loaded.
It works fine with IntelliJ. I simply declared the resources folder as resources folders and that's it.
Now with maven ..... actually I can't even compile with gmaven-plus. Nor run the test. So I did not even bother to declare the custom folder as a resource in the pom.xml file.
I based my pom.xml file based on an existing pom we have at work and from stuff I read on the web. There's no way I can make it work.
Here is a link to a 7zip file with my project, if one could put me on the right track, I would be grateful.
https://www.dropbox.com/s/jvn32ll5xfvjfwd/GroovyExample.7z?dl=0
Here is the pom:
<?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>Example</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.13</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.8.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compileTests</goal>
</goals>
<configuration>
<sources>
<source>
<directory>src/main/groovy</directory>
<includes>
<include>**/*.groovy</include>
</includes>
</source>
</sources>
<testSources>
<testSource>
<directory>src/test/groovy</directory>
<includes>
<include>**/*.groovy</include>
</includes>
</testSource>
</testSources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<failIfNoTests>true</failIfNoTests>
<testSourceDirectory>str/test/</testSourceDirectory>
<includes>
<include>**/*Test*.*</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Here is the output:
Unable to get Groovy version from InvokerHelper or GroovySystem,
trying jar name.
Failed to execute goal
org.codehaus.gmavenplus:gmavenplus-plugin:1.8.1:compile (default) on
project Example: Execution default of goal
org.codehaus.gmavenplus:gmavenplus-plugin:1.8.1:compile failed.
The 2.4 groovy-all POMs do not include Groovy as a dependency, because they are a POM for an uber-jar, rather than a POM that describes all the Groovy module jars. Because of this, GMavenPlus is unable to find the Groovy jar to use for compilation. The <type>pom</type> works for Groovy 2.5, and 3.0, but not 2.4. So for your use case, simply delete the <type>pom</type> (or replace it with the default of <type>jar</type>). This was the way Groovy was often included back before 2.5, so the groovy-all POMs of 2.5 and 3.0 were added to ease the transition. See https://groovy-lang.org/releasenotes/groovy-2.5.html#Groovy2.5releasenotes-Packaging.

Seperate the jars using maven assembly plugin

I need to separate the jars into different folders.
Inside my project, I have several modules, i.e: module1, module2, and assembly.
By using maven assembly plugin, I would like to put generated jar from modules1 and module2 into target/modules and all the dependencies into target/dependencies.
How can I achieve this requirement?
Thanks
Based on the fact that your project is structured like :
project
|- module1
|- module2
|- assembly
|- pom.xml
|- src
|- assembly
|- bin.xml
assembly should depend on module1 and module2; set these dependencies in assembly/pom.xml :
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module1</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module2</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
You must also add maven-assembly-plugin in assembly/pom.xml :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptors>
<descriptor>src/assembly/bin.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assembly:single is bound on package phase, to create the assembly when running mvn package.
Finally, define assembly/src/assembly/bin.xml as follows :
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>bin</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>modules</outputDirectory>
<includes>
<include>${project.groupId}:*:*</include>
</includes>
<excludes>
<exclude>${project.groupId}:${project.artifactId}:*</exclude>
</excludes>
</dependencySet>
<dependencySet>
<useTransitiveDependencies>true</useTransitiveDependencies>
<outputDirectory>dependencies</outputDirectory>
<excludes>
<exclude>${project.groupId}:*:*</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>
format defines the format you want for the assembly (here a directory, but could be tar.gz, zip, ...)
first dependencySet defines a folder modules/ where all artifacts from the same groupId will be put. Here you can also control if you want only some of the artifacts (for example if you want only module1). assembly JAR is excluded from this folder, as this module is only used to create the assembly
second dependencySet defines a folder dependencies/ where all dependencies (and transitive dependencies) will be put. Dependency here means artifact with a different groupId, as states the excludes clause
mvn package will then generate the assembly (in assembly/target/ folder), named assembly-${project.version}-bin, with the structure you want.

Adding an External jar file in Spring Boot Application [duplicate]

I am using maven-assembly plugin to create a jar of my application, including its dependencies as follows:
<assembly>
<id>macosx</id>
<formats>
<format>tar.gz</format>
<format>dir</format>
</formats>
<dependencySets>
<dependencySet>
<includes>
<include>*:jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
(I omitted some other stuff that is not related to the question)
So far this has worked fine because it creates a lib directory with all dependencies. However, I recently added a new dependency whose scope is system, and it does not copy it to the lib output directory. i must be missing something basic here, so I call for help.
The dependency that I just added is:
<dependency>
<groupId>sourceforge.jchart2d</groupId>
<artifactId>jchart2d</artifactId>
<version>3.1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/external/jchart2d-3.1.0.jar</systemPath>
</dependency>
The only way I was able to include this dependency was by adding the following to the assembly element:
<files>
<file>
<source>external/jchart2d-3.1.0.jar</source>
<outputDirectory>lib</outputDirectory>
</file>
</files>
However, this forces me to change the pom and the assembly file whenever this jar is renamed, if ever. Also, it seems just wrong.
I have tried with <scope>runtime</scope> in the dependencySets and <include>sourceforge.jchart2d:jchart2d</include> with no luck.
So how do you include a system scoped jar to your assembly file in maven 2?
Thanks a lot
I'm not surprised that system scope dependencies are not added (after all, dependencies with a system scope must be explicitly provided by definition). Actually, if you really don't want to put that dependency in your local repository (for example because you want to distribute it as part of your project), this is what I would do:
I would put the dependency in a "file system repository" local to the project.
I would declare that repository in my pom.xml like this:
<repositories>
<repository>
<id>my</id>
<url>file://${basedir}/my-repo</url>
</repository>
</repositories>
I would just declare the artifact without the system scope, this is just a source of troubles:
<dependency>
<groupId>sourceforge.jchart2d</groupId>
<artifactId>jchart2d</artifactId>
<version>3.1.0</version>
</dependency>
I'm not 100% sure this will suit your needs but I think it's a better solution than using the system scope.
Update: I should have mentioned that in my original answer and I'm fixing it now. To install a third party library in the file-based repository, use install:install-file with the localRepositoryPath parameter:
mvn install:install-file -Dfile=<path-to-file> \
-DgroupId=<myGroup> \
-DartifactId=<myArtifactId> \
-Dversion=<myVersion> \
-Dpackaging=<myPackaging> \
-DlocalRepositoryPath=<path-to-my-repo>
You can paste this as is in a *nix shell. On windows, remove the "\" and put everything on a single line.
Btw you can automate it and make it a part of your maven build. The following will install your jar into your local repository before compilation:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>validate</phase>
<configuration>
<file>${basedir}/lib/your-lib.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
I find easy solution in case you creating jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>dependencies/mydep</directory>
<targetPath>WEB-INF/lib</targetPath>
<filtering>true</filtering>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
You can also handle this via adding a supplemental dependencySet in your dependencySets.
<dependencySet>
<scope>system</scope>
<includes>
<include>*:jar</include>
</includes>
<outputDirectory>lib</outputDirectory>
</dependencySet>
The best thing would be to use a Repository Manager (like Nexus, Artifactory, Archiva) and install this kind of dependency in a particular repository. After that you can use such things as a simple dependency. This will simplify your life.
Docs:
Edited: Sorry that i didn't realize alx also mentioned about the clean life cycle workaround.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>hack-binary</id>
<phase>clean</phase>
<configuration>
<file>${basedir}/lib/your-lib.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<version>0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
Base on the solution provided by alx, you can execute the install file step at clean phase. but since the clean phase is not in the default life cycle, you have to execute mvn clean at the first time to ensure the jar is ready in the local repo.
ex: mvn clean; mvn package
A simple solution for this is to add it into local maven repository
One way to do is via mvn install commands as suggested in previous post .
Another easy way is ,
1) In your eclipse ide right click on project select Maven option .
2) Select Install or deploy an artifact to a maven repository option and click on next.
3)Click on browse next to the Artifact file checkbox & select your jar file
4)Enter the GroupId and ArtifactId and version ensure generate pom & create checksum are checked & packaging is jar
Click on finish and that's it ! Your job is done the jar is added in your local repository which you can define in setting.xml or m2 directory
Now just add the simple maven dependency as per the GroupId,ArtifactId & jar version that you have entered as per the import and that's it your external jar will be packaged by maven.
it has worked in a easier way on my solution :
remove from your dependency :
<dependency>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
</dependency>
Then add the maven-install-plugin in the pom.xml as well.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-external</id>
<phase>clean</phase>
<configuration>
<file>${basedir}/external/tiago.medici-0.0.1.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>

Generating OSGi bundles distribution with maven-assembly-plugin

I have a multi-module project, where each module is packaged as an OSGi bundle using the Apache Felix maven-bundle-plugin. The whole project is built using a parent POM that lists the above-mentioned modules. Some modules contain configuration resources (e.g. .properties files) that should not be jarred inside the bundles for deployment but rather externalized in a dedicated config folder. My goal is to create a distribution folder (possibly, a zip file) that would look something like this:
my-app-distribution
/bundles
module1-bundle.jar
module2-bundle.jar
etc.
/conf
external1.properties
external2.properties
etc.
where the properties files under the /conf directory are hand-picked files from the individual modules' /target folders. The reason the .properties files need to be picked up from the target folders vs. the src folders is that I am using Maven resource filtering, and the source property files contain ${..} placeholders for environment-specific values. Those placeholders are properly resolved during the build process - per build profiles - and the target/ folders contain actual environment-specific values.
I've done such distribution file manipulations many times - for distributions with executable JARs, etc. In this case I wanted to use the "moduleSets" configuration of the assembly descriptor - it is easy to pull all binaries/jars into a single distribution folder using moduleSet/binary descriptor. It is also easy to exclude certain files from being packaged into an OSGi bundle - in the maven-bundle-plugin. The only issue I am stuck with is creating the /conf distribution folder and collecting the necessary properties files there. I have tried to use "fileSets" inside the "moduleSet/sources" descriptor to include only specific files from **/target of each module, but that didn't seem to work.
Anyone have a suggestion/advice? There's got to be an easy way. Or should I not use at all?
Thanks,
CV
#PetrKozelka I am not sure that extracting configuration files specific to different bundles into a separate module is a good idea. The whole point of OSGi is for bundles to be independent and potentially reusable - both in development and distributions. It only makes sense that - in the source code - the functionality implementation and related configuration files are grouped together. For a particular distribution though I might need to extract some of the files - if there is a requirement for admins to have control of certain parameters. That may be different for a different distribution/application. The assembly configuration may change, but the bundles/sources would stay the same. Also, each bundle may potentially be developed and used separately, not all bundles have to always be part of the same uber project - as you seem to assume. What you are suggesting seems to fall into the same old category of packaging enterprise applications by the type of artifacts (e.g. "model", "services", "dataaccess", "config" etc.), not by functional domain/features. Such approach works ok within a single application/project, but fails on the enterprise level where there is often a need to reuse subsets of vertical components (split by functional domains).
To your point of being dependent on the file layout in the modules, I agree that there should be no such dependency. Files could be hand-picked by their explicit name or naming convention - per very specific distro requirements. (Which is exactly the case I am facing.)
I have actually figured out how to do it more or less elegantly. Posting the solution below in case someone else is looking to solve a similar problem.
SUMMARY
I am using the maven-assembly-plugin to extract the binaries (bundle JARs) from the individual modules and package them in the <my-distribution-folder>/bundles directory. In each module where some resource files should be externalized, I consolidate such files under the /src/main/resources/external directory, and use maven-resources-plugin to copy those resources during the packaging phase to the auto-generated directory in my dedicated distribution module that contains the assembly.xml descriptor file and is also built as part of the top project. I use maven-clean-plugin in the parent POM to clear the contents of the distribution staging directory during the CLEAN phase of the top-level project build.
MAVEN CONFIGURATION
Inside each bundle's module POM that contains resources that need to be externalized I add the following resource management configuration:
<build>
<defaultGoal>install</defaultGoal>
<!--
enable resource filtering for resolving ${...} placeholders with environment-specific values
exclude any files that must be externalized
-->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>external/*.*</exclude>
</excludes>
</resource>
</resources>
...
<plugins>
<!-- Copies contents of resources/external to dedicated folder defined by property in parent -->
<!-- externalized resources will be packaged according to assembly instructions -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.parent.basedir}/${externalizableResourcesStageDir}
</outputDirectory>
<resources>
<resource>
<directory>src/main/resources/external</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- builds a JAR file for this bundle -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
<Import-Package>*</Import-Package>
<Export-Package>
${project.groupId}.thismodulepackage*;version=${project.version}
</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
where externalizableResourcesStageDir is a property defined in the top/parent POM. In the project, I include a special distribution module with the following structure:
distribution
/ext-resources (target auto-generated dir for external resources from modules)
/src
/assemble
assembly.xml (assembly descriptor)
The assembly.xml file looks like this:
<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>
<!-- generate a ZIP distribution -->
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>/</baseDirectory>
<moduleSets>
<moduleSet>
<!-- Enable access to all projects in the current multi-module build -->
<useAllReactorProjects>true</useAllReactorProjects>
<!-- select projects to include-->
<includes>
<include>myGroupId:myModuleArtifactId1</include>
<include>myGroupId:myModuleArtifactId2</include>
...
</includes>
<!-- place bundle jars under /bundles folder in dist directory -->
<binaries>
<outputDirectory>${artifactId}/bundles</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
<!-- now take files from ext-resources in this module and place them into dist /conf subfolder-->
<fileSets>
<fileSet>
<directory>ext-resources</directory>
<outputDirectory>${artifactId}/conf/</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
The distribution module's POM would look like 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>
<parent>
<groupId>myGroupId</groupId>
<artifactId>parentArtifactId</artifactId>
<version>...</version>
</parent>
<groupId>myGroupId</groupId>
<artifactId>distribution</artifactId>
<version>...</version>
<packaging>pom</packaging>
<name>Distribution</name>
<description>This module creates the <MyProject> Distribution Assembly</description>
<url>http:...</url>
<!-- NOTE: These dependency declarations are only required to sort this project to the
end of the line in the multi-module build.
-->
<dependencies>
<dependency>
<groupId>myGroupId</groupId>
<artifactId>myModuleArtifactId1</artifactId>
<version>${project.version}</version>
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>dist-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assemble/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The parent POM would list all the bundle modules, plus the distribution module and also define the assembly plugin:
<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>myParentId</artifactId>
<version>...</version>
<packaging>pom</packaging>
<properties>
...
<!-- directory where build may place any sub-modules' resources that should be externalized -->
<!-- those resources may be picked up by maven-assembly-plugin and packaged properly for distribution -->
<externalizableResourcesStageDir>
esb-distribution/ext-resources
</externalizableResourcesStageDir>
</properties>
<!-- all project modules (OSGi bundles + distribution) -->
<modules>
<module>bundle-module1</module>
<module>bundle-module2</module>
...
<module>distribution</module>
</modules>
<dependencyManagement>
<dependencies>
...
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<!--
Cleans contents of the folder where the externalized resources will be consolidated
Each module adds its own external files to the distribution directory during its own build
-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>clean-ext-resources</id>
<phase>clean</phase>
</execution>
</executions>
<configuration>
<filesets>
<fileset>
<directory>${externalizableResourcesStageDir}</directory>
<includes>
<include>*.*</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptors>
<descriptor>src/assemble/assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
NOTE: We've also made sure that the externalized resource files are excluded from being packaged inside the individual bundle JARs (see the resources section of the module POM.) The resulting unzipped distribution will look like this:
my-app-distribution
/bundles
module1-bundle.jar
module2-bundle.jar
etc.
/conf
external1.properties
external2.properties
etc.

maven: multi-module project assembly into single jar

I have a multi-module project and want to create a single jar containing the classes of all my modules. Inside my parent POM, I declared the following plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>bin</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
However, when running mvn assembly:assembly, only the source from the parent folder (empty) are included. How do I include the sources from my modules into the archive?
I think you are looking for the Maven Shade Plugin:
http://maven.apache.org/plugins/maven-shade-plugin/index.html
Packages up any number of dependencies into an uber package depenency. This can then be deployed to a repository.
To package classes from all modules to a single jar I did the following:
Created additional module that is used only for packing contents of all other modules to a single jar. This is usually reffered to as a assembly module. Try calling this module same as target jar file.
In pom.xml of this new module i added maven-assemby-plugin. This plugin packages all classes and puts them in single file. It uses additional configuration file (step 4.)
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>go-framework-assemby</id>
<phase>package</phase><!-- create assembly in package phase (invoke 'single' goal on assemby plugin)-->
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assemble/framework_bin.xml</descriptor>
</descriptors>
<finalName>framework</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
3.In pom.xml of this new module I also added dependencies to all other modules including parent pom. Only modules included in dependencies will be packed in target jar file.
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>fwk-bam</artifactId>
<version>${project.version}</version>
</dependency>...
4.Finally i created assembly descriptor in assembly module (file: src/main/assemble/framework_bin.xml)
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>all-jar</id>
<formats>
<format>jar</format> <!-- the result is a jar file -->
</formats>
<includeBaseDirectory>false</includeBaseDirectory> <!-- strip the module prefixes -->
<dependencySets>
<dependencySet>
<unpack>true</unpack> <!-- unpack , then repack the jars -->
<useTransitiveDependencies>false</useTransitiveDependencies> <!-- do not pull in any transitive dependencies -->
</dependencySet>
</dependencySets>
</assembly>
The predefined bin won't do the trick here. You'll have to use a custom descriptor similar to the predefined bin descriptor but that declares moduleSet to include your project modules.

Resources