OSGi / blueprint中的服务引用无法正常工作

时间:2011-03-17 18:16:54

标签: java osgi blueprint

我目前有两个OSGi包(bundle1bundle2)都通过EBA中的蓝图公开服务。在bundle2的{​​{1}}中我想引用blueprint.xml中的服务并将注入它引入BuildService(下面的代码),因为BuildService将用于调用票务服务。然而,这会导致超时异常(也在下面)。似乎BuildService从未在OSGi中注册。我怎么做这样的工作?

bundle1

blueprint.xml

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

bundle2

BuildService的实现:

<?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>

启动应用程序服务器(Websphere)时,出现以下异常:

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;
    }


}

1 个答案:

答案 0 :(得分:5)

以下是解决方案:由于默认调用语义不同(本地传递引用与远程传值),OSGi应用程序运行时将远程服务与本地服务区别对待。为了防止应用程序意外调用仅为传值调用而设计的导出服务,它将从本地查找中隐藏。

解决方法是将相同的bean导出两次,一次用于远程调用,第二次用于本地。换句话说,您将添加具有相同配置但没有<service />属性的另一个service.exported.interfaces元素。

<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"/>

在websphere中实际上还有一个osgi控制台,它可以在[local websphere installation]/profiles/[profileName]/bin/osgiApplicationConsole.bat下找到。推出后,help()会为您提供一系列命令。要从SCA查看导入的服务,首先要连接到您的应用程序(例如connect(2),其中应用程序的编号在list()命令的结果中给出。然后,您可以services("(service.imported=true)")查看SCA添加的服务代理。命令services()将列出应用程序中的所有服务。