声明性地启动OSGi包时“无法转换为org.osgi.framework.BundleActivator”

问题描述 投票:0回答:2

有一种在容器内运行的基于Spring的传统Java应用程序。我试图通过在这个已经存在的应用程序中嵌入Apache Felix来提供一些OSGi插件功能。我通过以下方式声明性地启动框架:

https://dotcms.com/blog/post/navigating-osgi-extending-your-software-to-embed-an-osgi-framework

如果链接不起作用,我正在做的是将Felix作为maven依赖项导入,使用ServiceLoader获取对框架工厂的引用,启动框架,以及加载/启动特定目录中的所有bundle。

该捆绑包是通过Felix Bundle插件创建的,具有以下配置:

            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Export-Package>com.example</Export-Package>
                    <Import-Package>!*</Import-Package>
                    <Bundle-Name>${project.description}</Bundle-Name>
                    <Bundle-Activator>com.example.Activator</Bundle-Activator>
                    <Embed-Transitive>true</Embed-Transitive>
                </instructions>
            </configuration>

至于依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.felix</groupId>
        <artifactId>org.apache.felix.framework</artifactId>
        <version>6.0.1</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

正如您所看到的,它不会导入任何内容(它是整个应用程序中唯一的bundle,servlet本身不是OSGi包)。由于应用程序不是OSGi包,我无法从中导出框架类,因此必须将Felix嵌入到包本身中。

我无法启动捆绑包。这就是我得到的(stacktrace已被编辑了一点):

14:43:52,981 ERROR [con.example.Plugin] (Initialization Thread) Failed to start bundle com.example: org.osgi.framework.BundleException: Activator start error in bundle com.example.Plugin[2].
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2448)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2304)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)

Caused by: java.lang.ClassCastException: com.example.Activator cannot be cast to org.osgi.framework.BundleActivator
    at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4744)
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2379)
    ... 35 more

我已经设法将这个减少到可能的事实,即BundleActivator接口有两个实例:一个在bundle的类加载器中,另一个在Frameworks的ModuleClassLoader中。至少我认为这是正在发生的事情。

人们通常如何解决这个问题?我已经尝试创建另一个捆绑包,只导出要导入的初始捆绑包的框架,但是它在启动时会遇到相同的错误。将spring应用程序重构为整体OSGi能力是不可能的(这就是为什么我使用的是Felix而不是Equinox)。

java spring maven osgi osgi-bundle
2个回答
0
投票

Bundles不得拥有自己的OSGi Framework类的内部副本(即包org.osgi.framework及其子包)。他们必须从System Bundle导入这些包。

ClassCastException的原因是在Java中,类的标识是其完全限定名称和定义它的ClassLoader的组合。如果你在多个ClassLoader中定义BundleActivator类型 - 当你在bundle中有它的副本时会发生这种情况 - 那么它们被认为是不同的类型。


0
投票

尝试将依赖框架范围从编译更改为提供

© www.soinside.com 2019 - 2024. All rights reserved.