Managing multi-module dependencies with Maven assembly plugin - maven

I use Maven assembly plugin to create an assembly for my multi-module project. There are two separate applications built from this multi-module project, each having a separate set of dependencies. I made a custom assembly descriptor which assembles two directories (for each application) with module builds and their respective dependencies. It does everything fine but one thing - it puts dependencies for both modules to each other's assembly.
The following is a simplified version of my project, that has exactly the same behavior.
Consider a project consisting of two modules and an assembly module:
APP
module1
module2
assembly
I have added dependencies purely for demonstration:
com.test.app:module1:jar:1.0
\- commons-cli:commons-cli:jar:1.2:compile
com.test.app:module2:jar:1.0
\- commons-daemon:commons-daemon:jar:1.0.8:compile
Here's the parent POM:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>app</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>module1</module>
<module>module2</module>
<module>assembly</module>
</modules>
</project>
module1 POM:
<project>
<parent>
<groupId>com.test</groupId>
<artifactId>app</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.app</groupId>
<artifactId>module1</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
module2 POM:
<project>
<parent>
<groupId>com.test</groupId>
<artifactId>app</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.app</groupId>
<artifactId>module2</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>commons-daemon</groupId>
<artifactId>commons-daemon</artifactId>
<version>1.0.8</version>
</dependency>
</dependencies>
</project>
assembly POM:
<project>
<parent>
<groupId>com.test</groupId>
<artifactId>app</artifactId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.app</groupId>
<artifactId>assembly</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/descriptor.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>
And finally, the assembly descriptor:
<assembly>
<id>distribution</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>dir</format>
</formats>
<moduleSets>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>com.test.app:module1:jar</include>
</includes>
<binaries>
<outputDirectory>module1</outputDirectory>
<unpack>false</unpack>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</binaries>
</moduleSet>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>com.test.app:module2:jar</include>
</includes>
<binaries>
<outputDirectory>module2</outputDirectory>
<unpack>false</unpack>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</binaries>
</moduleSet>
</moduleSets>
</assembly>
As you can see, assembly is bind to package phase. So, when I execute
mvn package
from parent directory, I have the following assembly
module1/
commons-cli-1.2.jar
commons-daemon-1.0.8.jar
module1-1.0.jar
module2/
commons-cli-1.2.jar
commons-daemon-1.0.8.jar
module2-1.0.jar
Basically, the problem here is that module1 does not depend on commons-daemon, but the assembly plugin has included the dependence. Similarly, with module2 and commons-cli.
Can someone explain why the assembly plugin behaves this way?
An what would be a solution?

I've always had similar experiences using the assembly plugin with multi-module projects where the end result wasn't what I expected. I hope someone else can provide a more accurate answer as to why that's happening and how best to use those two concepts in tandem.
That said, a possible work-around would be to have module1 and module2 generate their own assembly artifacts which contain their respective jars and dependencies. Then you can modify the assembly sub-module pom file to have dependencies on the generated distribution artifacts from its sibling modules and then unpack those into a new assembly.
In both Module1 and Module2's pom files you can add an assembly plugin configuration to your package phase much like you did with the assembly sub-module.
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>src/main/assembly/descriptor.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
Module1 would have a src/main/assembly/descriptor.xml like this
<assembly>
<id>distribution</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>module1</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</assembly>
And Module2 will have a similar src/main/assembly/descriptor.xml
<assembly>
<id>distribution</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>module2</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</assembly>
Then in the assembly/pom.xml you would add the Module 1 and 2 zip artifacts as dependencies
<dependencies>
<dependency>
<groupId>com.test.app</groupId>
<artifactId>module1</artifactId>
<version>1.0</version>
<type>zip</type>
<classifier>distribution</classifier>
</dependency>
<dependency>
<groupId>com.test.app</groupId>
<artifactId>module2</artifactId>
<version>1.0</version>
<type>zip</type>
<classifier>distribution</classifier>
</dependency>
</dependencies>
...and trim up the assembly/src/main/assembly/descriptor.xml file to look like this
<assembly>
<id>distribution</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>dir</format>
</formats>
<dependencySets>
<dependencySet>
<useTransitiveDependencies>false</useTransitiveDependencies>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
</assembly>
Like I said this would be one possible work around and unfortunately adds a significant amount of additional XML configuration to your build process. But it works.

Related

How to package multi module in a zip file?

I have a multi module project.
Each module is packaged in a jar/war file in his own /target folder.
I want to take every module jar/war files and some config files, and put everything in a zip.
How to do that? I try with assembly plugin, but all i've managed to do so far is a zip of each module in their respective /target folder, so pretty useless ^^
First is to create a separate module let us call it dist add to the parent as new module and add all modules which you like to see in the resulting zip file as dependencies including the type war, jaretc.
The <packaging>pom</packaging> should be given cause this module does not contain any java code which needed to be compiled etc. We only want to create zip file which contains the given dependencies.
<project ..>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>module-1</groupId>
<artifactId>module-1-artifact</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>module-2</groupId>
<artifactId>module-2-artifact</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-bundles</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>proj1-assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Add the following descriptor:
<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>dist-assembly</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</assembly>
The dependencies are needed to be sure the order of execution is correctly calculated by Maven.
If you need supplemental configuration in that zip file you can add those files into src/main/config for example and add fileSets parts in the assembly descriptor.

