質問

データベースへのJDBC接続をテストする必要があります。それを行うJavaコードは次のように単純でなければなりません:

DriverManager.getConnection("jdbc connection URL", "username", "password");

ドライバーマネージャーは、指定された接続URLの適切なドライバーを検索します。ただし、実行時にJDBCドライバー(jar)をロードできる必要があります。つまり、上記のコードのスニペットを実行するJavaアプリケーションのクラスパスにJDBCドライバーがありません。

そのため、このコードを使用してドライバーをロードできます。例:

URLClassLoader classLoader = new URLClassLoader(new URL[]{"jar URL"}, this.getClass().getClassLoader());
Driver driver = (Driver) Class.forName("jdbc driver class name", true, classLoader).newInstance();

しかし、ドライバーマネージャーは、どのクラスローダーを使用するのかわからないため、それを選択しません。現在のスレッドのコンテキストクラスローダーを設定しようとしましたが、まだ機能しません。

誰でもそれを達成するための最良の方法について何か考えがありますか?

役に立ちましたか?

解決

記事実行時にJDBCドライバーを選択;参照用にここにコードを投稿するだけです。

アイデアは、ドライバーがシステムクラスローダーからロードされたとドライバーマネージャーに思い込ませることです。これを行うには、次のクラスを使用します。

public class DelegatingDriver implements Driver
{
    private final Driver driver;

    public DelegatingDriver(Driver driver)
    {
        if (driver == null)
        {
            throw new IllegalArgumentException("Driver must not be null.");
        }
        this.driver = driver;
    }

    public Connection connect(String url, Properties info) throws SQLException
    {
       return driver.connect(url, info);
    }

    public boolean acceptsURL(String url) throws SQLException
    {
       return driver.acceptsURL(url);
    }

    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException
    {
        return driver.getPropertyInfo(url, info);
    }

    public int getMajorVersion()
    {
        return driver.getMajorVersion();
    }

    public int getMinorVersion()
    {
        return driver.getMinorVersion();
    }

    public boolean jdbcCompliant()
    { 
        return driver.jdbcCompliant();
    }
}

この方法で登録するドライバーは、システムクラスローダーでロードされる DelegatingDriver タイプです。必要なクラスローダーを使用して、本当に使用したいドライバーをロードするだけです。例:

URLClassLoader classLoader = new URLClassLoader(new URL[]{"path to my jdbc driver jar"}, this.getClass().getClassLoader());
Driver driver = (Driver) Class.forName("org.postgresql.Driver", true, classLoader).newInstance();
DriverManager.registerDriver(new DelegatingDriver(driver)); // register using the Delegating Driver

DriverManager.getDriver("jdbc:postgresql://host/db"); // checks that the driver is found

他のヒント

問題は、 DriverManager が「即時の呼び出し元のクラスローダーインスタンスを使用して」タスクを実行することです。 のガイドライン6-3を参照してください。 Javaプログラミング言語、バージョン2.0 。この場合、システムクラスローダーは特別なものではありません。

キックのためだけに、私はしばらく前にこの主題についてブログエントリを作成しました。私のソリューションは、 Nick Sayerのソリューションよりも複雑ですが、より完全です信頼できないコードでも動作します。また、新しいURLClassLoader よりも URLClassLoader.newInstance が優先されることに注意してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top