基于属性文件中的类路径加载Java类

时间:2009-04-21 19:59:00

标签: java jdbc properties classpath

我的应用程序使用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类加载器不在树中。麻烦的是,在我应该停止工作一整天之后很长一段时间(在英国),我无法想象如何以一种模糊整洁的方式解决它。

想法?

感谢。

2 个答案:

答案 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();