Felix OSGI嵌入式应用程序问题

时间:2016-06-03 17:40:56

标签: java osgi apache-felix embedded-osgi

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

所以我有三个maven项目

1)具有界面的maven项目。并导出此接口的包。 ---> ProjA。

2)实施项目 - > ProjB,另一个maven项目,它将ProjA作为maven依赖项导入,并使用具体类在其上实现接口。同样在这个项目中,我为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的一个错误。

2 个答案:

答案 0 :(得分:2)

ProjA位于主项目的类路径中(打开嵌入的OSGi容器),它也作为捆绑包安装到嵌入式OSGi容器中。解析ProjB后,它会连接到ProjA软件包,因此它实现了来自已安装的projA软件包的接口。

当您尝试转换结果对象时,您尝试转换为主项目的类路径上的接口。这是ProjB捆绑实现的另一个接口,因为它实现了projA bundle的接口。

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

答案 1 :(得分:0)

another way to solve this problem is using export tag in maven maven-bundle-plugin or manifest file

<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>

and did'nt forget

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