Search code examples
osgiosgi-bundlejbossfuseblueprint-osgi

Importing a OSGi service that is a singleton bean (that has a factory method)


How do I import the exported OSGi service that's a Singleton bean?

I end up getting the Exception as follows:

Unable to start blueprint container for bundle opaClient
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to find a matching constructor on class com.opa.gateway.OPAGateway for arguments [] when instantiating bean opaGateway
    at org.apache.aries.blueprint.container.BeanRecipe.getInstance(BeanRecipe.java:336)

My Blueprint xml where the service is exported is as follows:

<bean id="opaGateway" class="com.opa.gateway.OPAGateway" factory-method="getInstance"/>
<service ref="opaGateway" interface="com.opa.gateway.IOPAGateway" />

And the service is referenced in another bundle as follows:

<reference interface="com.opa.gateway.OPAGateway" component-name="opaGateway" availability="mandatory" />

Is there a way to directly reference a singleton bean that's a OSGi service?


Solution

  • Yes, you can reference a singleton which is an OSGi service. Make sure (as @Balazs suggested) that your class has a static function/method getInstance() with no arguments.

    Have a look at the blueprint below. Hope it gives you a clue... (If you need the complete sample I can try to post it.

    <bean   id="opaGateway"
            class="org.test.OPAGateway" factory-method="getInstance">
    </bean>
    
    <bean id="opaClient"
          class="org.test.client.OPAClient"
            init-method="startup"
            destroy-method="shutdown">
    </bean>
    
    <service ref="opaGateway" interface="org.test.IOPAGateway" />
    
    
    <reference interface="org.test.IOPAGateway" availability="optional">
        <reference-listener bind-method="setOPAGateway"
                        unbind-method="unsetOPAGateway">
            <ref component-id="opaClient"/>
        </reference-listener>
    </reference>
    

    • bean opaGateway (org.test.OPAGateway). It is a class implementing org.test.IOPAGateway. It is instantiated by static method getInstance():

      public class OPAGateway implements IOPAGateway {
          private static OPAGateway instance = null;
      
          public static OPAGateway getInstance () {
              if(instance == null) {
                  instance = new OPAGateway();
              }
              return instance;
          }
      
          // A very simple method...
          @Override
          public String printMessage() {
              return "I AM AN OPAGATEWAY";
          }
      }
      
    • bean: opaClient: It is just a consumer or the class that references the opaGateway:

      public class OPAClient {
          public void setOPAGateway(IOPAGateway c) {
              if(c != null) {
                  System.out.println("Message: " + c.printMessage());
              }
          }
          public void unsetOPAGateway(IOPAGateway c) {
      
          }
      }
      
    • The reference-listener: Injects the instance of opaGateway in the opaClient using the bind/unbind-method.

    You can find more information here: http://www.ibm.com/developerworks/library/os-osgiblueprint/