BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Hibernate添加了对OSGi的支持

| 作者 Alex Blewitt 关注 4 他的粉丝 ,译者 张卫滨 关注 13 他的粉丝 发布于 2013年7月17日. 估计阅读时间: 8 分钟 | AICon 关注机器学习、计算机视觉、NLP、自动驾驶等20+AI热点技术和最新落地成功案例。

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

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

OSGi最大的开源社区 by soft wmz

OSGi最大的开源社区:osgia.com,还有在线演示,相当NB。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT