1

bundle-jar ファイルを送信して、オンザフライで osgi にインストールします。これまでのところ魅力のように機能します。しかし、コンテンツをチェックアウトするとすぐに、コードはバンドル内の注釈を検出できません。注釈は両方とも同じです (両方のバンドル、検出側と送信側のバンドル) は同じ注釈 jar を使用するため、同じである必要があります。インストールされたバンドルは、受信後にファイルシステムに保存されます。さらに、osgi のさまざまなクラスローダーの問題ではないかと考えていました。この場合、注釈が null である理由を知っている人はいますか?

BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
Bundle bundle = context.installBundle("foobar.jar");
bundle.start();

BundleContext context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
Bundle bundle = context.installBundle("foobar.jar");
bundle.start();
BundleWiring wiring = bundle.adapt(BundleWiring.class);
Collection<String> classes = wiring.listResources("/", "*.class",BundleWiring.LISTRESOURCES_RECURSE);

LinkedList<String> c = new LinkedList<String>();

for (String str : classes) {
    str = str.replaceAll(".class", "");
    c.add(str.replaceAll("/", "."));
}
String classname = c.get(0);

Class<?> clazz = bundle.loadClass(classname);

for (Method m: clazz.getDeclaredMethods()) {
    System.out.println(m.getName());
    TestAnnotation testAnnotation= m.getAnnotation(TestAnnotation.class);
    if (txAnnotation != null) 
        System.out.println("\tsource=" + testAnnotation.sourceUnit() + "; target=" + testAnnotation.targetUnit());
}

注釈は次のようになります。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestAnnotation{
    String a();
    String b();
}

注釈付きクラスの例:

public class annoClass{

    @TestAnnotation(sourceUnit="a", targetUnit="b")
    public int foo(int i) {
        return 2;
    }

    @TestAnnotation(sourceUnit="xyz", targetUnit="abc")
    public int bar(int i) {
        return 3;
    }

}

受信者のマニフェスト:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Receiver
Bundle-SymbolicName: com.foo.bar.receiver.impl
Bundle-Version: 1.0.0
Bundle-Activator: comfoo.bar.impl.receiver
Import-Package: com.foo.bar.receiver;version="1.0.0",
 com.foo.bar.annotation,
 javax.jms,
 org.apache.activemq.command;version="5.8.0",
 org.osgi.framework;version="1.3.0",
 org.osgi.util.tracker;version="1.5.1"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: org.eclipse.osgi

注釈のマニフェスト:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Annotations
Bundle-SymbolicName: com.foo.bar.annotations
Bundle-Version: 1.0.0
Import-Package: javax.jms,
 org.apache.activemq.command;version="5.8.0",
 org.osgi.framework;version="1.3.0",
 org.osgi.util.tracker;version="1.5.1"
Export-Package: com.foo.bar.annotation
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: org.eclipse.osgi

プロデューサーのマニフェスト: (プロデューサーは単に転送するだけなので、アノテーションのインポートは必要ありません)

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Producer
Bundle-SymbolicName: com.foo.bar.producerplugin
Bundle-Version: 1.0.0
Bundle-Activator: com.foo.bar.producerplugin.ProducerPlugin
Bundle-ActivationPolicy: lazy
Import-Package: org.osgi.framework;version="1.3.0",
 org.apache.activemq;version="0.0.0",
 org.apache.activemq.command;version="0.0.0",
 javax.jms;version="0.0.0",
 com.foo.bar.brokerplugin;version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: org.eclipse.osgi
4

1 に答える 1

1

注釈が別のバンドルにあると仮定しましょう。そのため、注釈を使用してバンドル内に注釈が存在するパッケージをインポートする必要があります。さらに、インポートが満足できるように、アノテーションを含むバンドルをインストールする必要があります。

これを行う最も簡単な方法は、ビルドで bnd または felix バンドル プラグインを使用することです。使用されているパッケージを自動的に検出し、マニフェストを作成します。

場合によっては、同じ注釈をエクスポートする 2 つのバンドルがあるという問題が発生することもあります。たとえば、jaxb アノテーションと cxf の場合。JAXB は jdk の一部であるため、システム バンドル (OSGi フレームワーク) によってエクスポートされます。CXF は、これらを更新されたバージョンに置き換えます。そのため、cxf が更新されたバンドルを使用している間に、バンドルがシステム バンドルのバンドルを使用する場合があります。したがって、互換性がありません。その場合、システム パッケージのエクスポートを再定義して、これらのパッケージを削除する必要があります。これは、たとえばapache karafで行われます。

そのため、通常、アノテーション パッケージは通常のクラスと同様にインポートする必要があります。難しいのは、Java ではオプションのようなものだということです。したがって、注釈が利用できない場合、コードは失敗せず、単に無視されます。

于 2013-08-28T07:24:47.653 に答える