【问题标题】:Maven + OSGi bundle build complicationMaven + OSGi 捆绑构建复杂性
【发布时间】:2016-06-27 11:34:13
【问题描述】:

我目前正在开发一个基于 OSGi 的应用程序(使用 Felix)。在这个项目中,有一些依赖于其他包的包。过去我们使用 Ant 脚本来编译和构建所有东西,现在我们想把它 mavenize 化,但是这个任务一点也不简单。

这是我的文件夹结构:

+-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 中的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

但是,我收到如下错误:

[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

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

<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>

更重要的是,我需要在那里插入所有内容吗?我不能跳过其中的一些吗,例如Export-Service?我在上面输入的本地路径发生了什么,为什么插件没有这些?它会自动找到它们吗?

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

提前致谢。

【问题讨论】:

  • 如果您刚开始,最好先开始(这在您的设置中可见),然后您可以从enroute.osgi.org 站点学习很多 OSGi 基础知识。在你掌握了基础知识之后,如果你还想设置一个 maven 项目,那就很容易了。

标签: maven osgi osgi-bundle


【解决方案1】:

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

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

考虑到您的出发点,我认为将您的项目构建为一个普通的 Java 项目是最容易的......现在完全不用担心 OSGi!这将确保您拥有所需的所有编译时依赖项,如果遇到困难,您可以再次使用任何标准的 Maven 教程。

一旦您有一个实际构建的纯 Java 项目,您就可以添加 bnd-maven-plugin 以将您的 JAR 转换为包。

完全披露:我是bnd-maven-plugin的原作者。

【讨论】:

    【解决方案2】:

    手工完成所有包的导入和导出非常困难。即使你实现了它,代码也会非常脆弱,因为你必须适应所有的重构。如果您还想手动执行 package uses 子句,那您就完蛋了。

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

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

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

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

    【讨论】:

    • 我刚刚看到您使用了 Bundle-ClassPath。只有当你真的需要在你的包中嵌入一些东西时才这样做。通常不需要。
    • 所以您的建议是利用该 Github 帐户中提供的项目,提出一个 .bnd 文件并将其作为参数传递到 pom.xml 中,我做对了吗?
    • 另外,您是如何知道 .bnd 文件中的内容的?比如,为什么org.hibernate.proxy被导入了,而org.apache.aries.jpa没有被导入,等等?
    • 通常不需要添加特殊的导入。 bnd 库从您的代码中计算出来。 org.hibernate.proxy 是一种特殊情况,因为 hibernate 在运行时增强了类。所以这个依赖在编译时是未知的。
    • 对于初学者来说似乎有点复杂。但是,据我了解,我必须使用 bnd-maven-pluginbnd.bnd 文件来构建它。我不知道放在这里做什么,比如依赖项,这是主要问题。在我自己的 pom.xml 中,这也是问题所在。我包括org.apache.felix,它仍然告诉我找不到org.apache.felix.service.command。我不知道如何确定什么应该是依赖项,什么不应该。
    猜你喜欢
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 2011-06-19
    相关资源
    最近更新 更多