0

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.

2 Answers2

1

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.

Clement
  • 2,817
  • 1
  • 12
  • 11
  • thanks Clement. What do you mean by bundle 0? Do you mean exporting the packages in my host app using Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA ? – user3243330 Jan 29 '14 at 09:52
  • moving my code to OSGI bundle worked for me. But I am interested in using it from my host. Therefore, what to export exactly? and Why this solution would work? – user3243330 Jan 29 '14 at 10:16
  • Using the above solution. In my host, I set Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA to all ipojo packages that can be found on earth. Yet, I get the same error. java.lang.ClassCastException: org.apache.felix.ipojo.ComponentFactory cannot be cast to org.apache.felix.ipojo.Factory` – Traveling Salesman Feb 06 '14 at 12:06
0

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.

Community
  • 1
  • 1
Angular University
  • 42,341
  • 15
  • 74
  • 81
  • my classpath seems clean. I only have felix.jar, and org.apache.felix.ipojo-1.6.0.jar as libraries. What else the problem could be? – user3243330 Jan 29 '14 at 06:20
  • Have a look at class identity crisis http://www.ibm.com/developerworks/java/library/j-dyn0429/ and debug the classpath looking for two jars containing ComponentFactory. There are two versions of ComponentFactory somewhere for sure, as it's the only explanation for the last ClassCastException you show, hope this helps. – Angular University Jan 29 '14 at 07:46