Maven: Packaging dependencies alongside project JAR? - maven-2

I'd like Maven to package a project alongside its run-time dependencies. I expect it to create a JAR file with the following manifest:
.....
Main-Class : com.acme.MainClass
Class-Path : lib/dependency1.jar lib/dependency2.jar
.....
and create the following directory structure:
target
|-- ....
|-- my-project.jar
|-- lib
|-- dependency1.jar
|-- dependency2.jar
Meaning, I want the main JAR to exclude any dependencies and I want all transitive dependencies to get copied into a "lib" sub-directory. Any ideas?

I've like Maven to package a project with run-time dependencies.
This part is unclear (it's not exactly what you describe just after). My answer covers what you described.
I expect it to create a JAR file with the following manifest (...)
Configure the Maven Jar Plugin to do so (or more precisely, the Maven Archiver):
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.acme.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
...
<dependencies>
<dependency>
<groupId>dependency1</groupId>
<artifactId>dependency1</artifactId>
<version>X.Y</version>
</dependency>
<dependency>
<groupId>dependency2</groupId>
<artifactId>dependency2</artifactId>
<version>W.Z</version>
</dependency>
</dependencies>
...
</project>
And this will produce a MANIFEST.MF with the following entries:
...
Main-Class: fully.qualified.MainClass
Class-Path: lib/dependency1-X.Y.jar lib/dependency2-W.Z.jar
...
and create the following directory structure (...)
This is doable using the Maven Dependency Plugin and the dependency:copy-dependencies goal. From the documentation:
dependency:copy-dependencies takes the list of project direct dependencies and optionally transitive dependencies and copies them to a specified location, stripping the version if desired. This goal can also be run from the command line.
You could bind it on the package phase:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>

Add the following plugins in pom.xml. Check the value at mainClass,classpathPrefix,addClasspath tags.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>org.apache.camel.spring.Main</mainClass>
<classpathPrefix>lib/</classpathPrefix>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/assembly/some-assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Create some-assembly.xml under src/assembly as below.
<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>distribution</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<scope>runtime</scope>
<outputDirectory>/lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
Note that useProjectArtifact flag to false, unpack flag to false. If root folder inside zip file is not required,then one can make includeBaseDirectory to false.
This will create name-version-distribution.zip file. Inside zip file, there will be folder name-version. Inside this folder, your executable jar and lib folder containing all dependency jars will be present. Check manifest.MF file of executable jar. It contains both main class and classpath information.

You can use the maven jar plugin, take a look on this page:
http://maven.apache.org/plugins/maven-jar-plugin/examples/manifest-customization.html

Related

Why maven compilation doesn't work with "pom" packaging type

I don't know why my maven build doesn't generate target/classes in current pom setting, the packaging type must be "pom" in my case, please advise what is wrong... Thanks!
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>com.abc.sm.doctor</groupId>
<artifactId>smdoctor</artifactId>
<packaging>pom</packaging>
<version>${SMDOCTOR_VERSION}</version>
<name>sm doctor</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<debug>true</debug>
<debuglevel>source,lines</debuglevel>
<showDeprecation>true</showDeprecation>
<archive>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>smdoctor</finalName>
<descriptors>
<descriptor>dist.xml</descriptor>
<descriptor>zip.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/smdoctor.zip</file>
<type>zip</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>...</mainClass>
</manifest>
</archive>
</configuration>
<version>2.3.1</version>
</plugin>
</plugins>
</build>
<dependencies>
...
</dependencies>
By setting the packaging type to pom, you specify that nothing should be compiled. Maybe pom isn't the right packaging type for this artifact after all? It looks like your script would run fine as jar.
The compiler plugin is not bound to any phase in the maven lifecycle with packaging pom. You would have to configure an execution like you did for the assemby plugin:
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
If your sources are in a folder other than src/main/java you would have to configure this folder in the build section of your pom:
<build>
<sourceDirectory>${basedir}/path/to/sources</sourceDirectory>
<!-- plugins and other configuration -->
</build>
pom packaging is just to let other modules inherit common and regular configurations such as plugins, dependencies, contributors, developers,....and so on for child modules. Just remember that it won't go beyond validate phase.
This packaging is logical and not real one and so you should not put any real code or resources at that level. If you use junit in say 5 child modules, so rather than defining the dependency in 5 pom files then you can just do it in the parent pom with pom packaging, and you still can specify specific version in your module if you like to override what's in the parent pom. When you run the parent pom then the pom execution starts from parent to children and then all dependencies are retrieved from up to down.
That's how i understand pom packaging. So, If you have code with such packaging this means that your maven project structure need amendment. Only use packaging pom as a common configurations between multiple modules only

modelling XML dependencies between projects using maven

I'm building an application that is composed of two projects: common and theApp.
Now, theApp depends upon common (modelled using a dependency). The tricky thing i'm facing is:
There are XML files in common/src/main/env which will be needed while theApp is running.
To make things more fun, a distribution of run will have this structure:
bin/ - has scripts
lib/ - has the jars created by theApp and common
dependencies/ - has the library jars on which the app depends
config/ - has the xml files from theApp and common
I'm all done, except that I'm still looking for a way to write a maven goal in theApp's POM that can put common's XML files in config/.
Any ideas?
Thanks,
Harshath
You'll need the maven assembly and dependency plugins. Create an assembly descriptor in common/src/main/resources/assemblies/config.xml like this:
<assembly>
<id>config</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${basedir}/src/main/env</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<outputDirectory>config/</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>
Then use it in your pom like:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>my.groupid</groupId>
<artifactId>common</artifactId>
<version>my.version</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
This'll create an attached artifact common-config.zip, which you can expand with the maven-dependency-plugin inside theApp's pom.xml, putting the files in theApp's target/config directory (which may not be suitable, depending on how you're creating your final distribution):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>my.groupid</groupId>
<artifactId>common</artifactId>
<version>my.version</version>
<type>zip</type>
<overWrite>true</overWrite>
<includes>*</includes>
<outputDirectory>${project.build.directory}/config</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
Some of this is documented in http://www.sonatype.com/books/mvnref-book/reference/assemblies.html ...

