Java OSGi/blueprint中的服务引用工作不正常

Java OSGi/blueprint中的服务引用工作不正常,java,osgi,blueprint,Java,Osgi,Blueprint,我目前有两个OSGi捆绑包(bundle1和bundle2),都是通过EBA中的蓝图公开服务的。在bundle2的blueprint.xml中,我想引用bundle1中的服务,并将其注入到BuildService(下面的代码),因为BuildService将用于调用TicketService。但是,这会导致超时异常(如下所示)。BuildService似乎从未向OSGi注册过。我怎样才能做出这样的作品 blueprint.xml对于bundle1: <?xml version="1.0"

我目前有两个OSGi捆绑包(
bundle1
bundle2
),都是通过EBA中的蓝图公开服务的。在
bundle2
blueprint.xml
中,我想引用
bundle1
中的服务,并将其注入到BuildService(下面的代码),因为BuildService将用于调用TicketService。但是,这会导致超时异常(如下所示)。BuildService似乎从未向OSGi注册过。我怎样才能做出这样的作品

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


}
启动应用程序服务器(Websphere)时,我遇到以下异常:

  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)

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

解决方案是导出同一个bean两次,一次用于远程调用,第二次用于本地调用。换句话说,您将添加另一个具有相同配置的
元素,但没有
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控制台,可以在
[本地websphere安装]/profiles/[profileName]/bin/osgiapplicationsole.bat
下找到。启动后,
help()
将为您提供命令列表。要查看从SCA导入的服务,首先连接到应用程序(例如,
connect(2)
,其中应用程序的编号在
list()
命令的结果中给出)。然后可以执行
services(((service.imported=true)
以查看SCA添加的服务代理。命令
services()
将列出应用程序中的所有服务。

Websphere是否允许您访问OSGi控制台,以便您可以列出部署的捆绑包?另外,您如何部署捆绑包?在WAB?中,应用程序部署在EBA中。Websphere确实有一个控制台,您可以在其中查看已部署的工件,但它只允许您查看eba,而不允许深入查看它包含的内容。RAD中还有一个Servers选项卡,您可以在该选项卡下查看在该服务器实例上部署的内容。所有这些看起来都很好,而且应用程序及其捆绑包似乎都已正确部署。同样,如果您能够访问OSGi控制台,您可以运行“services”命令来查看服务是否已注册。如果它已注册,但bundle2仍无法获取它,则可能存在接口兼容性问题。。。确保TicketService接口只有一个副本,bundle1和bundle2都从同一位置导入。
<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"/>