关于Apache Felix Maven Bundle Plugin:能否用非OSGi依赖构建FATJar OSGi Bundle?
Absolutely! You can use non-OSGi dependencies to build a "fat" OSGi bundle with the Apache Felix Maven Bundle Plugin (BND). This is a super common use case when you need to package all your dependencies—including transitive ones—into a single OSGi JAR. Let me walk you through how to set this up:
Embed dependencies with the
Embed-Dependencydirective
This is the core setting that tells BND to pack specified dependencies directly into your bundle. For non-OSGi dependencies, you can use a wildcard to include all compile and runtime-scoped dependencies (skip test/provided ones that aren't needed at runtime):<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>Pull in transitive dependencies with
Embed-Transitive
To automatically include all transitive dependencies (no need to list each one manually), add this directive set totrue:<Embed-Transitive>true</Embed-Transitive>BND will handle resolving and embedding transitive dependencies even if they aren't OSGi bundles themselves.
Configure the bundle classpath
By default, embedded dependencies are placed in alib/folder inside your bundle. Make sure your bundle's classpath includes both its own classes and these embedded JARs:<Bundle-ClassPath>.,lib/</Bundle-ClassPath>The
.refers to the bundle's root classpath, whilelib/points to the embedded dependency JARs.Handle edge cases like conflicts or signed JARs
- If you hit duplicate class errors, exclude specific dependencies using
excludeGroupIdsorexcludeArtifactIds:<Embed-Dependency>*;scope=compile|runtime;excludeGroupIds=org.slf4j</Embed-Dependency> - If your dependencies are signed JARs, embedding them might break their signatures. You can either re-sign the final bundle, or use
inline=trueto embed the dependency's classes directly into your bundle's classpath (note: this increases bundle size and requires careful conflict management):<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
- If you hit duplicate class errors, exclude specific dependencies using
Example POM Configuration
Here's a complete snippet of how your Maven plugin setup might look:
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>5.1.9</version> <!-- Use the latest stable version --> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> <Bundle-Name>${project.name}</Bundle-Name> <!-- Optional: Add an activator if your bundle needs startup logic --> <!-- <Bundle-Activator>com.your.package.BundleActivator</Bundle-Activator> --> <!-- Embed all compile/runtime dependencies and their transitives --> <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <!-- Set the classpath to include root and embedded libs --> <Bundle-ClassPath>.,lib/</Bundle-ClassPath> </instructions> </configuration> </plugin> </plugins> </build>
Once you've set this up, run mvn clean install—you'll get a single OSGi bundle that includes all your non-OSGi dependencies and their transitives, ready to deploy to any OSGi container.
内容的提问来源于stack exchange,提问作者Sergio Rodríguez Calvo

