Question

I have a bundle component,

package ipojo;

import ipojo.service.Hello;

import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Invalidate;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Validate;


    @Component(name="hello-factory")
    @Provides
    public class HelloImpl implements Hello{

        @Override
        public void shoutHello() {

            System.out.println("HellooOOOOoooOooo!");

        }


        @Validate
        public void start() throws Exception {

            System.out.println("Hello started :)");

        }

        @Invalidate
        public void stop() throws Exception {

            System.out.println("Hello Stopped :(");

        }       

    }

In my java application, I embedded Apache Felix, and deployed iPOJO APIs. Then, I tried to create an instance of my above component using Factory Service, as the following:

    myBundle= context.installBundle("myBundlePath");
    myBundle.start();


    ServiceReference[] references = myBundle.getBundleContext().getServiceReferences(Factory.class.getName(), "(factory.name=hello-factory)");

    if (references == null) { 
    System.out.println("No references!");
    } 

    else {
    System.out.println(references[0].toString());
    Factory factory = myBundle.getBundleContext().getService(references[0]);
    ComponentInstance instance= factory.createComponentInstance(null);
    instance.start();

    }

I successfully got the reference to the factory service, but at the following line:

 Factory factory = myBundle.getBundleContext().getService(references[0]);

I get the following ClassCastException:

java.lang.ClassCastException: org.apache.felix.ipojo.ComponentFactory cannot be cast to org.apache.felix.ipojo.Factory`

I changed this line to:

Factory factory = (ComponentFactory) myBundle.getBundleContext().getService(references[0]);

then I got:

java.lang.ClassCastException: org.apache.felix.ipojo.ComponentFactory cannot be cast to org.apache.felix.ipojo.ComponentFactory

How can I solve my problem? Thank you.

Was it helpful?

Solution

When embedding Felix (or any other OSGi framework) you create a boundary between the classloaders. The host and the bundles are not using the same classloaders meaning that classes from inside and outside are not compatible. In other words, accessing OSGi services from the host is particularly complex and require using reflection.

For simplicity reasons, you should use the Factory service (and any other services) from a bundle and not from the host.

If you really need to use them from the host, you have to configure the OSGi framework to export all the required packages from bundle 0.

OTHER TIPS

This exception means that there are classpath problems, as there are multiple versions of libraries in the classpath.

A ClassCastException when a class cannot be cast to a class of the same name is caused by an attempt to cast classes accross classloaders: it's not possible to do so, see here.

The classloader which loaded the class makes part of the class unique identifier.

So two classes with the exact same name org.apache.felix.ipojo.ComponentFactory will not be the same if they where loaded in different classloaders.

You need to debug your classpath, find the unwanted version of the library containing that class and remove it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top