简体   繁体   English

一致导入第三方库的OSGi

[英]Consistent OSGi import of 3rd party libraries

I've been developing OSGi modules but so far I've come across a number of issues when I've had to wrap existing jars. 我一直在开发OSGi模块,但是到目前为止,当我不得不包装现有的jar时,我遇到了许多问题。 An example of this is the use of the Oracle database driver which, even though I've wrapped the jar as bundle, just refuses to work (cannot find the driver class even though its present). 这方面的一个示例是使用Oracle数据库驱动程序,即使我将jar打包为捆绑包,它也拒绝工作(即使存在驱动程序类,也无法找到)。 This is just a single example but I've had issues with other 3rd party libraries and was wondering if there's a best practice approach to using 3rd party libraries which works every time? 这仅是一个示例,但是我与其他第三方库存在问题,并且想知道是否存在每次都能使用的最佳方法来使用第三方库?

Jlove 杰洛夫

My preferred approach is not to wrap the library, but to unjar it, add a manifest, and re-jar it. 我的首选方法不是包装库,而是解压缩它,添加清单,然后重新打包。 Jars-inside-jars tend to cause issues that are hard to debug. Jars-inside-jars往往会导致难以调试的问题。 Unjar and re-jar can be automated with a simple ant script. 可以使用简单的ant脚本自动执行Unjar和re-jar。

Also, I like to write MANIFEST.MF manually. 另外,我喜欢手动编写MANIFEST.MF。 If the library being wrapped is small, then it's easy enough to do that. 如果要包装的库很小,那么这样做很容易。 Tools like bnd that generate MANIFEST.MF for you do not always give the right results, and if you rely on them too much you don't know what is going on under the hood. 像bnd这样的为您生成MANIFEST.MF的工具并不总是能给出正确的结果,如果您过多地依赖它们,您将不知道到底发生了什么。

The problem in your case is that jdbc uses a class from the java runtime to find the database driver (DriverManager.getConnection). 您遇到的问题是jdbc使用Java运行时中的类来查找数据库驱动程序(DriverManager.getConnection)。 This can not work as the database driver is not accessible from the system classloader (that loaded the DriverManager class). 由于无法从系统类加载器(已加载DriverManager类)访问数据库驱动程序,因此无法使用该功能。

A way that works in OSGi is to use a DataSource instead: http://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html . OSGi中一种有效的方法是改用DataSource: http : //docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html There you simply create the data source using new and this of course works. 在这里,您只需使用new创建数据源,这当然可以工作。 The problem is that it makes your user bundle depend on the specific DB driver. 问题在于它使您的用户捆绑包依赖于特定的数据库驱动程序。 So the best practice is to create the DataSource centrally and publish it as service. 因此,最佳实践是集中创建DataSource并将其作为服务发布。

You can find some more details in my Apache Karaf DB Tutorial ( http://www.liquid-reality.de/display/liquid/2012/01/13/Apache+Karaf+Tutorial+Part+6+-+Database+Access ). 您可以在我的Apache Karaf数据库教程( http://www.liquid-reality.de/display/liquid/2012/01/13/Apache+Karaf+Tutorial+Part+6+-+Database+Access)中找到更多详细信息)。

Btw. 顺便说一句。 In general this kind of factories are tpyically where libraries fail in OSGi. 通常,这种工厂通常在OSGi中库失败的地方。 Every lib invents another and different factory system and most of the are incompatible with the restricted classloaders of OSGi. 每个库都发明了另一个不同的工厂系统,并且大多数与OSGi的受限类加载器不兼容。 Luckily most libs are made OSGi ready nowadays. 幸运的是,如今大多数库都可以使用OSGi。 Most times this simply means that you can also call the factory with a concrete object that you can retrieve using an OSGi service. 大多数情况下,这仅意味着您还可以使用可以使用OSGi服务检索的具体对象来调用工厂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM