2009-04-21 17 views
0

私のアプリケーションはJDBCデータベースドライバを使用します。私は現在作業しているDB2の場合、jarファイルdb2jcc.jarからこれらをロードします。クラスパスにこのjarを使用すると、すべてが正常であるが、私は代わりに、アプリケーションの設定ファイルにプロパティからjarファイルを見つけるための要件が​​ある - 例えば、プロパティファイル内のクラスパスに基づいてJavaクラスをロード

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

を私は、[OK]の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 

(再配置と多少名前を変更;のnewInstanceは、その方法の一つである間、私は実際には、このコードを含むクラスのコンストラクタでのloadClassを行います。)

私は私の推測私のクラスをロードしたクラスローダーがキャストを行うためにDB2XADataSourceを見つけようとしているので、クラスローダーが複雑になってしまいましたが、URLクラスローダーはツリーの上にありません。問題は、私が一日働いていなくてはならないと思っています(ここでは英国です)。

アイデア?

ありがとうございました。

答えて

1

最も簡単な方法は、setterメソッドを呼び出すためにjava.beans API(または必要ならば直接反映)を使用することです。

または、データベースコードで動的にロードされたコードにリンクする必要があります。したがって、データベースコードを動的にロードします。あなた次第です。あなたは "ブートストラップ"を除いてほとんどすべてをロードするかもしれません。

0

はい - クラスは独自の依存関係を読み込むことができません。 ClassLoaderのいくつかの魔法を使うことができますが、それは非常に手早く乱雑になると思います。

リフレクションの量を減らす1つの方法は、に依存するコードを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(); 
関連する問題