5

実行時にjarファイルをクラスパスに追加しようとしています。私はこのコードを使用します

 public static void addURL(URL u) throws IOException {

            URLClassLoader sysloader = (URLClassLoader) ClassLoader
                    .getSystemClassLoader();
            Class<URLClassLoader> sysclass = URLClassLoader.class;

            try {
                Method method = sysclass.getDeclaredMethod("addURL", parameters);
                method.setAccessible(true);
                method.invoke(sysloader, new Object[] { u });
                System.out.println(u);
            } catch (Throwable t) {
                t.printStackTrace();
                throw new IOException("Error");
            }

        }

システム出力は次の URL を出力します。

file:/B:/Java/Tools/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18/mysql-connector-java-5.1.18-bin.jar

このパスを注意深く確認したところ、この jar が存在します。このテストでも、com.mysql.jdbc. ドライバークラスが存在します。

javap -classpath "B:\Java\Tools\mysql-connector-java-5.1.18\
mysql-connector-java-5.1.18\mysql-connector-java-5.1.18-bin.jar" com.mysql.jdbc.
Driver
Compiled from "Driver.java"
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver i
mplements java.sql.Driver{
    public com.mysql.jdbc.Driver()       throws java.sql.SQLException;
    static {};
}

しかし、この Class.forName(driver) を使用すると、依然として java.lang.ClassNotFoundException が発生します。このコードの何が問題になっていますか?

4

2 に答える 2

5

URLは問題ありませんが、クラスパスからjarをロードしようとしているため、最初にファイルをcpに入れる必要があります。クラスパスにないjarをロードする場合は、URLClassLoaderを使用する必要があります。また、JARの場合は、JARClassLoaderも使用できます。サンプルレッスンが必要な場合は、http://docs.oracle.com/javase/を参照してください 。チュートリアル/デプロイメント/jar/jarclassloader.html

ここで私が自分で実行したサンプルがあなたに役立つかどうかを確認します。クラスパスにないLog4jのLoggerクラスを検索します。もちろん、コンストラクターに正しいパラメーターを渡さなかったため、コンストラクターの呼び出しで例外が発生しました。

package org.stackoverflow;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

public class URLClassLoaderSample
{
  public static void main(String[] args) throws Exception
  {
    File f = new File("C:\\_programs\\apache\\log4j\\v1.1.16\\log4j-1.2.16.jar");
    URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL()},System.class.getClassLoader());
    Class log4jClass = urlCl.loadClass("org.apache.log4j.Logger");
    log4jClass.newInstance();
  }
}



Exception in thread "main" java.lang.InstantiationException: org.apache.log4j.Logger
    at java.lang.Class.newInstance0(Class.java:357)
    at java.lang.Class.newInstance(Class.java:325)
    at org.stackoverflow.URLClassLoaderSample.main(URLClassLoaderSample.java:19)

間違った呼び出しによる例外ですが、この段階ではすでにクラスが見つかりました

于 2012-05-16T19:30:24.070 に答える
1

直接ドライバーではなく、DataSource を使用した代替アプローチを試してみてください。以下はコードです (Oracle ドライバーを使用しています。SQL データベースはありませんが、プロパティは同じです)。JDBC 2.0 以降、一般的に DataSource インターフェイスを使用することが推奨されるアプローチです。 DataSource jar は、以下のテストでもクラスパスにありませんでした

public static void urlCLSample2() throws Exception
{

    File f = new File("C:\\_programs\\jdbc_drivers\\oracle\\v11.2\\ojdbc6.jar");

    URLClassLoader urlCl = new URLClassLoader(new URL[] { f.toURL() }, System.class.getClassLoader());
    // replace the data source class with MySQL data source class.
    Class dsClass = urlCl.loadClass("oracle.jdbc.pool.OracleDataSource");
    DataSource ds = (DataSource) dsClass.newInstance();

    invokeProperty(dsClass, ds, "setServerName", String.class, "<put your server here>");
    invokeProperty(dsClass, ds, "setDatabaseName", String.class, "<put your db instance here>");
    invokeProperty(dsClass, ds, "setPortNumber", int.class, <put your port here>);
    invokeProperty(dsClass, ds, "setDriverType",String.class, "thin");
    ds.getConnection("<put your username here>", "<put your username password here>");

    System.out.println("Got Connection");
  }

  // Helper method to invoke properties
  private static void invokeProperty(Class dsClass, DataSource ds, String propertyName, Class paramClass,
      Object paramValue) throws Exception
  {
    try
    {
      Method method = dsClass.getDeclaredMethod(propertyName, paramClass);
      method.setAccessible(true);
      method.invoke(ds, paramValue);
    }
    catch (Exception e)
    {
      throw new Exception("Failed to invoke method");
    }
  }
于 2012-05-17T15:07:24.553 に答える