在 OSGi 环境中,类路径和类加载器是如何设置的?

Posted

技术标签:

【中文标题】在 OSGi 环境中,类路径和类加载器是如何设置的?【英文标题】:In an OSGi environment, how are the classpaths and classloaders set up? 【发布时间】:2010-11-19 07:34:47 【问题描述】:

我对 OSGi 中的类可见性感到困惑。我正在运行 Apache Felix 并加载以下包:

来自 eclipselink 的 antlrasmjpacore 捆绑包 javax.persistence 1.99 的 OSGi jar 带有com.mysql.jdbc 驱动程序的OSGi jar 我自己的包,其中包含带注释的实体类和persistence.xml 我自己的另一个包,调用Persistence.createEntityManagerFactory(String, Map)

现在,我很困惑的是哪个包必须能够看到 MySQL 驱动程序。我认为这将是创建 EntityManagerFactory 的包,但是当我在该清单中导入时出现 ClassNotFound 错误。接下来,我尝试从 eclipselink jpa 包的清单中导入它,但又出错了。只有当我从包含持久性单元(实体类和persistence.xml)的包的清单中导入它时,它才能工作。

所以,看起来数据库驱动程序是由类加载器查找 PU 包的,但这对我来说没有意义。怎么回事?

我似乎无法为此找到一个简单的文档。 These slides 给出了一些提示,但并不全面。

【问题讨论】:

【参考方案1】:

我熟悉围绕 Hibernate 和 JDBC 的 OSGi 类路径问题,我可以根据您链接到的幻灯片向您解释正在发生的事情。

我假设您已将 JDBC 驱动程序条目添加到您的 PU 包内的 persistence.xml 中?

EclipseLink 正在使用extender 模式代表PU 包执行工作。扩展器正在侦听捆绑包,检查它们是否有 persistence.xml,然后进行设置工作。它希望 PU 包导入您可能在 persistence.xml 中引用的所有类型,包括 JDBC 驱动程序。

考虑一下。 EclipseLink 包不会导入所有已知的 JDBC 驱动程序(它不应该)——只有你的包可以知道他们需要哪个数据库驱动程序,所以期望你的 PU 包导入 JDBC 驱动程序类是合理的。

如果第三方库已经是 OSGi 化的,例如 EclipseLink,则不需要修改它们的清单。

【讨论】:

我将驱动程序作为属性传递给 createEntityManagerFactory,但我想这是一回事吗?不知何故,这对我来说似乎很奇怪。不应该是处理所有数据库特定内容的持久性提供程序吗? 持久性提供者所需要的只是一个可以处理 JDBC 接口的 DB 驱动程序。这样你就可以保持包之间的耦合很低。选择使用哪个数据库是特定于应用程序的,因此它应该是您的代码/配置的一部分。这是 OSGi 的基本模式:接口用作契约,一些包提供域或特定于应用程序的实现。【参考方案2】:

我发现这个 pdf 关于类加载的信息非常丰富: http://www.martinlippert.org/events/WJAX2008-ClassloadingTypeVisibilityOSGi.pdf

【讨论】:

以上是关于在 OSGi 环境中,类路径和类加载器是如何设置的?的主要内容,如果未能解决你的问题,请参考以下文章

weblogic上的类路径和类加载

OSGi Felix 和 BndTools - 按名称加载类

如何在 Equinox 中获取捆绑包的类加载器?

JAVA基础_类加载器

如何配置OSGi环境以便可以从EclipseStarter类中使用它?

websphere OSGi应用环境下服务调用saaj包加载问题分析报告