3

私はosgiにかなり慣れていないので、機能的な概念実証を一緒に取得しようとしています。

セットアップでは、私の共通APIは、バンドルアクティベーターのないcommon-api.jarというクリエイティブな名前のバンドルで作成されますが、すべてのインターフェイスをエクスポートします。この状況で重要なのはDatabaseService.javaです。

次に、systemx-database-serviceという2番目のバンドルがあります。これにより、データベースサービスインターフェイスが実装されます。これは、実装バンドルのアクティベーターの場合と同様に正常に機能します。データベースへの接続をテストし、いくつかの調停値を選択します。他のバンドルで利用できるようにしたいサービスも登録します。

   context.registerService(DatabaseService.class.getName(), new SystemDatabaseServiceImpl(context), new Properties());

基本的な考え方は、データベースサービスのサービス参照を探すときに、SystemDatabaseServiceの実装を取得することです。

私が検査サービスを行うとき、それを出力します:

-> inspect s c 69
System Database Service (69) provides services:
----------------------------------------------
objectClass = za.co.xxx.xxx.common.api.DatabaseService
service.id = 39

これは、テストバンドルでこれを行うと次のように信じるようになります。

context.getService(context.getServiceReference(DatabaseService.class));

DatabaseService.classのインスタンスを取り戻す必要がありますが、残念ながらそのような運はありません。サービスが見つからないようです。ここで私に固執する私の話は奇妙になります。

行くところがないと思って、私はこの怪物を書きました:

 for (Bundle bundle : bundles) {
        if (bundle.getSymbolicName().equals("za.co.xxx.xxx.database-service")) {
            ServiceReference[] registeredServices = bundle.getRegisteredServices();
            for (ServiceReference ref : registeredServices) {
                DatabaseService service = (DatabaseService) context.getService(ref);
               // use service here. 
               }
            }
        }
    }

これで実際にサービス参照を見ることができますが、このエラーが発生します

java.lang.ClassCastException: za.co.xxx.xxx.database.service.impl.SystemDatabaseServiceImpl cannot be cast to za.co.xxx.xx.common.api.DatabaseService

実装が明らかにインターフェースを実装しているので、これはクレイジーです!

どんな助けでもいただければ幸いです。私はosgiの考え方に非常に慣れていないので、ここでの私のアプローチ全体に欠陥がある可能性があることを覚えておいてください。

ああ。マニフェストが必要な場合は投稿できます。そして、私はmaven-bnd-pluginを使用してfelixでビルドおよび実行しています。

ありがとう

ニコ

4

1 に答える 1

2

テストバンドルは、SystemDatabaseServiceImplと同じDatabaseServiceインターフェイスのインポートに解決される必要があります。これが発生しない場合、getServiceReferenceは、サービスが見つかった場合でもnullを返すことを文書化します。バンドルを手動で検索し、サービスとキャストを検索しようとすると、getServiceReferenceがこのように動作する理由がわかります。任意のサービスが返された場合、Javaキャストは失敗します。

implバンドルとtestバンドルの両方でDatabaseService.class.getClassLoader()を印刷して、それらが同じバンドルであるかどうかを証明することをお勧めします。そうでない場合は、OSGi MANIFEST.MFメタデータを調整して、インターフェースクラスのビューが一貫していることを確認する必要があります。

たとえば、DatabaseServiceインターフェイスはtestバンドルとimplバンドルの両方に含まれていますか?はいの場合、そのインターフェイスをimplバンドル(およびExport-Package)または3番目のインターフェイスバンドルおよびExport-Packageに移動する必要があります。次に、他のバンドルをImport-Packageに調整します。

于 2010-04-28T14:01:05.043 に答える