Felix maven-bundle-plugin transitive dependency issue
I'm new to OSGI and trying to deploy my first application. I've a spring dependency in my pom. While deploying I realized that Felix runtime requires all transitive dependencies to install the bundle properly. Since then, I'm sort of struggling to resolve this issue. I've tried embedded-dependency and embedded-transitive options, but of no luck. Here's my 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>com.test</groupId>
<artifactId>taxonomydaobundle</artifactId>
<version>1.0.0</version>
<packaging>bundle</packaging>
<name>Taxonomy Dao Bundle</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>fusesource</id>
<url>http://repo.fusesource.com/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
<repository>
<id>apache-public</id>
<url>https://repository.apache.org/content/groups/public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<开发者_JAVA技巧;releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>taxonomymodelbundle</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.0.1</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.test.taxonomy.api.*;version=1.0.0
</Export-Package>
<Import-Package>com.test.taxonomy.message.*;version=1.0.0,
*
</Import-Package>
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Initially, I was trying mvn install but it was only including the direct dependencies and not the transitive ones. After reading the felix maven plugin documentation, I tried mvn org.apache.felix:maven-bundle-plugin:bundleall. But, the execution is failing as its not able to get the required jar files from the repository its using. Looking at the logs, I can see that it's referring to http://repo1.maven.org/maven2 repository which doesn't have the required versions. For e.g. this one is from hessian 3.1.3,among other ones.
[INFO] Unable to find resource 'hessian:hessian:pom:3.1.3' in repository central
(http://repo1.maven.org/maven2)
I'll appreciate if someone can share their experience in this regard.
-Thanks
In the OSGi environment the common way to deploy required libraries is to deploy them as own bundles. Embedding a library is an option that is most used (as I know) if the library is not OSGi enabled and does not matter for other bundles in the OSGi container.
So, if your bundle depends on other libraries you should first have a look, if these libraries are OSGi enbabled and install them as own bundles in the OSGi container.
If you use a library that is not OSGi enabled you can have a look to some places that offer OSGi enabled "wrapped" bundles of these libraries, e.g.
- http://www.springsource.com/repository
- http://repo.fusesource.com/
Spring is OSGi enabled - it should be possible for you to deploy these bundles on their own. I also recommend to have a look at Spring Dynamic Modules (documentation). If you build Spring enabled bundles you can also start with an OSGi Container that's already prepared with these bundles. I made good expirience with FUSE ESB (which is free (based on apache servicemix) OSGi container (and more) with commercial support).
So although I did not answer your concrete questions I shared some of my experience and hope that will help you. Good luck!
Run Maven with the -X option, which will get the bundle plugin to print what it thinks the dependency tree is
[DEBUG] Will bundle the following dependency tree
org.springframework:spring-remoting:jar:2.0.8:runtime
aopalliance:aopalliance:jar:1.0:compile
commons-httpclient:commons-httpclient:jar:3.0.1:compile
junit:junit:jar:3.8.1:compile
(commons-logging:commons-logging:jar:1.0.3:compile - omitted for conflict with 1.1)
commons-codec:commons-codec:jar:1.2:compile
commons-logging:commons-logging:jar:1.1:compile
log4j:log4j:jar:1.2.12:compile
logkit:logkit:jar:1.0.1:compile
avalon-framework:avalon-framework:jar:4.1.3:compile
(javax.servlet:servlet-api:jar:2.3:compile - omitted for conflict with 2.4)
hessian:hessian:jar:3.0.20:compile
Unfortunately you can not tweak your project's pom depdnencyManagement section to remove "optional" dependencies because maven-bundle-plugin is ignoring this.
According to FELIX-954 its pretty much going to visit all optional dependencies. The only advice I can offer is to find those optional artifacts and make sure Maven can resolve them.
There is a bug in the transitive dependencies management for the maven-bundle-plugin that causes it to look up optional dependencies (some of which may not exist). I suspect this is what is happening when it tries to pull in hessian.
I'll second K. Claszen's idea of looking for versions of your bundles on springsource or fusesource, but if there are bundles you cannot find, the maven-bundle-plugin provides a bundleall goal (it's described in the goals section). This goal will cause the bundle plugin to create bundles for all of the transitive dependencies of your application. You can then use the ones you couldn't find in springsource/fusesource. Once you've done this, you won't need to embed the jars into your bundle, which will make them available to other bundles as well.
One caveat that you may run into is the need to deploy the bundles such that no bundle is deployed before one of its dependencies. In the past, I have used the Eclipse Virgo server to get around this. It allows you to place all of your bundles in a repository and have the server determine the deployment order.
精彩评论