`

Hibernate添加了对OSGi的支持

阅读更多
转载于http://www.infoq.com/cn/news/2013/07/hibernate-osgi

Hibernate是流行的Java ORM Manager,最近添加了对OSGi的支持,这样使得Hibernate可以作为单独的Jar使用也可以位于OSGi运行时中。尽管对于库来说添加对OSGi的支持一般只需在MANIFEST.MF中添加几个条目即可,但是对于要通过反射来查找类的库来说,这可能是更具有挑战性的工作。

InfoQ联系到了Brett Meyer以了解他们遇到了什么困难以及特性是如何演化的,他是Red Hat的软件工程师并且也是Hibernate ORM的核心开发人员。

InfoQ: 看起来使Hibernate支持OSGi是 最近的一个bug,但是这个请求可以追溯到2008年。你能介绍一下这个修正是如何进行的吗?


Meyer: 在很多方面来讲,这都是社区驱动项目取得的进展。有些人的兴趣会围绕着特定的主题并提供了迭代的解决方案,这个解决方案最终落实到了最后的结果之中。在这件事上,我过去就一直主张让Hibernate可以在OSGi环境中运行。所以,在2012年8月我加入这个团队之后,这项任务就位于我的优先级列表之中了。这整合了社区的多个成员开始做一些启动的工作并引起了整体的讨论。

InfoQ: 相对于其他的Java库,为Hibernate添加OSGi支持为什么更为困难呢?


Meyer: 基本上来说,针对于JPA中ORM实现的每一项困难都涉及到多个ClassLoader。扫描、解析实体、解析映射资源、索引注解、注册/使用扩展点实现、代理、保持状态、缓存以及其他需要考虑的因素使得这成为一项令人有些沮丧的复杂问题。

将其放到Hibernate的“bundle家族”(而不是一个“超级jar(uber-jar)”)中,并且最终还要支持动态的持久化单元bundle,事情会变得更加糟糕。

InfoQ: Hibernate中有没有什么新的特性能够帮助你实现对OSGi的支持?


Meyer: 在Hibernate ORM 4中,有一些新的理念显然会使得事情更为简单。多阶段启动(Multi-phased bootstrapping)能够更为容易地在加载和处理资源之前提供ClassLoader和集成挂钩(hook)。集成挂钩本身能够更容易得织入在持久化单元bundle之中的“扩展点”实现。

但是,依然有很多静态的并且类似于创可贴式的修复,这使得在当前架构中这些问题更为明显。Hibernate ORM 5中正在进行的新元模型将会在很大程度上增加我们的支持能力。

InfoQ: Hibernate库如何获取对JPA类的引用呢?


Meyer: 为了支持多个持久化单元、多个Hibernate ORM实例并且可能会有两者的多个版本,我们完全避免了 DynamicImport-Package。当请求EntityManagerFactory(JPA)或SessionFactory(原生)时,Hibernate ORM OSGi为Core提供了一个自定义的ClassLoader。这个ClassLoader只关心Hibernate bundle的实例以及”请求bundle(requesting bundle)“——包含持久化单元的bundle。按照通常的做法,实体可以通过持久化单元明确地列出也可以通过扫描来进行查找。我们也可以查找”扩展点“接口的实现,如Integrator。所有的一切要求整个持久化单元(所有的映射、实体以及扩展点)位于一个bundle中,它需要EMF/SF。

需要一个单元来组成的bundle并不理想,我们正在努力来对其进行提高。另外,需要提及的是对于多个Hibernate ORM实例及多版本尚未完全支持。正如前面所提到的,Hibernate ORM 4依然是非常静态化的,这是很令人遗憾的。针对Hibernate ORM 5的更为动态化的工作正在进行之中。

InfoQ: 你能够重启一个依赖于Hibernate的bundle并正确的获得新的类吗?


Meyer: 在理论上,”请求bundle“ClassLoader架构应该允许这样做。这个功能与要求EMF/SF的持久化bundle进行关联,因此重启应该是可行的。但是,到Hibernate ORM 5的时候才能真正完全支持这种动态特性,尤其是涉及到优雅地清理等等。

InfoQ: 针对OSGi的支持,你是如何进行测试的?


Meyer: 在Arquillian上,我创建了一个集成/单元测试,用到了Apache Felix作为容器。这带来了许多很独特的挑战,大多数与ClassLoading有关。我最初希望使用ShrinkWrap或Tinybundles在运行时动态地在内存中创建持久化单元。但是,这两种方式都会导致Hibernate ORM Core在获得实体的时候,实体的注解丢失(用于为ShrinkWrap提供InputStream的ClassLoader和在Core读取它们的ClassLoader是不同的)。还有其他的问题,如测试运行时重写了”请求bundle“(前文所述),本质上来讲是把整个容器的ClassLoader赋给它了。围绕着这些问题,引入了一些hacky风格的丑陋的修正。

我最后形成了三个独立的资源集合:test、testClientBundle和testResult。test集合包含了实际的Arquillian测试用例。testClientBundle集合包含了持久化单元和实际的“单元测试”,用到了Hibernate OSGi服务(同时包含JPA和原生方式)并校验结果。任何的失败都会设置到一个OSGi服务引用中,而它是通过testResult中的接口定义的。在运行的最后,用最初的测试用例来检查服务。除了解决ClassLoader的问题,这几乎构建了一个现实世界的运行环境。我最后发现这种中介类型的服务构建方式与Aries JPA测试的工作方式非常接近。在此之前,我应该首先了解一下它们……

InfoQ: 关于如何结合OSGi使用Hibernate,有什么文档或样例吗?


Meyer: 作为开始,最好的地方是我们的开发人员指导。它描述了我们所支持的环境、实现细节以及警告说明。另外,还有一个教程(Tutorial)和快速起步(QuickStart)工程。对于想了解更详细讨论的人来说,可以从JIRA上OSGi的顶层任务、子任务以及关联的需求开始。

在上周发布的Hibernate 4.2.3释放版中添加了OSGi的支持,你觉得这项新功能如何?

原文英文链接:Hibernate adds OSGi Support
分享到:
评论

相关推荐

    java开源包1

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包11

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包2

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包3

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包6

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包5

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包10

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包4

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包8

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包7

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包9

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    java开源包101

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    Java资源包01

    容易维护扩展(不需要修改主类就可以添加新的API支持) 注入型解释器(依据不同的返回格式注入相应的解释器) 集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展...

    JAVA上百实例源码以及开源项目源代码

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    JAVA上百实例源码以及开源项目

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    Spring攻略(第二版 中文高清版).part2

    10.3 为应用添加Spring BlazeDS支持 406 10.3.1 问题 406 10.3.2 解决方案 406 10.3.3 工作原理 406 10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 ...

    Spring攻略(第二版 中文高清版).part1

    10.3 为应用添加Spring BlazeDS支持 406 10.3.1 问题 406 10.3.2 解决方案 406 10.3.3 工作原理 406 10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 ...

Global site tag (gtag.js) - Google Analytics