Felix OSGI Embedded application issue

泄露秘密 提交于 2019-12-11 08:18:16

问题


I was using Felix as a embedded application as explained in, How to start and use Apache Felix from code?. What I want to do is dynamically load jar files from my host application via OSGi and invoke methods of implementation classes.

So I have following three maven projects

1) A maven project which has an interface. And the package of this interface is exported. ---> ProjA .

2) A implementation project --> ProjB, another maven project which import ProjA as a maven dependency and implement interface on it with a concrete class. Also in this project I do OSGi import-package for ProjA interface package. Also here I register my implementation on OSGI via activator.

3) Then ProjC which is the hosted application. What I do there is,

    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();

Everything works fine until cast. There I can see following error,

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)

Can anyone help me on this, for me this seems like a bug on felix.


回答1:


ProjA is on the classpath of your main project (that opens the embedded OSGi container) and it is also installed into the embedded OSGi container as a bundle. When ProjB is resolved, it wires to the ProjA bundle, so it implements the interface that is coming from the installed projA bundle.

When you try to cast the result object, you try to cast to the interface that is on the classpath of the main project. That is a different interface that the ProjB bundle implements as it implements the interface from projA bundle.

You should not install ProjA as a bundle into the OSGi container. You should be sure that ProjB bundle can resolve. To do that, you should add projA as a system package to the embedded OSGi container.




回答2:


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");


来源:https://stackoverflow.com/questions/37620492/felix-osgi-embedded-application-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!