我的应用程序使用JDBC数据库驱动程序。我在目前正在使用的DB2的情况下从jar文件db2jcc.jar加载这些文件。在类路径中使用此jar,一切都很好,但我需要从应用程序的配置文件中的属性中找到jar - 例如,
database.driver=/opt/IBM/db2/V9.5/java/db2jcc.jar
我可以通过URLClassLoader ok加载类,但问题是我需要将这样创建的对象视为显式DB2XADataSource。例如:
URLClassLoader dbClassLoader = new URLClassLoader(new URL[]{driverJar});
xaClass = dbClassLoader.loadClass("com.ibm.db2.jcc.DB2XADataSource");
DB2XADataSource dataSource = (DB2XADataSource) xaClass.newInstance();
dataSource.setCurrentSchema(DATABASE_SCHEMA); // <- dataSource has to be a
dataSource.setDatabaseName(DATABASE_NAME); // DB2XADataSource to do this
(重新排列并重命名;我实际上在包含此代码的类的构造函数中执行loadClass,而newInstance在其中一个方法中。)
我想我正在进入一个类加载器纠结,因为加载我的类的类加载器试图找到DB2XADataSource来进行转换,但是URL类加载器不在树中。麻烦的是,在我应该停止工作一整天之后很长一段时间(在英国),我无法想象如何以一种模糊整洁的方式解决它。
想法?
感谢。
答案 0 :(得分:1)
最简单的方法是使用java.beans API(如果必须,直接反射)来调用setter方法。
或者:您的数据库代码需要链接到动态加载的代码。因此,动态加载数据库代码。多少钱取决于你。除了“bootstrap”之外,您几乎可以加载所有内容。
答案 1 :(得分:0)
是的 - 该类无法加载自己的依赖项。你可以做一些ClassLoader魔法,但我想它会很快变得混乱。
减少反射量的一种方法是将依赖于 DB2XADataSource 的任何代码放入通过调用ClassLoader可用的接口调用的实现中。
//in mydb2driver.jar
public class MyDb2Driver implements IDriver {
private DB2XADataSource dataSource = new DB2XADataSource();
public void init() {
dataSource.setCurrentSchema(DATABASE_SCHEMA);
}
//etc.
}
这是你的驱动程序:
database.driver=/opt/IBM/db2/V9.5/java/db2jcc.jar:/foo/mydb2driver.jar
调用代码位于常规类路径中:
public interface IDriver {
public void init();
//etc.
}
...
URLClassLoader dbClassLoader = new URLClassLoader(new URL[]{driverJar});
xaClass = dbClassLoader.loadClass("foo.MyDb2Driver");
IDriver dataSource = (IDriver) xaClass.newInstance();
dataSource.init();