Hanno Fietz
Hanno Fietz

Reputation: 31380

How do I bundle multiple modules and 3rd-party JARs in a ZIP using Maven2?

I'm developing my application as a set of OSGi bundles using Maven 2. Some common functionality, such as logging, web server etc. is used from other OSGi bundles, for example, I'm using the OSGi version of Jetty.

I want to ship my application with all third-party bundles and an OSGi container included. I chose Apache Felix as my default container.

I'm quite new to Maven and I don't know how to write the POM file that does this and couldn't find a similar example in the Maven book. The core point seems to be that a multi-module project doesn't create an artifact of its own.

It does build and package my bundles into OSGI-compatible JAR files as it should (using the maven-bundle-plugin). Now I want it to wrap up the other stuff as well (which doesn't need to be built or anything, just pulled in and put into the package) and produce a ZIP file like this:

+-Archive Root
 |
 +- /bundles
  |
  +- my.bundle1.jar
  +- my.bundle2.jar
  +- 3rd.party.bundle1.jar
  +- 3rd.party.bundle2.jar
 +- /conf
  |
  +- ... some config files ...
 +- felix.jar

That way, my user can download the ZIP file, unpack it to a directory, say "MyApp", and then go

# > java -jar /path/to/MyApp/felix.jar

Some notes on details, if they matter:

Upvotes: 3

Views: 3540

Answers (2)

Rich Seller
Rich Seller

Reputation: 84038

In the doc you reference, there is a section titled Embedding dependencies that describes how the plugin resolves the Maven project dependencies and add them to the classpath and resources.

The plugin uses the instruction to transform the project dependencies into and clauses, which are then appended to the current set of instructions and passed onto BND. If you want the embedded dependencies to be at the start or middle of or then you can use {maven-dependencies}, which will automatically expand to the relevant clauses.

...

The plugin uses the instruction to transform the project dependencies into and clauses, which are then appended to the current set of instructions and passed onto BND. If you want the embedded dependencies to be at the start or middle of or then you can use {maven-dependencies}, which will automatically expand to the relevant clauses.

In the example below the {maven-dependencies} placeholder will be expanded to include the project dependencies that are scope runtime or compile into the Include-Resource and Bundle-Classpath elements.

<!-- embed all compile and runtime scope dependencies -->
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>

<Include-Resource>
  {maven-resources},{maven-dependencies}
</Include-Resource>

<Bundle-ClassPath>.,{maven-dependencies},some.jar</Bundle-ClassPath>

Normally the plugin only checks direct dependencies, but this can be changed to include the complete set of transitive dependencies with the following option:

<Embed-Transitive>true</Embed-Transitive>

If you want a dependency inlined instead of embedded add the inline=true. For example to inline all compile and runtime scoped dependencies use:

<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>

Upvotes: 2

Hanno Fietz
Hanno Fietz

Reputation: 31380

It took me a while (about half a day of doc reading) to realize that the rather simple answer I was looking for was:

Use Maven Assemblies.

They actually let you put together all kinds of archives from your project's artifacts and dependencies.

Upvotes: 2

Related Questions