Maven + OSGi捆绑构建复杂性

时间:2016-06-27 11:34:14

标签: maven osgi osgi-bundle

我目前正在开发基于OSGi的应用程序(使用Felix)。在这个项目中,有一些捆绑包取决于其他捆绑包。在过去,我们使用Ant脚本来编译和构建所有内容,现在我们想要对此进行编组,但是任务根本不是微不足道的。

这是我的文件夹结构:

+-shared
 -- pom.xml 
 -- someProject
  --- pom.xml
 -- org.apache.felix
  --- pom.xml
 -- org.apache.activemq
  --- pom.xml
 -- org.apache.log4j
  --- pom.xml
 -- org.snake.yaml
  --- pom.xml
 -- ...

显然,根POM应该在这里构建所有内容,而单个POM只是简单地描述了这些包。我在每个包中也有MANIFEST.MF个文件(不是自动生成的)。我必须说,我们不希望从公共存储库获取内容,而是拥有我们自己的本地存储库。

现在,我使用maven-bundle-plugin这样的插件,我正在尝试自己这样做。但是我遇到了很多错误,这些错误大多是package does not exist错误。所以我怀疑我做错了什么。在论坛中四处看看之后,我注意到很多人一直在使用maven-bundle-plugin,所以我也开始考虑这样做了。然而,官方网站只能帮助我,直到某一点,然后我卡住了。

这么长的故事简短,我想要一个至少可以编译的功能pom.xml。它也可以自动生成MANIFEST.MF,会很好,但是,我不知道该怎么办。

到目前为止,我想出了pom.xmlsomeProject1):

<?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>shared</groupId>
      <artifactId>shared.master</artifactId>
      <relativePath>../pom.xml</relativePath>
      <version>1.0.0-SNAPSHOT</version>
   </parent>
   <groupId>shared</groupId>
   <artifactId>shared.cmd.felix</artifactId>
   <name>shared.cmd.felix</name>
   <version>1.0.0</version>
   <packaging>jar</packaging>
   <dependencies>
      <dependency>
         <groupId>shared</groupId>
         <artifactId>org.apache.felix</artifactId>
         <version>1.0.0</version>
         <scope>system</scope>
         <systemPath>${project.basedir}/../org.apache.felix/felix.jar</systemPath>
      </dependency>
      <dependency>
         <groupId>shared</groupId>
         <artifactId>org.apache.log4j</artifactId>
         <version>1.0.0</version>
         <scope>system</scope>
         <systemPath>${project.basedir}/../org.apache.log4j/log4j-1.2.17.jar</systemPath>
      </dependency>
   </dependencies>
   <build>
      <sourceDirectory>src/</sourceDirectory>
      <plugins>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
               <source>${jdk.version}</source>
               <target>${jdk.version}</target>
            </configuration>
         </plugin>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.1</version>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                     <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                  </manifest>
                  <manifestEntries>
                     <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                     <Bundle-Version>${project.version}</Bundle-Version>
                     <Bundle-ClassPath>.</Bundle-ClassPath>
                     <Export-Package>shared.cmd.felix</Export-Package>
                  </manifestEntries>
               </archive>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

pom.xml的{​​{1}}:

org.apache.felix

我的<?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>shared</groupId> <artifactId>shared.master</artifactId> <relativePath>../pom.xml</relativePath> <version>1.0.0-SNAPSHOT</version> </parent> <groupId>shared</groupId> <artifactId>org.apache.felix</artifactId> <name>org.apache.felix</name> <version>1.0.0</version> </project> 是:

MANIFEST.MF

然而,我得到的错误如下:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Shared Felix Console Extension
Bundle-SymbolicName: shared.cmd.felix
Bundle-Version: 1.0.0
Fragment-Host: shared.mw;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ClassPath: .,
 bundle/system/org.apache.felix.gogo.runtime-0.10.0.jar
Export-Package: shared.cmd.ext
Import-Package: shared,
 shared.cmd,
 shared.comp,
 shared.mw,
 shared.sched,
 shared.service,
 org.apache.felix.service.command,
 org.apache.log4j,
 org.osgi.framework
Require-Bundle: org.apache.felix;bundle-version="1.0.0",
 org.apache.activemq

现在,如果我想将其更改为可以使用maven-bundle-plugin的状态,那怎么可能呢?我想出了这个,但不知道这是否与我上面的相符:

[ERROR] /shared/shared.cmd.felix/src/shared/cmd/ext/ListScheduledTasks.java:[11,40] package org.apache.felix.service.command does not exist
[ERROR] /shared/shared.cmd.felix/src/shared/cmd/ext/ListScheduledTasks.java:[15,19] cannot find symbol

更重要的是,我需要在那里插入所有内容吗?我不能跳过其中一些,例如<project> <modelVersion>4.0.0</modelVersion> <groupId>shared</groupId> <artifactId>shared.cmd.felix</artifactId> <packaging>bundle</packaging> <name>shared.cmd.felix</name> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>org.apache.felix</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>${pom.groupId}</groupId> <artifactId>org.apache.log4j</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>${pom.groupId}</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Export-Package>--WHAT TO PUT HERE?--</Export-Package> <Private-Package>--WHAT TO PUT HERE?-</Private-Package> <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> <Bundle-Activator>--WHAT TO PUT HERE?-</Bundle-Activator> <Export-Service>--WHAT TO PUT HERE?-</Export-Service> </instructions> </configuration> </plugin> </plugins> </build> </project> ?我上面输入的本地路径发生了什么,为什么插件没有这些?它会自动找到它们吗?

有人可以帮我解决这个问题吗?我将不胜感激。

提前致谢。

2 个答案:

答案 0 :(得分:2)

假设您使用的是bnd-maven-plugin,则不会在bnd.bnd文件中添加依赖。您只能以标准Maven方式在pom.xml中添加它们。请遵循任何标准的Maven教程。

如果您从Java编译器收到有关未知软件包的错误,那么它只是意味着您错过了pom.xml中的构建依赖项。

鉴于您的出发点,我认为将项目作为普通的Java项目开始构建是最简单的......不要担心OSGi!这将确保您拥有所需的所有编译时依赖项,如果遇到困难,您还可以使用任何标准的Maven教程。

一旦你有一个实际构建的普通Java项目,那么你可以添加bnd-maven-plugin以便将你的JAR变成捆绑包。

完全披露:我是bnd-maven-plugin

的原作者

答案 1 :(得分:1)

手工完成所有包进口和出口非常困难。即使你实现它,代码也会非常脆弱,因为你必须适应所有的重构。如果你还想手工使用包,你就完全搞砸了。

我使用了maven-bundle-plugin以及bnd-maven-plugin。两者都很棒。如果您的项目设计得很好,那么您根本不需要太多配置。

tasklist-ds example显示了如何将其应用于完整的捆绑树。

我配置maven-bundle-plugin only in the parent pom。实际配置在导入的bnd.bnd个文件中完成。

你可以先将它们保持为空。然后查看生成的包。然后,您可以调整导入和导出,但尝试将这些特殊配置保持在最低限度。