【问题标题】:Missing annotations after bundle install in OSGi在 OSGi 中安装包后缺少注释
【发布时间】:2013-08-27 11:30:00
【问题描述】:

我正在发送一个 bundle-jar 文件并将其安装在我的 osgi 中。到目前为止,它就像一个魅力。但是,一旦我检查了内容,我的代码就无法发现捆绑包中的注释。注释都是相同的(捆绑,发现和发送)使用相同的注释-jar,所以它们应该是相同的。 安装的包在收到后会保存到文件系统中。 此外,我想知道这是否可能是 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

【问题讨论】:

  • 您尚未发布捆绑清单。你确定TestAnnotation 的包被列为 OSGi 依赖项吗?
  • 啊,原来如此。将检查这一点,并会回复你。感谢您的提示。
  • 好吧,我重组了 bundle 并尽可能集中了注解。仍然(即使清单中的导入现在都指向带有注释的同一个包) txAnnotation = null ... 怎么会? :)
  • 不能仅凭此说。发布您的清单和所涉及类的 FQCN?
  • 哪些类被注解,哪些类试图读取注解?

标签: java annotations osgi bundle


【解决方案1】:

让我们假设您的注释位于不同的包中。因此,您需要使用注解来导入注解所在的包。此外,您必须安装带有注释的捆绑包,以便满足导入。

最简单的方法是在构建中使用 bnd 或 felix bundle 插件。它会自动检测使用过的包并创建你的清单。

在某些情况下,您可能还会遇到两个包导出相同注释的问题。例如在 jaxb 注释和 cxf.由于 JAXB 是 jdk 的一部分,系统包(OSGi 框架)将它们导出。 CXF 将这些替换为更新版本。因此,您的捆绑包可能会使用系统捆绑包中的捆绑包,而 cxf 使用更新的捆绑包。所以它们不兼容。在这种情况下,您需要重新定义系统包的导出以删除这些包。例如,这是在 apache karaf 中完成的。

所以通常注释包必须像普通类一样导入。困难的是它们对于java来说是一种可选的。因此,如果注释不可用,那么您的代码将不会失败,它们将被忽略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多