如何查看 Apache Felix Log 中未满足捆绑要求的原因?

How to see why bundle requirements are not fulfilled in Apache Felix Log?

我在嵌入式模式下使用 Felix,使用 File Install 捆绑包,并且有一个已安装但未解决的捆绑包(因此不是启动/活动),我比我想象的更挣扎在日志中找到根本原因...

您如何/从哪里获得那些有用的 "Unable to resolve ... because..." 或 "BundleException: Unresolved constraint in bundle ... Unable to resolve ... missing requirement ... osgi.wiring.package" 日志中的消息,自动从 Felix 框架 and/or 文件安装包?我没有看到类似的东西 - 我应该看到吗?在哪里?

我还添加了日志记录(通过 Apache Felix Log and osgi-loglistener-slf4j),但仍然是 nada - 在(嵌入式)Felix 中启用此类问题的日志记录是否需要比我做的更多?

然后我添加了 Felix Gogo Shell CLI,发现它的 inspect 命令也不是很有用(不适用于未解析的包),并且只有 start 会显示根本原因 - 但我怎样才能得到它来记录,而不必有控制台并开始:

g! lb  
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (5.6.1)|5.6.1
    1|Active     |    1|Apache Felix File Install (3.5.4)|3.5.4
    2|Active     |    1|Apache Felix Remote Shell (1.1.2)|1.1.2
    3|Active     |    1|Apache Felix Gogo Runtime (0.16.2)|0.16.2
    4|Active     |    1|Apache Felix Gogo Command (0.16.0)|0.16.0
    5|Active     |    1|Apache Felix Gogo Shell (0.12.0)|0.12.0
    6|Installed  |    1|osgi.testplugin (1.0.0.SNAPSHOT)|1.0.0.SNAPSHOT
g! inspect req * 6
Bundle 6 is not resolved.
g! start 6
org.osgi.framework.BundleException: Unable to resolve ch.vorburger.minecraft.osgi.testplugin [8](R 8.0): missing requirement [ch.vorburger.minecraft.osgi.testplugin [8](R 8.0)] osgi.wiring.package; (osgi.wiring.package=org.spongepowered.api.command) Unresolved requirements: [[ch.vorburger.minecraft.osgi.testplugin [8](R 8.0)] osgi.wiring.package; (osgi.wiring.package=org.spongepowered.api.command)]

我确实了解,由于 OSGi 的异步包初始化,何时记录失败的包启动可能并不明显,因为它可能必须等待相关包出现?在某种宽限期之后,它仍然不能..记录这种错误吗?

在找到 pax exam 选项来检查所有捆绑包是否已解决之前,我在测试中遇到了类似的问题。

我所做的是以编程方式遍历捆绑包列表并在每个未启动的捆绑包上调用 start。 bundle.start() 然后抛出异常,原因类似于上面的控制台命令。

不确定是否可以将 felix 设置为默认也记录此日志。

不确定这是最好的解决方案,但对我有帮助

import org.osgi.framework.*;

public class Activator implements BundleActivator, BundleListener {

    public void start(BundleContext context) {
        context.addBundleListener(this);
    }

    public void stop(BundleContext context) {
        context.removeBundleListener(this);
    }

    @Override
    public void bundleChanged(BundleEvent bundleEvent) {
        if (bundleEvent.getType() == BundleEvent.UNRESOLVED) {
            System.out.println("BUNDLE " + bundleEvent.getOrigin().getSymbolicName() + " UNRESOLVED");
        try{
            System.out.println("TRYING TO START " + bundleEvent.getOrigin().getSymbolicName() + " BUNDLE");
            bundleEvent.getOrigin().start();

        } catch (BundleException e) {
            e.printStackTrace();
        }

    }
}

}

并将激活器配置添加到 .bnd 文件

Bundle-ClassPath: .
Bundle-Activator: com.netcracker.webportal.framework.activator.Activator
Import-Package: org.osgi.framework