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 はそのメソッドの 1 つにあります。)

クラスをロードしたクラスローダーがキャストを行うために DB2XADataSource を見つけようとしているのに、URL クラスローダーがツリー内でその上にないため、クラスローダーのもつれに陥っていると思います。問題は、その日 (ここイギリスで) 仕事をやめるべきだったのに、ずいぶんと時間が経ってしまったということです。

アイデア?

ありがとう。

4

2 に答える 2

1

最も簡単な方法は、java.beans API (または必要に応じて直接リフレクション) を使用してセッター メソッドを呼び出すことです。

または: データベース コードは、動的にロードされるコードにリンクする必要があります。したがって、データベース コードを動的にロードします。いくらかはあなた次第です。「ブートストラップ」以外のほとんどすべてをロードできます。

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