1
votes

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.

2

2 Answers

2
votes

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.

0
votes

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