2013-08-27 72 views
1

我正在發送一個bundle-jar文件並將其安裝在我的osgi中。像迄今爲止的魅力一樣工作。但只要我檢查出內容,我的代碼就無法發現捆綁中的註釋。註釋都是相同的(包,發現和發送一個)使用相同的註釋jar,所以他們應該是相同的。 安裝的軟件包在收到後會保存到文件系統中。 此外,我想知道這是否是osgi中不同類加載器的問題。任何人都知道爲什麼註釋在這種情況下爲空?在OSGi中安裝軟件包後缺少註釋

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 
+0

你還沒有發佈你的軟件包清單。你確定'TestAnnotation'包是否被列爲OSGi依賴項? – chrylis

+0

啊,就是這樣。將檢查通過,並會回到你身邊。感謝提示。 – Chaoz77

+0

好的,我重新整理了包並儘可能集中了註釋。仍然(即使清單中的導入現在都指向帶註釋的同一個包)txAnnotation = null ...怎麼回事? :) – Chaoz77

回答

1

讓我們假設你的註釋是在不同的包。因此,您需要使用註釋來導入批註所在的包。此外,您將不得不安裝包含註釋的軟件包,以便滿足導入。

最簡單的方法是在構建中使用bnd或felix bundle插件。它會自動檢測使用的軟件包並創建您的清單。

在某些情況下,您也可能遇到導出相同註釋的兩個捆綁包的問題。例如,在jaxb註釋和cxf的情況下。由於JAXB是系統包(OSGi框架)的jdk的一部分,因此導出它們。 CXF用更新後的版本替換它們。所以可能發生的情況是,您的軟件包使用系統軟件包中的軟件包,而cxf使用更新的軟件包。所以他們不兼容。在這種情況下,您需要重新定義系統包的導出以刪除這些包。這例如在apache karaf中完成。

所以通常註釋包必須像普通類一樣導入。難點在於它們對於java來說是可選的。所以如果註釋不可用,那麼你的代碼不會失敗,它們將被忽略。

相關問題