stu*_*f22 4 java osgi blueprint
我目前有两个OSGi捆绑包(bundle1和bundle2)都通过EBA中的蓝图暴露服务.在bundle2的blueprint.xml我想引用来自服务bundle1和注射入编译服务(下面的代码),作为编译服务将被用于调用票务.然而,这会导致超时异常(也在下面).似乎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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
启动应用程序服务器(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)
Run Code Online (Sandbox Code Playgroud)
下面是解决方案: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"/>
Run Code Online (Sandbox Code Playgroud)
在websphere中实际上还有一个osgi控制台,它可以在下面找到[local websphere installation]/profiles/[profileName]/bin/osgiApplicationConsole.bat.一旦推出,就会help()给出一个命令列表.要从SCA查看导入的服务,首先要连接到您的应用程序(例如connect(2),在list()命令结果中给出应用程序的编号).然后,您可以services("(service.imported=true)")查看SCA添加的服务代理.该命令services()将列出应用程序中的所有服务.