Hibernate、JDBC驱动程序和OSGi问题

Hibernate、JDBC驱动程序和OSGi问题,hibernate,osgi,springsource,Hibernate,Osgi,Springsource,我遇到了一个有点令人沮丧的问题。 我使用ApacheFelix作为我的OSGi框架,我还使用Hibernate解决持久性问题 我正在使用Hibernate的“OSGibundle”版本(com.springsource.org.Hibernate-3.2.6.ga.jar)。据我所知,这是Hibernate内核,在META-INF/MANIFEST.mf中安装了一些额外的osgi metdata。此信息(包导出和包导入)对于osgi系统至关重要 我的问题是Hibernate包找不到我的JDBC驱

我遇到了一个有点令人沮丧的问题。 我使用ApacheFelix作为我的OSGi框架,我还使用Hibernate解决持久性问题

我正在使用Hibernate的“OSGibundle”版本(com.springsource.org.Hibernate-3.2.6.ga.jar)。据我所知,这是Hibernate内核,在META-INF/MANIFEST.mf中安装了一些额外的osgi metdata。此信息(包导出和包导入)对于osgi系统至关重要


我的问题是Hibernate包找不到我的JDBC驱动程序。将导入语句添加到springsource Hibernate包中感觉非常错误。一定有更好的方法来解决这个问题。

您开始订购正确的捆绑包了吗?有一种方法可以设置每个捆绑包的开始级别,以便您的系统能够正确引导。如果某些激活器试图直接获取服务,则可能需要包的正确起始级别。如果服务不可用,服务消费者将被卡住

尝试为bundle设置适当的开始级别,看看它是否有效。具体地说,您必须在hibernate捆绑包之前首先使用JDBC驱动程序启动捆绑包

另一个问题可能是您有一些未解决的依赖项。确保所有东西都在那里。您可以通过获取OSGi控制台并请求服务列表来实现这一点。在Equinox中,这归结为OSGi shell中的-console命令行参数和“ss”后跟“diag”命令

编辑(回答您的评论):


驱动程序通过其接口进行注册。然后Hibernate可能通过其接口查找驱动程序,无需导入特定的驱动程序类。无论如何,这将引入对特定于实现的类的不必要的依赖。

Hibernate不是一个很好的OSGi公民,因为Hibernate对类可见性的许多假设在OSGi容器中不再成立

类.forName()
加载JDBC驱动程序的常用方法在OSGi中不起作用,因为在这种情况下,Hibernate会尝试加载驱动程序,但找不到,因为Hibernate不会(也不应该)导入JDBC驱动程序包

JDBC驱动程序管理器还试图通过确定调用类的类加载器是否应该看到驱动程序来实现智能化,这也与OSGi冲突

如果您使用Spring配置Hibernate,那么我建议您使用
SimpleDriverDataSource
类,因为它在OSGi中工作,Spring允许您使用具体的数据源配置Hibernate,而不是传递Hibernate需要实例化的类名

一旦解决了这个问题,您可能会遇到Hibernate无法看到域类的问题。我只有XML映射方法的经验,我认为OSGi更简单,因为我认为注释方法需要某种AOP编织,这是OSGi当前的另一个难点

目前,除非您使用Spring的dm Server之类的工具,否则您需要更加熟悉Java的类加载机制,以及如何使用OSGi的服务方法来解决vanilla Java和OSGi世界之间的不兼容问题


具体来说,了解企业库如何使用上下文类加载器,以及如何管理它。我正在使用SpringDM在OSGi服务中包装遗留代码,因为这样可以很容易地控制上下文类加载器。

我刚才遇到过。解决方案是将jdbc提供者包和jdbc用户包注册为“伙伴”。这是因为一个bundle不能在没有显式声明的情况下使用来自另一个bundle的类(所以jdbc驱动程序也是如此)。这是针对Eclipse的,所以我认为它可能会对您有所帮助。

在OSGi捆绑包中,您只能看到您导入的包中的类和资源。Hibernate捆绑包不会(也不应该)导入您的域类。因此,当Hibernate试图处理XML映射文件时,它会抱怨找不到要映射的类(您的域类)

我们通过使用Equinox的伙伴策略来解决这个问题,因此提供域对象的每个包都是Hibernate的类加载伙伴。我不太喜欢这种方法,但是我没有时间去写我脑海中(希望是)优雅的解决方案

正如我在之前的文章中所说,对于Hibernate来说,操纵上下文类加载器可能是最好的长期选择。

我没有尝试过这一点(因为我反对RDBMS,因此也反对ORM),但一种解决方案可能是使用OSGi片段

创建一个包含域类的片段,并将Hibernate捆绑包指定为主机。这个片段应该导出域类的包

同样,您可以对想要使用的JDBC驱动程序执行相同的操作。获取驱动程序类,并将它们转换为以Hibernate作为主机包的OSGi片段。但是,您不必导出驱动程序包,因为它们只供Hibernate包使用

我怀疑9个月前Felix还没有完全支持这些片段,但现在看来确实如此:

但是如果不显式导入例如org.embedded.derby或org.mysql.jdbc,我看不出hibernate包如何找到正确的jdbc驱动程序。您有hibernate包的源代码吗?看一下清单,看看哪个是activator类。然后看看这个类,这可能会回答您的问题“Hibernate然后可能通过其接口查找驱动程序,不需要导入特定的驱动程序类”。这是否意味着Hibernate捆绑包有一些用于设置特定JDBC驱动程序的API?(例如,设置mysql jdbc、设置oracle jdbc等。否则我看不出hibernate如何获得正确的驱动程序)驱动程序提供程序注册他的驱动程序(ctx.register(JDBCDriver,MySQLJDBCDriver),任何需要它的人都会请求驱动程序(ctx.getService(J