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

标签 java osgi blueprint

我目前有两个 OSGi 包(bundle1bundle2)都通过 EBA 中的蓝图公开服务。在 bundle2blueprint.xml 中,我想从 bundle1 中引用一个服务并将其注入(inject)到 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>

blueprint.xml 用于 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>

构建服务的实现:

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 />具有相同配置的元素,但没有 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"/>

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

关于java - OSGi/blueprint 中的服务引用无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5343388/

相关文章:

Java morphia - 按列表字段中的值查询

java - OSGI 包和线程

python - Flask-如何处理URL中的中文字符

python - flask - blueprint - sqlalchemy - 无法将名称 'db' 导入 moles 文件

java - 如何使用Httpclient的GET方法访问flashplayer

java - 如何获得用于生成随机数的范围?

java - Android:使用贝塞尔的数字签名

java - 从流构建模型(异常 : Reader not found on classpath)

java - org.osgi.framework.BundleException : Unable to resolve: missing requirement: osgi. wiring.package; (osgi.wiring.package=org.json)

http-status-code-404 - flask :蓝图的error_handler