【问题标题】:Felix not starting bundle菲利克斯没有开始捆绑
【发布时间】:2019-06-01 23:44:13
【问题描述】:

无法将包加载到 felix。我下载了 Felix 6.0.1,使用

运行
> java -jar bin/felix.jar
____________________________
Welcome to Apache Felix Gogo

g! 

我在 Eclipse 中创建了一个 MavenProject TestA

  1. 我按照提供的方式向 felix (6.0.1) 添加了一个依赖项。
  2. 我在TestA/src/main/java/testa/impl/Activator.java 中创建了一个类。
  3. 我将testa.impl.Activator 类扩展为org.osgi.framework.BundleActivator
  4. 我覆盖public void start(BundleContext bc) throws Exception 以打印出Hello World!

这是java源码:

package testa.impl;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

    public void start(BundleContext arg0) throws Exception {
        System.out.println("Hello World!");
    }

    public void stop(BundleContext arg0) throws Exception {
        System.out.println("stop");
    }
}

这是我的pom.xml

<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>test</groupId>
    <artifactId>testa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.main</artifactId>
            <version>6.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <defaultGoal>clean install org.apache.felix:maven-bundle-plugin:bundle</defaultGoal>
    </build>
</project>

然后我使用 mvn 编译到 jar 并使用

g! install file:/C:/xxx/TestA/target/testa-0.0.1-SNAPSHOT.jar                              
Bundle ID: 20

然后我使用lb列出所有捆绑包

g! lb                                                                                                           15:51:56
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (6.0.1)|6.0.1
    1|Active     |    1|jansi (1.17.1)|1.17.1
    2|Active     |    1|JLine Bundle (3.7.0)|3.7.0
    3|Active     |    1|Apache Felix Bundle Repository (2.0.10)|2.0.10
    4|Active     |    1|Apache Felix Gogo Command (1.0.2)|1.0.2
    5|Active     |    1|Apache Felix Gogo JLine Shell (1.1.0)|1.1.0
    6|Active     |    1|Apache Felix Gogo Runtime (1.1.0)|1.1.0
   20|Installed  |    1|testa (0.0.1.SNAPSHOT)|0.0.1.SNAPSHOT
g!                                                                                                              

无论如何,我使用start 启动捆绑包:

g! start 20
g!

我预计会打印“Hello World”,但 什么都没有显示出来!

我现在很困惑,并尝试找出捆绑包是否真的开始了。

g! lb                                                                                                           15:51:56
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (6.0.1)|6.0.1
    1|Active     |    1|jansi (1.17.1)|1.17.1
    2|Active     |    1|JLine Bundle (3.7.0)|3.7.0
    3|Active     |    1|Apache Felix Bundle Repository (2.0.10)|2.0.10
    4|Active     |    1|Apache Felix Gogo Command (1.0.2)|1.0.2
    5|Active     |    1|Apache Felix Gogo JLine Shell (1.1.0)|1.1.0
    6|Active     |    1|Apache Felix Gogo Runtime (1.1.0)|1.1.0
   20|Active     |    1|testa (0.0.1.SNAPSHOT)|0.0.1.SNAPSHOT
g!                                                                                                              15:51:58

它已启动,但我的代码尚未执行。

问题

为什么控制台上没有打印Hello World

【问题讨论】:

  • 检查记录器配置
  • @jhamon 记录器配置正确。

标签: java maven osgi apache-felix


【解决方案1】:

Hello World 不会打印在控制台上,因为您创建的 jar 实际上并不是一个包。 奇怪的是,felix 允许您启动一个在清单中没有任何 OSGI 相关信息的 jar。 我不清楚启动这样的捆绑包意味着什么?也许这些课程会发布,也可能不会。

大多数 java 框架扫描 jar 中的文件并使用反射或字节码分析来查找相关类。 对于普通框架,扫描 jars 的开销只会在启动时产生一次。 OSGI 被设计为轻量级的,也可用于移动设备。 此外,由于在 OSGI 中捆绑可以来去去去,他们设计了一种更有效的方法。 OSGI 包将元数据存储在清单中。 这是一个简单的文本文件,始终位于同一位置(在 jar 中):“META-INF/MANIFEST.MF”。 如果您使用 zip 工具检查 jar 中的文件,您应该会看到如下内容:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Peter Rader
Build-Jdk: 1.8.0_111

对于未来的 OSGI 故障排除,我建议您检查(并发布)已创建的清单。

一个有效的 OSGI 清单看起来像这样:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Peter Rader
Build-Jdk: 1.8.0_111
Bundle-Name: testa
Bundle-SymbolicName: testa.impl
Bundle-Version: 1.0.0
Bundle-Activator: testa.impl.Activator
Import-Package: org.osgi.framework

当 felix 读取此清单时,它使用“Bundle-Activator”条目来查找激活器(如果有)。 替换manifest,bundle应该可以正常部署了。
只需在相对于 jar 的位置创建一个名为“META-INF/MANIFEST.MF”的文本文件,其中包含上述文本。 接下来将 jar 中的清单文件替换为以下 linux 命令(或您喜欢的 zip 工具):

zip testa-0.0.1-SNAPSHOT.jar -u META-INF/*

zip 命令的预期输出:

updating: META-INF/MANIFEST.MF (deflated 36%)

请务必使用 zip 文件打开 jar,并检查内容是否已更改。 现在,如果您安装并启动捆绑软件,它应该会打印“Hello World!”。

虽然这解决了问题,但它不是一个非常干净的解决方案。
jar 规范有一些相当奇怪的规则,关于清单中的条目应该如何格式化:
https://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Manifest_Specification
最值得注意的是:

No line may be longer than 72 bytes (not characters), in its UTF8-encoded form.
If a value would make the initial line longer than this, 
it should be continued on extra lines (each starting with a single SPACE).

因此,您不想手动编辑此文件。 正如其他人所说,您有多种自动生成 OSGI 清单的选项。 和以前一样,您可以检查生成的 jar 中的清单以验证它是否正确生成。

【讨论】:

  • TLDR,一个简单的mvn -DBundle-Activator=testa.impl.Activator 就可以解决问题
  • 是的,mvn -DBundle-Activator=testa.impl.Activator 成功了。
【解决方案2】:

您似乎在手动创建清单。您应该使用 bnd-maven-plugin 之类的工具来执行此操作。由于您手动创建了清单,因此它看起来是错误的。您不会导入您在代码中使用的包。即org.osgi.framework

此外,不要从其他人的代码中扩展激活器类,因为您通常无法导入他们的实现包。只需自己实现它:

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class TestA implements BundleActivator {

【讨论】:

  • 我相信实际的问题是简单地将META-INF/MANIFEST.MF 文件放在src/main/resources 下并不会使其成为JAR 文件的清单。 maven-jar-plugin 不能那样工作。正如 BJ 所说,您应该使用像 bnd-maven-plugin 这样的工具来生成清单,并阅读该插件的文档以确保生成的清单实际上被 maven-jar-plugin 使用。
猜你喜欢
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
  • 2012-01-08
  • 1970-01-01
  • 2023-01-07
  • 2014-05-26
  • 1970-01-01
相关资源
最近更新 更多