How to copy all maven dependencies when packaging using assembly file?

I have a project A that has some dependencies in its POM.
A has a parent project B and a grand-parent project C.
When packaging A, using an assembly file, I'd like to put all necessary dependencies for A inside a directory in the packaged project.
Currently the I can only package the dependencies that are in A's POM.
I didn't find a way to package B's and C's dependencies that are necessary to A.
Do you know how I could do that?
Here's the assembly XML:
<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>bundle</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<!--Include runtime dependencies-->
<outputDirectory>${ser.depdir}</outputDirectory>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<!--Get the generated application jar-->
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<!--Get application resources-->
<directory>src/main/resources</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>*.properties</include>
<include>*.sh</include>
<include>log4j2.xml</include>
</includes>
</fileSet>
<fileSet>
<!--Get misc user files-->
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
And A's 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>
<parent>
<groupId>group</groupId>
<artifactId>ser</artifactId>
<version>1.0.6-SNAPSHOT</version>
</parent>
<artifactId>ser-art</artifactId>
<name>SER ART</name>
<description>desc</description>
<properties>
<ser.depdir>${project.artifactId}-dependencies</ser.depdir>
</properties>
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>../config/test</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>mainClass</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>${ser.depdir}/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>./conf/</Class-Path>
</manifestEntries>
</archive>
<excludes>
<exclude>*.properties</exclude>
<exclude>*.sh</exclude>
<exclude>log4j2.xml</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${ser.depdir}</outputDirectory>
<includeScope>runtime</includeScope>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>group</groupId>
<artifactId>ser-commons</artifactId>
<version>1.0.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>group</groupId>
<artifactId>utilities-lib</artifactId>
<version>1.0.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
A workaround from top of my head could be that you use "maven dependency plugin" copy phase to copy everything to a certain dir and then using "fileset" descriptor of assembly pluging. But this will make your pom look dirty.
I have not tried but assembly plugin supports the packaging of transitive dependency. That is the correct solution in your case.

How to get the content of a directory inside of WAR that is inside of an EAR that is inside of a ZIP?

