OSGI与Apache Commons-DBCP 类加载问题
我继承了一些在 OSGi 包中使用 Apache commons-dbcp 连接池的代码。此代码与 Eclipse/Equinox OSGi 版本 3.4.3 (R34x_v20081215)、commons-dbcp 1.2.2 和来自 springsource.org 的 postgres jdbc3 8.3.603 捆绑包配合良好。
我想要现代化,也许这是我的第一个错误!
当我将新版本的 Felix 或 Equinox OSGI Cores 与新的 postgresql JDBC3 或 JDBC4 捆绑包以及最新版本的 commons-dbcp (1.4.1) 一起使用时,我遇到了类加载问题。我进行了大量搜索,发现 commons-dbcp 代码应该有一个修复 DBCP-214 ,但似乎仍然失败。
我尝试将 org.postgresql 放在 commons-dbcp MANIFEST.MF 导入包行上,但这也不起作用。
我在激活器中编写了一个简单的测试,首先执行基本的 class.forName() 和 DriverManager.getConnection(),这工作正常,但是当我添加 BasicDataSource() 并设置与 BasicDataSource.getConnection() 的连接时,我得到ClassNotFoundException。请参阅下面的代码示例。
预先感谢您的任何帮助、建议……
Sau!
// This one fails with an exception
public void dsTest() {
BasicDataSource bds = new BasicDataSource();
ClassLoader cl;
try {
logger.debug("ContextClassLoader: {}",
Thread.currentThread().getContextClassLoader().toString());
cl = this.getClass().getClassLoader();
logger.debug("ClassLoader: {}", cl);
if (bds.getDriverClassLoader() != null) {
logger.debug(bds.getDriverClassLoader().toString());
}
// The failure is the same with and with the setDriverClassLoader() line
bds.setDriverClassLoader(cl);
bds.setDriverClassName("org.postgresql.Driver");
bds.setUrl("jdbc:postgresql://127.0.0.1/dbname");
bds.setUsername("user");
bds.setPassword("pword");
Class.forName("org.postgresql.Driver").newInstance();
conn = bds.getConnection();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM table");
conn.close();
logger.debug("Closed DataSource Test");
} catch (Exception ex) {
ex.printStackTrace();
logger.debug("Exception: {} ", ex.getMessage());
}
}
// This one works
public void managerTest() {
ClassLoader cl;
try {
cl = this.getClass().getClassLoader();
logger.debug("ClassLoader: {}", cl);
Class.forName("org.postgresql.Driver").newInstance();
String url = "jdbc:postgresql://127.0.0.1/dbname";
conn = DriverManager.getConnection(url, "user", "pword");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM table");
conn.close();
logger.debug("Closed Manger Test");
} catch (Exception ex) {
ex.printStackTrace();
logger.debug("Exception: {} ", ex.getMessage());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是因为由于 osgi 类加载器,commons-dbcp 包无法查看实际的驱动程序类。解决方案是使用 Dynamic Import * 将片段附加到 commons-dbcp 类。您在 MANIFEST 中需要的实际标头如下:
Fragment-Host: org.apache.commons.dbcp
DynamicImport-Package: *
之后,您提到的代码就起作用了。希望这不会来得太晚。
this is due to the fact that the commons-dbcp bundle cannot look at the actual driver class, because of the osgi class loader. The solution to this is to attach a fragment to the commons-dbcp class with Dynamic Import *. The actual headers that you need in your MANIFEST are the following:
Fragment-Host: org.apache.commons.dbcp
DynamicImport-Package: *
After this, the code you mentioned worked. Hope this doesnt come too late.