我考虑修改现有的java框架以使用OSGi。我有几个组件依赖于反射并适用于任何类型的类(如bean和持久性服务)。 我对OSGi还不是很熟悉,但据我所知,OSGi包只能看到它明确导入的包中的类。如果我使用 maven-bundle-plugin 构建一个包并指定一个通配符作为import-package,它会解析在构建时由代码引用的包。我需要代码来处理构建时未知的包中的类。
我想要实现的是bundle-A可以使用bundle-B中的持久性框架来持久化属于bundle-C的类。虽然bundle-B在构建时不知道bundle-C。
我需要哪些清单条目以及如何使用 maven-bundle-plugin 设置它们?
此外,由于不同捆绑包可以使用同一类的多个版本,这在OSGi环境中是否有意义?如果我理解正确,Bundle-A和Bundle-B可能会看到Bundle-C的不同版本。如果Bundle-A现在将位于Bundle-C中的类的对象传递给Bundle-B然后在类上使用反射,那么Bundle-B将看到它在Bundle-C中定义的类或者它在Bundle-A< Bundle-C中定义。 例如,如果我在Bundle-C中有以下类:
class Y {
[...]
}
class X {
Y y;
[...]
}
Bundle-C与Bundle-A和B不同.B将类X的对象传递给A.如果B现在发现字段y并解析它的类将解析Y,因为它在其中#& 39; Bundle-C的版本或A?
已知的版本简而言之,即使我有一个从所有bundle中导入所有类的bundle,这对于创建一个将对象持久存储到数据库中的服务甚至是有用的吗?
答案 0 :(得分:1)
整个类加载问题仅在加载类时才有意义。反射在OSGi中的工作方式与OSGi外部相同。
因此,如果您在bundle b中有一个方法,它将Object作为参数。然后,您可以使用bundle c中定义的Class实例从bundle A调用此方法。即使bundle b没有导入对象的包,它仍然可以使用反射来处理对象。
如果您希望在不导入包的包中按名称加载类,则安全的方法是为其提供包含类的包的类加载器。
例如,你可以在bundle b中使用这个方法:
public Object loadTest(ClassLoader loader, String name) {
return loader.loadClass(name);
}
现在的问题当然是如何在bundle a中获取bundle b的类加载器。最简单的方法是使用MyClass myObject = new MyClass()从b创建一个类。捆绑a可以在导入包时执行此操作。然后,您可以使用myObject.getClass().getClassLoader()
获取bundle b的类加载器。
在OSGi中,每个对象的类加载器是它所定义的包的类加载器(如果你不做任何奇怪的事情)。
如果无法做到这一点,您可以使用
获取捆绑包的类加载器ClassLoader loader = bundle.adapt(BundleWiring.class).getClassLoader();
答案 1 :(得分:0)
您在一篇文章中有多个问题:)
要在OSGi环境中设置JPA,您可以check my blog。
OSGi环境中的JPA实现以另一种方式工作。它挂钩到一个bundle监听器,如果一个bundle用persistent(@Entity)类启动,它将加载它们。
关于班级版本:
通常情况下 - 如果您想要一些服务包来识别您的课程,您可以注入'它使用捆绑片段。在你的情况下 - 你有一个直接依赖(X依赖于Y),因此加载类X的任何包将加载类Y(具有特定版本)。
在OSGi环境中,您可以使用不同的类版本,但不能混用它们。实际上,bundle依赖于特定的类版本(声明或首次发现)。实际上 - 每个类都由其名称和类加载器标识来标识。因此,强制捆绑包使用来自不同类加载器(版本)的相同类将导致“类加载器中毒”#39;以及许多难以追查的例外情况。
玩得开心