I have the following :
WAR1 that has /images directory that contains : photo1.png, photo2.png
WAR2 that has /images directory that contains : photo2.png, photo3.png
WAR3 that has /images directory that contains : photo4.png, photo5.png
EAR1 that has WAR1 and WAR2
EAR2 that has WAR3
ZIP file that created by the Maven Assembly plugin that contains EAR1 and EAR2.
Now I need the following :
While creating the ZIP file by the Maven Assembly plugin, I need to create the directory /images inside of the ZIP file that contains the content of /images directory of every WAR file that is in the EAR that is in the ZIP.
Please, if not clear let me know guys, so I would give more details.
Thank you so much.
The first step is to create a separate module like mod-zip which contains the following pom which has dependencies to all the artifacts and the configuration for maven-assembly-plugin.
You have to change the parent to your parent approriately:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.soebes.maven.multiple.artifacts</groupId>
<artifactId>parent</artifactId>
<version>1.0.4-SNAPSHOT</version>
</parent>
<artifactId>mod-zip</artifactId>
<packaging>pom</packaging>
<name>Mod: ZIP</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mod-war1</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mod-war2</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mod-war3</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mod-ear1</artifactId>
<version>${project.version}</version>
<type>ear</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mod-ear2</artifactId>
<version>${project.version}</version>
<type>ear</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>test</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>test.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Second you need an assembly descriptor which describes what you like to have which is a little bit tricky:
<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>test</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<useProjectArtifact>false</useProjectArtifact>
<includes>
<include>${project.groupId}:*:war:${project.version}</include>
</includes>
<unpackOptions>
<includes>
<include>images/**</include>
</includes>
</unpackOptions>
</dependencySet>
</dependencySets>
<moduleSets>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<includes>
<include>${project.groupId}:*:ear:${project.version}</include>
</includes>
<binaries>
<outputDirectory>result</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
</assembly>
The tricky things is to go via two steps. First filter the artifacts having only the wars with the dependencySets and the unpackOptions which will filter out the images from them. And second you need to use the EAR modules by using the moduleSets.

maven: how to export packed sources with jar in "package" stage

I have a maven export script (that wasn't been written by me) and I would like to add sources coping as well.
the build script generates 2 outputs using the "maven-source-plugin":
.jar and -sources.jar and they are both exist in the same output folder one next to another.
so far only the jar is being copied, I want the script to place the -sources.jar file next to its jar file
the build pom:
<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>org.mytest</groupId>
<artifactId>my-parent</artifactId>
<version>6.0.00-SNAPSHOT</version>
<packaging>pom</packaging>
<name>my-parent</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<assembly.format>dir</assembly.format>
<my.repository.rootUrl>http://maven.my.com</my.repository.rootUrl>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
.
.
.
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<target>1.6</target>
<source>1.6</source>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<modules>
.
.
.
</modules>
<repositories>
.
.
.
</repositories>
<distributionManagement>
.
.
.
</distributionManagement>
<pluginRepositories>
.
.
.
</pluginRepositories>
<organization>
<name>My</name>
</organization>
<profiles>
<profile>
<id>dist</id>
<modules>
<module>../my-assembly/my-runner</module>
</modules>
</profile>
</profiles>
</project>
the export pom:
<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>org.mytest</groupId>
<artifactId>my-parent</artifactId>
<version>6.0.00-SNAPSHOT</version>
<relativePath>../../my-parent</relativePath>
</parent>
<artifactId>my-runner</artifactId>
<dependencies>
.
.
.
</dependencies>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<goals>
<goal>single</goal>
</goals>
<id>create-runner</id>
<phase>package</phase>
<configuration>
<finalName>runner</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/runner.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
the runner file (referenced by the export 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">
<formats>
<format>tar.gz</format>
<format>zip</format>
<format>dir</format>
</formats>
<id>runner</id>
<dependencySets>
.
.
.
<dependencySet>
<outputDirectory>lib</outputDirectory>
<outputFileNameMapping>${artifact.artifactId}.${artifact.extension} </outputFileNameMapping>
<includes>
<include>org.mytest:*:jar</include>
<include>org.mytest.systemobjects:*:jar</include>
</includes>
<excludes>
<exclude>*:my-services-so:*</exclude>
<exclude>*:my-services-tests:*</exclude>
<exclude>*:my-runner:*</exclude>
</excludes>
</dependencySet>
</dependencySets>
<fileSets>
.
.
.
</fileSets>
</assembly>
thank you in advance!
From looking at MNG-1994 it seems that in each phase a child's plugins will execute before the parent's.
Your parent POM specifies the source plugin (which generates the sources JAR) in the package phase (this is the source plugin's default phase if not explicitly specified in the execution), but the assembly plugin, which generates the tar.gz, zip and uncompressed finished versions of your project, is run before the source plugin because the assembly plugin is declared in the child and the source plugin is declared in the parent.
A solution can be to change the phase the source plugin runs in to ensure it runs before the assembly plugin, something right before the package phase such as prepare-package will work. (full list of lifecycle phases is here)
In the parent, explicitly setting the phase to prepare-package will make it:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>prepare-package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
This should force the source plugin to execute before the assembly plugin and therefore the assembly plugin should pick up both attached JARs now.
Add another include element with the classifier sources:
<include>org.mytest:*:jar:sources</include>
See the documentation: http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_dependencySet

Maven how to aggregate source from project depedencies

I use maven-bundle-plugin to create osgi plugin from non osgi depedency and I want to include the source from this depedency into the projet build.
This is an example I create an OSGI bundle from jfreechart and when I publish it I want to include jfreechart sources.
<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>org.jfree.chart</groupId>
<artifactId>com.netappsid.org.jfree.chart</artifactId>
<version>1.0.13</version>
<name>JFreeChart OSGI</name>
<packaging>bundle</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>org.jfree.chart.*;org.jfree.data.*</Export-Package>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Embed-Dependency>jfreechart;inline=true</Embed-Dependency>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jfree</groupId>
<artifactId>com.springsource.org.jfree</artifactId>
<version>1.0.12</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>com.springsource.javax.servlet</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
</project>
I had the same issue. Here's what I ended up doing:
unpack the sources using the maven-dependency-plugin
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-sources</id>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/sources</outputDirectory>
<artifactItems>
<artifactItem>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
<classifier>sources</classifier>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
attach a sources artifact built with the maven-assembly-plugin
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>source-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
with the following descriptor (note that the descriptor id is used as the classifier ; the artifact is attached by default):
<?xml version="1.0"?>
<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>sources</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>jar</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/sources</directory>
<outputDirectory>/</outputDirectory>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
If I understand you correctly...
I've had to package many osgi-less JARs myself for use in an OSGi application. When using the maven-bundle-plugin, if you are using Export-Package in the manifest (or osgi.bnd file) then its classes will be included in the created bundle.
Example:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: ACME PostgreSQL Driver Bundle
Bundle-SymbolicName: com.acme.org.postgresql
Bundle-Version: 9.0.801.jdbc4
# NB: I've imported a little too much for what is required.
Import-Package: org.postgresql*;version="9.0-801.jdbc4", \
javax*, \
org.w3c.dom, \
!org.ietf.jgss, \
!org.dom.xml.views
Export-Package: org.postgresql*;version="9.0-801.jdbc4"
Private-Package: org.w3c.dom*, org.xml*, javax*
Here, the exported packages will be included in the JAR from my Maven dependencies in the POM.
If you also want to include the dependency JAR, then you can use Embed-Dependency:
Embed-Dependency: org.postgresql*;version="9.0-801.jdbc4"
Embed-Transitive: true
If this what you were looking for?
Tony

Resources