2013-08-27 3 views
1

Я отправляю файл с пакетом-пакетом и устанавливаю его в свой osgi на лету. Пока работает как прелесть. Но как только я проверяю содержимое, мой код не удается обнаружить аннотации, которые находятся в комплекте. Аннотации одинаковы (оба пучка, обнаружение и отправка) используют одни и те же аннотации-банку, чтобы они были одинаковыми. Установленный пакет сохраняется в файловой системе после ее получения. Кроме того, мне было интересно, может ли это быть проблемой разных загрузчиков классов в 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 является частью jdk, системный пакет (OSGi framework) экспортирует их. CXF заменяет их обновленной версией. Так что может случиться так, что ваш пакет использует один из системного пакета, а cxf использует обновленные. Поэтому они несовместимы. В этом случае вам нужно переопределить экспорт системного пакета, чтобы удалить эти пакеты. Это делается, например, в apache karaf.

Так что в общем случае пакеты аннотаций должны быть импортированы, как обычные классы. Трудно, что они являются необязательными для java. Поэтому, если аннотации недоступны, ваш код не будет терпеть неудачу, и они просто будут проигнорированы.

Смежные вопросы