我正在发送一个 bundle jar 文件并将其即时安装到我的 osgi 中。到目前为止,效果就像一个魅力。但是,一旦我检查内容,我的代码就无法发现 bundle 中的注释。注释都是相同的(两个包,发现包和发送包)都使用相同的注释 jar,因此它们应该是相同的。 安装的 bundle 在收到后会保存到文件系统中。 此外我想知道这是否可能是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;
}
}
接收者 list :
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
注释 list :
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
生产者 list : (生产者不需要导入注释,因为它只是转发)
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
最佳答案
假设您的注释位于不同的包中。因此,您需要使用注释导入注释所在的包。此外,您还必须安装带有注释的 bundle ,以便满足导入的要求。
最简单的方法是在构建中使用 bnd 或 felix bundle 插件。它将自动检测使用过的包并创建您的 list 。
在某些情况下,您还可能遇到两个包导出相同注释的问题。例如 jaxb 注释和 cxf 的情况。由于 JAXB 是 jdk 的一部分,系统 bundle (OSGi 框架)会导出它们。 CXF 用更新版本替换了这些。因此,您的 bundle 可能会使用系统 bundle 中的 bundle ,而 cxf 使用更新后的 bundle 。所以他们不兼容。在这种情况下,您需要重新定义系统包的导出以删除这些包。例如,这在 apache karaf 中完成。 .
所以一般来说注释包必须像普通类一样导入。困难的是它们对于 java 来说是可选的。因此,如果注释不可用,那么您的代码不会失败,它们只会被忽略。
关于java - OSGi 中 bundle 安装后缺少注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18464163/