2016-03-11 34 views
0

我正在考虑修改现有的java框架以使用OSGi。我有几个依赖反射的组件,并且可以与任何类型的类(如bean和持久性服务)一起工作。 我对OSGi还不是很有经验,但据我了解,OSGi包只能看到它明确导入的包中的类。如果我用maven-bundle-plugin构建一个包,并指定通配符作为导入包,它将解析构建时由代码引用的包。我需要代码来处理构建时未知的包中的类。使用maven构建基于反射的OSGi服务

我想要实现的是,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-B将按照其在Bundle-C中定义的类或者在Bundle-C中定义的类Bundle-A的Bundle-C。 例如,如果我在捆绑-C以下类:

class Y { 
    [...] 
} 

class X { 
    Y y; 
    [...] 
} 

捆绑-C是用于捆绑-A不同和B B通过类X的一个目的是A.如果B现在发现领域ÿ并解决它的类是否会解析Y,因为它是Bundle-C的版本还是A已知的版本?

简而言之,即使我有一个从所有包中导入所有类的包,这甚至可以用来创建一个服务来将对象保存到数据库中?

回答

1

当你加载类类加载的整个问题才有意义。反射在OSGi中的工作方式与外部OSGi相同。

所以,如果你有一个方法捆绑b,把一个对象作为参数。然后你可以从bundle A中调用这个方法,并在bundle c中定义一个Class的实例。即使bundle b没有为该对象的包导入,它仍然可以使用反射来处理该对象。

如果您希望在不导入包的包中按名称加载类,那么安全的方法是将其包含类的包的类加载器。

因此,例如,你可以在捆B这个方法:

public Object loadTest(ClassLoader loader, String name) { 
    return loader.loadClass(name); 
} 

现在的问题当然是如何让包B的包一个类加载器的。最简单的方法是使用MyClass myObject = new MyClass()从b创建一个类。捆绑一个可以做到这一点,因为它导入包。然后您可以使用myObject.getClass().getClassLoader()来获取bundle b的类加载器。

在OSGi中,每个对象的类加载器都是它定义的包的类加载器(如果你不做任何奇怪的事情)。

如果这是不可能的,你可以通过使用

ClassLoader loader = bundle.adapt(BundleWiring.class).getClassLoader(); 
+0

谢谢。因此,如果一个类由类加载器加载,则其字段的类也由相同的类加载器填充。我认为当getFields被调用时,线程的类加载器可能会延迟加载它,这会看到不同版本的字段类。我想这意味着调用newInstance将使用构造类的类加载器而不是调用者的类加载器。如果您不介意另外一个问题,我可以依赖具有不同哈希码的相同类的不同版本,还是依赖于JVM?我需要缓存每个类的DAO(-version) – user3240383

+0

OSGi类加载不使用线程上下文类加载器。 这些字段通常由它们所在类的bunde类加载器加载..但是如果字段类位于该包之外,则此类加载器引用其他bundle类加载器。所以字段类可能有不同的类加载器。 我认为hashcodes应该是不同的,但从来没有尝试过。 –

+0

类的标识来源于完全限定的类名和定义它的类加载器。 hashCode不会帮助你区分类。 –

0

您在一篇文章多个问题:)

对于在OSGi环境可能你check my blog建立JPA。

OSGi环境中的JPA实现以另一种方式工作。它挂接到一个包监听器,如果一个包以持久化(@Entity)类启动,它将加载它们。

关于类版本:

一般 - 如果你想要一些服务捆绑认识到你的类,你可以“注入”它使用束片段。在你的情况 - 你有一个直接的依赖关系(X取决于Y),因此任何加载类X的bundle都将加载Y类(使用特定版本)。

在OSGi环境中,您可以使用不同的类版本,但不可混用它们。实际上,一个包依赖于特定的类版本(声明或首次发现)。事实上 - 每个类都由其名称和类加载器标识来标识。因此,迫使bundle使用来自不同类加载器(版本)的相同类将导致“类加载器中毒”和大量难以追踪的异常。

玩得开心

+0

感谢您的附加信息获得一个捆绑的类加载器。我应该提到我使用我自己的不是JPA的持久性框架。 – user3240383