web-dev-qa-db-ja.com

Java 9の下で実行時にクラスパスにjarを追加します

Java9 まで、プログラムで使用するすべての人が実行時にクラスパスに外部jarを追加します。

URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
method.invoke(sysloader, new Object[]{file.toURI().toURL()});

Java9では、問題が発生します。

スレッド「メイン」の例外Java.lang.ClassCastException:Java.base/jdk.internal.loader.ClassLoaders $ AppClassLoaderをJava.base/Java.net.URLClassLoaderにキャストできません

URLClassLoaderはJava 9.では機能しなくなりました。実行時にプログラムで外部jarをクラスパスに追加するには、jdk9で何をしますか?

12
Evgeniy Egorov

JavaSE9リリースノート ほぼ同じことを読んでください:

アプリケーションクラスローダーは、_Java.net.URLClassLoader_(以前のリリースでは指定されていなかった実装の詳細)のインスタンスではなくなりました。

_ClassLoader::getSytemClassLoader_URLClassLoaderオブジェクトを返すことを前提とするコードを更新する必要があります。

Java SEとJDKは、実行時にクラスパスを動的に拡張するためのアプリケーションまたはライブラリ用のAPIを提供しないことに注意してください

さらに、拡張クラスパスが必要な場合は、

_Class<?> clazz = Class.forName("nameofclass", true, new URLClassLoader(urlarrayofextrajarsordirs));
_

これで提案されているように Oracleからのスレッド 。これには注意が必要です。

  • _Java.util.ServiceLoader_は、スレッドのClassLoaderコンテキストThread.currentThread()。setContextClassLoader(specialloader);を使用します。

  • _Java.sql.DriverManager_は、スレッドのClassLoaderではなく、呼び出し元のクラス 'ClassLoaderを尊重します。 Class.forName("drivername", true, new URLClassLoader(urlarrayofextrajarsordirs).newInstance();を使用して直接ドライバーを作成します

  • _javax.activation_は、スレッドのClassLoaderコンテキストを使用します(javax.mailにとって重要)。

7
Naman