2009-04-21 124 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(); 
相關問題