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

时间:2019-02-04 20:56:37

标签: java spring maven osgi osgi-bundle

有一种基于Spring的传统Java应用程序,它在容器中运行。我正在尝试通过将Apache Felix嵌入到此现有应用程序中来提供一些OSGi插件功能。我声明性地通过遵循以下步骤启动框架:

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

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

该捆绑包是通过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>

因此,如您所见,它不会导入任何内容(它是整个应用程序中唯一的包,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接口有两个实例:一个在捆绑包的类加载器中,另一个在框架的ModuleClassLoader中。至少我认为是这样。

人们通常如何解决这个问题?我尝试创建另一个捆绑包,该捆绑包仅导出框架以供初始捆绑包导入,但是启动时会遭受相同的错误。重构spring应用程序使其具有完整的OSGi功能是不可能的(这就是为什么我使用的是Felix而不是Equinox)。

2 个答案:

答案 0 :(得分:0)

捆绑包不得具有自己的OSGi Framework类的内部副本(即,包org.osgi.framework及其子包)。他们必须从系统捆绑包中导入那些软件包。

ClassCastException的原因是,在Java中,类的标识是其完全限定的名称和定义该类的ClassLoader的组合。如果您在多个ClassLoader中定义BundleActivator类型(当在包中包含其副本时会发生这种情况),那么它们将被视为不同的类型。

答案 1 :(得分:0)

尝试将依赖框架范围从 compile 更改为提供的