Search code examples
javakarafblueprint

using a Java blueprint service defintion


I can't get the blueprint right for using a service locally. The OSGi server (karaf) displays GracePeriod and eventually a timeout waiting on ILookupMfgService.

If I remove the reference line the bundle starts and has an ILookupMfgService available.

Any suggestions on what I'm doing wrong?

Thanks for helping with my learning!

Timothy

<blueprint default-activation="eager" xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"

    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0 
            http://www.w3.org/2001/XMLSchema-instance http://www.w3.org/2001/XMLSchema-instance 
            http://aries.apache.org/xmlns/jpa/v1.0.0 http://aries.apache.org/xmlns/jpa/v1.0.0 
            http://aries.apache.org/xmlns/transactions/v1.0.0 http://aries.apache.org/xmlns/transactions/v1.0.0
            http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 ">

<!-- implemenation of the service -->
    <bean id="lookupMfgServiceStubImpl" class="com.services.jpa.LookupMfgServiceStub" scope="singleton"
        init-method="init" />

<!-- create a service with the implementation -->
    <service id="lookupMfgServiceStubLocal" ref="lookupMfgServiceStubImpl" interface="com.services.ILookupMfgService" />

<!-- create a reference for injecting into another bean - this line causes the GracePeriod / timeout --> 
    <reference id="lookupMfgServiceStubRef" interface="com.services.ILookupMfgService" availability="mandatory" ctivation="eager" />

    <bean id="EntityImpl" class="com.services.jpa.Entity" scope="singleton" init-method="init">
<!-- use the service - won't work without the reference above being valid -->
        <property name="lookupMfg" ref="lookupMfgServiceRef" />      
    </bean>
 </blueprint>

without reference line

karaf@root()> services -p 123

com.server.services (123) provides:
----------------------------------------
objectClass = [com.services.ILookupMfgService]
osgi.service.blueprint.compname = lookupMfgServiceStubImpl
service.id = 932
----

Solution

  • You must not declare a mandatory reference to service exposed in the same blueprint/bundle. The container gets confused because it wants to start a service with a reference to a service that is not yet there (himself) which results in an unrecoverable GracePeriod.

    A rough analogy of a reference is a Java Import from another package. The analogy of a service is a public class. You need the import (=reference) if you want to use a class from a different package.

    In your example you do not need the reference because you are within your bundle. You can reference your declared Bean directly instead:

    <!-- implemenation of the service -->
    <bean id="lookupMfgServiceStubImpl" class="com.services.jpa.LookupMfgServiceStub" scope="singleton"
        init-method="init" />
    
    <!-- create a service with the implementation -->
    <service id="lookupMfgServiceStubLocal" ref="lookupMfgServiceStubImpl" interface="com.services.ILookupMfgService" />
    
    <bean id="EntityImpl" class="com.services.jpa.Entity" scope="singleton" init-method="init">
    <!-- use the service - won't work without the reference above being valid -->
        <property name="lookupMfg" ref="lookupMfgServiceStubImpl" />      
    </bean>
    

    p.s. If no no other bundle needs your LookupMfgService then you can even leave out the service declaration.