Felix OSGI Embedded 应用问题

Felix OSGI Embedded application issue

我将 Felix 用作嵌入式应用程序,如中所述, How to start and use Apache Felix from code?。我想要做的是通过 OSGi 从我的主机应用程序动态加载 jar 文件并调用实现方法 classes。

所以我有以下三个 Maven 项目

1) 一个有接口的maven项目。并且导出了这个接口的包。 ---> 项目。

2) 一个实施项目 --> ProjB,另一个 Maven 项目,它将 ProjA 作为 Maven 依赖项导入并使用具体 class 在其上实现接口。同样在这个项目中,我为 ProjA 接口包做了 OSGi import-package。同样在这里,我通过激活器在 OSGI 上注册了我的实现。

3) 然后是托管应用程序 ProjC。我在那里做的是,

    HostActivator activator = new HostActivator();
    List<Object> list = new LinkedList<Object>();
    list.add(activator);
    map.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
    Felix f = new Felix(map);
    f.start();

    Bundle a = f.getBundleContext().installBundle("file:C:/ProjA.jar"); 
    Bundle b = f.getBundleContext().installBundle("file:C:/ProjB.jar"); ); // dirty path ;)
    b.start();

    ServiceReference sr = activator.getContext().getAllServiceReferences(MyInterface.class.getName(), "(" + "osgi-device-name" + "=*)")[0];
    MyInterface dictionary =  (MyInterface) activator.getContext().getService(sr);
    dictionary.doAction();

投射前一切正常。在那里我可以看到以下错误,

Exception in thread "main" java.lang.ClassCastException: projB.MyImplementation cannot be cast to projA.MyInterface
    at MyHostApplication.MyMainClass.main(MyMainClass.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

任何人都可以帮助我解决这个问题,对我来说这似乎是 felix 上的一个错误。

ProjA 在您的主项目(打开嵌入式 OSGi 容器)的类路径中,它也作为一个包安装到嵌入式 OSGi 容器中。当 ProjB 被解析时,它连接到 ProjA 包,因此它实现来自已安装的 projA 包的接口。

当您尝试转换结果对象时,您尝试转换到主项目类路径上的接口。这是 ProjB 包实现的不同接口,因为它实现了 projA 包的接口。

您不应将 ProjA 作为捆绑包安装到 OSGi 容器中。您应该确保 ProjB 包可以解析。为此,您应该将 projA 作为系统包添加到嵌入式 OSGi 容器中。

另一种解决此问题的方法是在 maven maven-bundle-plugin 或清单文件中使用导出标记

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
                    <Export-Package>come.example.myInterface</Export-Package>
                    <Bundle-Activator>come.example.Activator</Bundle-Activator>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

并且没有忘记

map.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "come.example.myInterface; version=0.0.1");