0

我的应用程序使用 JDBC 数据库驱动程序。我从一个 jar 文件中加载这些文件,对于我目前正在使用的 DB2,我是 db2jcc.jar。在类路径中使用这个 jar,一切都很好,但我需要从应用程序配置文件中的属性中找到 jar - 例如,

database.driver=/opt/IBM/db2/V9.5/java/db2jcc.jar

我可以通过 URLClassLoader 加载类,但问题是我需要将由此创建的对象视为显式 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 类加载器不在树中它的上方。问题是,在我应该停止一天工作(在英国)之后很久,我想不出如何以一种模糊整洁和理智的方式最好地解决它。

想法?

谢谢。

4

2 回答 2

1

最简单的方法是只使用 java.beans API(或者如果必须的话直接反射)来调用 setter 方法。

或者:您的数据库代码需要链接到动态加载的代码。因此,动态加载您的数据库代码。多少取决于你。除了“引导程序”之外,您几乎可以加载所有内容。

于 2009-04-21T20:08:29.320 回答
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();
于 2009-04-21T20:34:52.970 回答