2009-04-21 122 views
0

我的应用程序使用JDBC数据库驱动程序。我从一个jar文件加载这些,db2jcc.jar是我正在使用的DB2的情况。有了这个罐子在classpath中,一切都很好,但我有一个条件,找出从属性在应用程序的配置文件中的罐子代替 - 例如,根据属性文件中的类路径加载Java类

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类加载器不在树的上方,所以正在进入类加载程序纠结。问题是,在我应该停止工作一天之后(在英国这里),我想不出如何以最简单和最理智的方式解决问题。

想法?

谢谢。

回答

1

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

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

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(); 
相关问题