我目前有两个OSGi包(bundle1
和bundle2
)都通过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;
}
}
答案 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()
将列出应用程序中的所有服务。