4

I currently have two OSGi bundles (bundle1 and bundle2) both both exposing services through a blueprint in an EBA. In bundle2's blueprint.xml i want to reference a service from bundle1 and Inject it into the BuildService (code below), as BuildService will be used to call TicketService. This however results in a Timeout exception (also below). It seems like the BuildService never gets registered with OSGi. How would I make something like this work?

blueprint.xml for bundle1:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:bptx="http://aries.apache.org/xmlns/transactions/v1.0.0">

    <bean id="TicketServiceBean" class="com.example.b2.impl.TicketServiceImpl">
        <bptx:transaction value="Required" method="*" />
    </bean>

        <service ranking="0" id="TicketService" interface="com.example.b2.service.TicketService" ref="TicketServiceBean">
        <service-properties>
            <entry key="service.exported.interfaces" value="*" />
        </service-properties>
    </service>  

</blueprint>

blueprint.xml for bundle2

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

    <bean 
        id="BuildServiceImplBean"
        class="com.example.b1.impl.BuildServiceImpl" 
        activation="eager" >
        <property name="ticketService" ref="TicketServiceRef" />
    </bean>  


    <service    
        id="BuildService" 
        ref="BuildServiceImplBean"
        interface="com.example.b1.service.BuildService"
        activation="eager"> 

        <service-properties>
            <entry key="service.exported.interfaces" value="*" />
        </service-properties>

    </service>



    <reference 
        id="TicketServiceRef" 
        interface="com.example.b2.service.TicketService" 
        availability="mandatory"
        activation="eager" />


</blueprint>

Implementation of the BuildService:

public class BuildServiceImpl implements BuildService {

    private TicketService ticketService;

    @Override
    public TicketBuildResponse ticketBuild(TicketBuildRequest ticketBuildRequest) throws BuildServiceException {

        //do stuff here
    }



    public TicketService getTicketService() {
        return ticketService;
    }

    public void setTicketService(TicketService ticketService) {
        this.ticketService = ticketService;
    }


}

When starting up the application server (Websphere) I get the following exception:

  BlueprintCont E org.apache.aries.blueprint.container.BlueprintContainerImpl$1 run Unable to start blueprint container for bundle com.example.b1.module due to unresolved dependencies [(objectClass=com.example.b2.service.TicketService)]
                                     java.util.concurrent.TimeoutException
        at org.apache.aries.blueprint.container.BlueprintContainerImpl$1.run(BlueprintContainerImpl.java:273)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:453)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:315)
        at java.util.concurrent.FutureTask.run(FutureTask.java:150)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:207)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:736)
stuff22
  • 1,662
  • 4
  • 24
  • 42
  • Does Websphere give you access to an OSGi console so you can list what bundles are deployed? Also how are you deploying your bundles? In a WAB? – rancidfishbreath Mar 17 '11 at 20:13
  • The application is deployed in an EBA. Websphere does have a console where you can look at the artifacts you have deployed, but it only lets you view the eba, and not drill down into what it contains. There is also a Servers tab in RAD under which you can see what is deployed on that server instance. All there looks fine, and it seems like the application with all its bundles are deployed correctly. – stuff22 Mar 17 '11 at 20:42
  • Again if you are able to access the OSGi console you could run the "services" command to see whether the service is registered or not. If it IS registered but bundle2 still doesn't pick it up then you may have an interface compatibility problem... make sure that there is just one copy of the TicketService interface and both bundle1 and bundle2 import it from the same place. – Neil Bartlett Mar 18 '11 at 02:50

1 Answers1

5

Here is the solution: The OSGi applications runtime treats remote services differently from local ones, because of the different default invocation semantics (local pass-by-reference versus remote pass-by-value). To prevent an application accidentally calling an exported service that is only designed for pass-by-value calls, it is hidden from local lookups.

The solution to this is to export the same bean twice, once for remote calls, and the second for local. In other words, you would add another <service /> element with the same configuration, but without the service.exported.interfaces property.

<service ranking="0" id="TicketServiceExport" interface="com.example.b2.service.TicketService" ref="TicketServiceBean">
    <service-properties>
        <entry key="service.exported.interfaces" value="*" />
    </service-properties>
</service>  

<service ranking="0" id="TicketService" interface="com.example.b2.service.TicketService" ref="TicketServiceBean"/>

There is actually also an osgi console in websphere and it can be found under [local websphere installation]/profiles/[profileName]/bin/osgiApplicationConsole.bat. Once lauched, help() gives you a list of commands. To see your imported services from SCA, you first connect to your application (e.g. connect(2), where the number of the application is given in the results of the list() command). You can then do services("(service.imported=true)") to see the service proxies that have been added by SCA . The command services() will list all the services in the application.

Thomas Francois
  • 866
  • 6
  • 21
stuff22
  • 1,662
  • 4
  • 24
  • 42