LWJGL を使用する 1 つの「ゲーム」のランチャーを作成しようとしており、そのクラスを他の JAR からロードする必要がありました。
だから私は次のことをしました:
// ...
// The files that i must load.
String[] files = new String[] { "lwjgl.jar", "jinput.jar", "lwjgl_util.jar", "game_jar.jar" };
// Converting strings to URLs
urls = new URL[files.length];
for ( int i = 0; i < files.length; i++ )
urls[i] = new File(directoryWithMyJARsAsFileClass, files[i]).toURI().toURL();
// I'ts needed too
System.setProperty("org.lwjgl.librarypath", directoryWithMyLWJGLNativessAsFileClass.getAbsolutePath() + File.separator);
System.setProperty("net.java.games.input.librarypath", directoryWithMyLWJGLNativessAsFileClass.getAbsolutePath() + File.separator);
// All paths are correct, I tested it.
// Class loading
URLClassLoader loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader())
// Object test = loader.loadClass("org.lwjgl.LWJGLException").newInstance(); // (2)
Object game = loader.loadClass("the.game.package.MainClass").newInstance(); // (1)
// ...
ただし、(1) でコードがエラーでクラッシュします。
Exception in thread "main" java.lang.NoClassDefFoundError: org/lwjgl/LWJGLException
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at my.own.packacge.MyLauncher.main(MyLauncher.java:##) <- ## pointing to (1)
Caused by: java.lang.ClassNotFoundException: org.lwjgl.LWJGLException
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 6 more
そして、(2) のコメントを外すと、org.lwjgl.LWJGLException のインスタンスが正常に作成され、それを使っていくつかのことができるようになります! クラス org.lwjgl.LWJGLException が読み込まれて動作しますが、ゲームはそれを使用できません。私の質問は「どのように?なぜ?」です。
また、ゲームのメイン クラスを逆コンパイルしたところ、org.lwjgl.LWJGLException が他の JAR から最初にインポートされていることがわかりました。
...
import some.import.Class;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.ContextCapabilities;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU;
import other.import.Class;
...
私はクラスローダーの初心者なので、愚かな間違いをしたのでしょうか? JAR からクラスをロードする他の簡単な方法が見つからなかったため、URLClassLoader を使用しました。他のプロジェクトでテストしましたが、問題なく動作します。