Maven: add a folder or jar file into current classpath

I am using maven-compile plugin to compile classes. Now I would like to add one jar file into the current classpath. That file stays in another location (let's say c:/jars/abc.jar . I prefer to leave this file here). How can I do that?
If I use classpath in the argument:
<configuration>
<compilerArguments>
<classpath>c:/jars/abc.jar</classpath>
</compilerArguments>
</configuration>
it will not work because it will override the current classpath (that includes all the dependencies)
This might have been asked before. See Can I add jars to maven 2 build classpath without installing them?
In a nutshell: include your jar as dependency with system scope. This requires specifying the absolute path to the jar.
See also http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
The classpath setting of the compiler plugin are two args. Changed it like this and it worked for me:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerArgs>
<arg>-cp</arg>
<arg>${cp}:${basedir}/lib/bad.jar</arg>
</compilerArgs>
</configuration>
</plugin>
I used the gmavenplus-plugin to read the path and create the property 'cp':
<plugin>
<!--
Use Groovy to read classpath and store into
file named value of property <cpfile>
In second step use Groovy to read the contents of
the file into a new property named <cp>
In the compiler plugin this is used to create a
valid classpath
-->
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.0</version>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<!-- any version of Groovy \>= 1.5.0 should work here -->
<version>3.0.6</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
</dependencies>
<executions>
<execution>
<id>read-classpath</id>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<configuration>
<scripts>
<script><![CDATA[
def file = new File(project.properties.cpfile)
/* create a new property named 'cp'*/
project.properties.cp = file.getText()
println '<<< Retrieving classpath into new property named <cp> >>>'
println 'cp = ' + project.properties.cp
]]></script>
</scripts>
</configuration>
</plugin>
From docs and example it is not clear that classpath manipulation is not allowed.
<configuration>
<compilerArgs>
<arg>classpath=${basedir}/lib/bad.jar</arg>
</compilerArgs>
</configuration>
But see Java docs (also https://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/tooldocs/solaris/javac.html)
-classpath path Specifies the path javac uses to look up classes needed to run javac or being referenced by other classes you are
compiling. Overrides the default or the CLASSPATH environment variable
if it is set.
Maybe it is possible to get current classpath and extend it,
see in maven, how output the classpath being used?
<properties>
<cpfile>cp.txt</cpfile>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>build-classpath</id>
<phase>generate-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>${cpfile}</outputFile>
</configuration>
</execution>
</executions>
</plugin>
Read file (Read a file into a Maven property)
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
def file = new File(project.properties.cpfile)
project.properties.cp = file.getText()
</source>
</configuration>
</execution>
</executions>
</plugin>
and finally
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<compilerArgs>
<arg>classpath=${cp}:${basedir}/lib/bad.jar</arg>
</compilerArgs>
</configuration>
</plugin>
We mixed two of the answers found here to solve a similar problem. Our project needs a JAR only in compile stage, but add a local dependency, using system scope, it is unuseful because Maven refuse the artifact publication with an error related to a missing dependency.
The snippets used are the following:
<properties>
<classpathfile>${basedir}/classpathfile.classpath</classpathfile>
</properties>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>build-classpath</id>
<phase>generate-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>${classpathfile}</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
def file = new File(project.properties.classpathfile)
project.properties.originalClassPath = file.getText()
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerArgs>
<arg>-cp</arg>
<arg>${originalClassPath}${path.separator}${basedir}/../../../bin/POM_RUNTIME_PLACEHOLDER/ExtraJar.jar</arg>
</compilerArgs>
</configuration>
</plugin>
Maven is able to compile and successfully deploy the artifacts.
If anyone is interested the full POM is available in GitHub under project NuReflector, defaultPOM.template under src/NuReflector.

Maven - Include dependent libs in jar without unpacking dependencies?

We're trying to build a client jar that includes unpacked dependent jar's. And the manifest should have class-path entries to the dependent jars. The snippet below works but the jars are unpacked - how can we stop the jars from being unpacked?
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Indeed, assembling using jar-with-dependencies causes maven to unpack all the dependencies as ${assembly.dependencySets.dependency.unpack} is set to true in the corresponding assembly descriptor.
A simple fix would be to provide an assembly descriptor similar to the jar-with-dependencies.xml and modify ${assembly.dependencySets.dependency.unpack} to false, like this:
EDIT: For an unknown reason, the behavior when using <unpack>false</unpack> is not exactly the same and it seems necessary to add <outputDirectory>/</outputDirectory> to the fileSet or you don't get the expected result.
<assembly>
<id>uberjar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
You can add your dependencies as jar files to your jar:
assembly-descriptor.xml
<assembly>
<id>uberjar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>.</outputDirectory>
</fileSet>
</fileSets>
</assembly>
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-uberjar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptor>src/main/assemble/assembly-descriptor.xml</descriptor>
</configuration>
</execution>
</executions>
</plugin>
But unfortunately you can't use the Class-Path header in manifest.mf, see Adding Classes to the JAR File's Classpath:
Note: The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over Internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file called MyUtils.jar, you cannot use the Class-Path header in MyJar.jar's manifest to load classes in MyUtils.jar into the class path.
The solution proposed by Pascal Thivent defines a new assembly for the Maven assembly plugin. The Maven assembly plugin offers defaults assemblies which are 'bin', 'jar-with-dependencies', 'project' and 'src' producing various predefined bundles.
A new assembly has to be defined in a new xml file, most of the time located in src/assemble. Then it will be loaded instead of the predefined one, this way:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<!-- disabled predefined assembly -->
<!--
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
-->
<descriptors>
<descriptor>src/assemble/myAssembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>

How can I include unit tests in maven assembly?

Reason: Our project is using Ant as commandline interface. After making a new assembly with maven's assembly plugin, I want to make initial tests to see if all has been properly assembled. Therefore I need to include the unit tests in the final assembly. After assembling, the initial tests would then be called sth like
> ant initTest
build.xml:
<target="initTest">
<junit>
<test class="MyTest" />
</junit>
</target>
Problem is:
I want to keep my Unit tests in src/test/java and not move them to src/main/java.
Is there a way to tell the assembly plugin to include my unit tests? A simple include in the assembly descriptor does not do it ...
There are two steps:
Package the tests into a jar as well as the main code.
Depend on that "-tests" jar in the module that makes the assembly.
To package up the tests, you need to bin the jar:test-jar goal. e.g.
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>test-jar</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then in the assembly module, you can depend on the resulting artifact.
<dependencies>
<dependency>
<groupid>${project.groupId}</groupId>
<artifactId>some-artifact</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
</dependency>
</dependencies>
The key bit is the "classifier".
The answer from #Dominic-Mitchell did not work for me at all. What finally worked was adding a fileSet for the test classes to my assembly xml. Note that the fileSet directories are different! That stumped me for the longest time.
Use ${project.build.directory} for the test classes and ${project.build.outputDirectory} for the main:
<?xml version='1.0' encoding='UTF-8'?>
<assembly>
<id>toolbar-test</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<scope>runtime</scope>
<unpack>true</unpack>
<unpackOptions>
<excludes>
<exclude>**/LICENSE*</exclude>
<exclude>**/README*</exclude>
</excludes>
</unpackOptions>
</dependencySet>
<dependencySet>
<scope>test</scope>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
</assembly>
Credit where credit is due - I found this solution within this blog post here: http://alexgaddie.blogspot.com/2010/02/creating-uber-jar-with-maven.html
I did not need the profile part of the blog post.
The following works for us.
pom.xml snippet:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
assembly.xml snippet:
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<useProjectAttachments>true</useProjectAttachments>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
The key is the useProjectAttachments tag.