4

現在、2 つの OSGi バンドル (bundle1およびbundle2) があり、どちらも EBA のブループリントを通じてサービスを公開しています。BuildService はTicketServiceを呼び出すために使用されるため、 からサービスを参照して BuildService (以下のコード) に挿入しbundle2たいと考えています。ただし、これにより Timeout 例外が発生します (以下も参照)。BuildService が OSGi に登録されないようです。どうすればこのようなものを作ることができますか?blueprint.xmlbundle1

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>

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)
4

1 に答える 1

5

これが解決策です。OSGi アプリケーション ランタイムは、リモート サービスをローカル サービスとは異なる方法で扱います。これは、デフォルトの呼び出しセマンティクスが異なるためです (ローカルの参照渡しとリモートの値渡し)。値渡し呼び出し専用に設計された、エクスポートされたサービスをアプリケーションが誤って呼び出すのを防ぐために、このサービスはローカル ルックアップから隠されています。

これに対する解決策は、同じ Bean を 2 回 (リモート呼び出し用に 1 回、ローカル呼び出し用に 2 回) エクスポートすることです。<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()は、アプリケーション内のすべてのサービスを一覧表示します。

于 2011-03-18T20:51:44.800 に答える