更新2 :由于我的博客有点死,链接降级,所以你可以在这里查看文章:
我有一个maven项目,使用我的POM.XML中配置的非常有名的felix maven bundle插件,方法如下:
<packaging>bundle</packaging>
(...)
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Export-Package>jlifx.*</Export-Package>
<!-- <Embed-Dependency>*</Embed-Dependency> -->
</instructions>
</configuration>
</plugin>
然后我的POM中也包含了一些第一级/级别的依赖项:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha1</version>
</dependency>
</dependencies>
现在我的问题开始......如果我 mvn install 我会用我非常棒的MANIFEST.MF和我的所有内容完成我的捆绑,但我不会获取其他依赖项捆绑包,这意味着如果我抓取我的捆绑文件并将其放在我的OSGi框架实例上,我将得到类似&#34;无法解决1.0:缺少需求[1.0] osgi.wiring 。包; (&amp;(osgi.wiring.package = etc ...&#34;
所以我找到了一种方法来创建我的第一级依赖关系&#39;捆绑是通过在我的POM中创建一个配置文件,如下所示:
<profiles>
<!-- http://www.lucamasini.net/Home/osgi-with-felix/creating-osgi-bundles-of-your-maven-dependencies -->
<!-- -Pcreate-osgi-bundles-from-dependencies bundle:wrap -->
<profile>
<id>create-osgi-bundles-from-dependencies</id>
<build>
<directory>${basedir}/bundles</directory>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.0.1</version>
<extensions>true</extensions>
<executions>
<execution>
<id>wrap-my-dependency</id>
<goals>
<goal>wrap</goal>
</goals>
<configuration>
<wrapImportPackage>;</wrapImportPackage>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
这样当我执行 mvn -Pcreate-osgi-bundles-from-dependencies bundle:wrap 时,我将获得捆绑包,构造良好并且正常工作。但是,这是真正的交易。这些bundle也有自己的依赖关系,因此他们需要将它们的依赖关系作为bundle捆绑在一起。根据很多网页,很久以前我们有 mvn org.apache.felix:maven-bundle-plugin:bundleall 目标为我们做这件事,但是我已经尝试过,它是有缺陷的并且返回异常并将其标记为已弃用,根据Stuart的说法,它将在maven 2.4.1及更高版本中删除(参考:https://issues.apache.org/jira/browse/FELIX-4145)。
所以我现在唯一的解决方案是,手动,检查我的第一级依赖关系的每个清单,然后去google查找包含所需包的jar,将它们作为maven依赖项添加到我的POM.XML中,然后运行 mvn -Pcreate-osgi-bundles-from-dependencies bundle:wrap 将它们包装成捆绑包。
这就是所谓的依赖地狱......
有没有办法自动完成解决maven-bundle osgi项目的 nth 级别依赖关系的任务?即让maven学习我的第一级依赖关系&#39;清单文件,阅读导入包,查看提供此类软件包的jar的中央存储库,下载它们并将它们包装成捆绑包?
注意:请提供有关如何实现此目的的详细说明,请勿链接到此工具或可能解决此问题的工具。这些工具的主要问题是缺乏示例和文档。例如, bundleall 已被弃用,但似乎没有工具可以替换它,至少在他们的maven bundle插件的官方文档中,到目前为止已被弃用... 我确信我可能已经使用了能够做到这一点的工具,但缺乏文档禁止新手用户知道......
谢谢!
修改-1:
感谢您的答案到目前为止:) 我认为我没有以最恰当的方式解释我的情况,而且我只是通过纯文本感到有些困难。或者也许我不理解你的答案。我非常新鲜&#34; OSGi中我唯一的知识来自书籍(OSGi in Action等)和Google。
想象一下,我的包导入包A和B.但是包A导入包C,包B也导入包C.但现在C进口包装D,E,F和G.另一方面,包装D进口了大量其他包装,E,F和G也是如此。
我计算机中唯一的捆绑包是我自己的捆绑包以及提供包A和B的捆绑包,因为它们是我的第一级依赖项。但是,我没有任何其他必需的捆绑包,即使它们作为jars安装在我的JDK安装文件夹中,我也没有将它们作为捆绑包,我甚至不知道在哪里可以获得罐子包装它们(实际上我知道,但我想我不会)。
我希望构建工具能够运行类似于以下的算法:
1)转到我的捆绑MANIFEST.MF并阅读Import-Package字段。枚举所有必需的包及其resp。版本
2)在互联网上搜索我所需库的jar或包。
3)下载每一个并检查它们是否只是普通的jar或有一个有效的osgi清单文件(即它们是一个捆绑包)
3.1) 如果它们是捆绑,请将它们复制到我的捆绑包/文件夹。
3.2) 其他使用任何工具将jar包装成捆绑包并将捆绑包复制到我的捆绑包/文件夹。
4)现在,对于下载/创建的每个新捆绑包,重复步骤1),2),3)和4)。
我想要的最终结果是什么:我对其具有直接或间接依赖关系的每个库的包,以便我可以在我的OSGi Framework实例中即时安装它们,如felix或equinox。
我不想要的东西:
1)必须手动执行此操作,因为如果我尝试解决依赖关系的每个依赖关系,我可能会花费数小时或数天来收集和包装jar。
2)将所有依赖项嵌入到ubber / mega包中。根据我读过的几本书,这是一个不好的做法,单独维护每个依赖项更难,而且会破坏模块化。
注意:我的问题不在于将jar包装到一个包中的特定任务,而是关于递归到每个bundle的导入,即使它们需要从一个在线存储库,如maven的中心。
有没有办法自动执行此操作,或者我错过了一些关于OSGi的大事?如此之大,我永远不需要这样做,我要求的?
修改-2:
某些(如果不是全部)Import-Package依赖项可以在运行时解决。想象一下OSGi框架试图启动一个包,但不是显示错误消息&#34;无法解决8.0:缺少要求[8.0] osgi.wiring.package;&#34;它会在线搜索该软件包,下载并即时安装。生活会变得如此简单。
答案 0 :(得分:6)
如果你想包装不是捆绑的jar,但只需要将这些jar作为OSGi框架中的库包装,你可以用BND工具包装它。请参阅链接How to create/generate OSGi bundles from existing third-party jars?
但我可以看到你使用非常常见的库,而不是已经转换为osgi包。您可以在SpringSource Enterprise Bundle Repository中找到许多转换为包的库。
但是如果找不到任何未转换为良好OSGi包的库,则可以使用PAX-URL中的WRAP协议在OSGi框架中安装这些依赖项。要使用这些协议取决于您正在使用的OSGi框架,但是在默认情况下安装了karaf。例如,要从maven存储库安装库:
root@karaf> osgi:install -s 'wrap:mvn:commons-lang/commons-lang/2.4$Bundle-SymbolicName=commons-lang&Bundle-Version=2.4'
该指令将maven存储库中的commons-lang库安装到OSGi框架中,并将其包装为OSGi包,并在页面中显示标题。
对于自动安装依赖项,就像你在第二次编辑中说的那样,有几个解决方案,但是有点工作。自动捆绑到OSGi framewor有两个主要的解决方案,即“Felix OBR存储库”和“Felix Provisioning”捆绑包以及Equinox p2存储库。它们都有控制台命令来自动安装捆绑包和功能。问题是,实际上我找不到一个好的捆绑包公共存储库。您需要使用所有捆绑包构建自己的存储库。
如果使用maven-bundle-plugin,当您将工件安装到本地maven存储库时,插件会更新位于存储库根目录中的文件“repository.xml”,以反映捆绑包的要求和功能。该文件是OBR存储库文件。
答案 1 :(得分:3)
我想要的最终结果是:每个库的捆绑包 有直接或间接的依赖关系,所以我可以安装它们 在我的OSGi框架实例中即时运行,例如felix或equinox。
好的,如果我理解你的问题,你想要像maven-dependency-plugin这样的东西吗?
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/thridparty-libs</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>runtime</includeScope>
<excludeGroupIds>${project.groupId}</excludeGroupIds>
<excludeArtifactIds>...</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
如果你遇到问题,你有很多没有osgi-Manifest的依赖项,你应该检查它们是否在springource enterprise bundle repository http://ebr.springsource.com/repository/和apache-servicemix bundle {{3} (如我的评论所述)
答案 2 :(得分:3)
使用maven-bundle-plugin中的Conditional-Package递归内联JAR包中的所有必需包并激活标记true。
答案 3 :(得分:0)
尝试p2-maven-plugin它完全按照你所描述的从1到4进行描述。它实际上使用tycho来构建p2存储库,但你也可以使用它来收集和捆绑你的依赖项和传递依赖项。 我不是在这里写例子,因为在上面的链接中,每个思想都有很好的文档记录,以便于理解。
希望这会有所帮助
答案 4 :(得分:0)
此函数包括jar文件夹中的jar依赖项:OSGI-INF / lib /
在build.gradle中:
**
dependencies {
...dependencies
}
def bundleClassPath() {
def list = []
configurations.compile.each {
list += 'OSGI-INF/lib/' + it.name
}
return list.join(',')
}
def includeResource() {
def list = []
configurations.compile.each {
list += 'OSGI-INF/lib/' + it.name + "=" + it.path
}
return list.join(',')
}
bundle {
instructions << [
'Bundle-ClassPath' : bundleClassPath(),
'-includeresource' : includeResource()
]
}
**