私は経験豊富なプログラムですが、これまで修正できなかったこの非常に奇妙な問題に遭遇しました。次のエラーが表示されます。
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: rec/MiscIO
at rec.RECTool.run(RECTool.java:264)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: rec.MiscIO
at java.net.URLClassLoaderrun(Unknown Source)
at java.net.URLClassLoaderrun(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)
... 2 more
関連する行は次のとおりです。
File savedTo = MiscIO.copyJar(root);
私が理解していないのは、これが小さなアプリケーションであり、使用中のクラスが同じパッケージにあるということです。クラス名と内容以外は基本的に同じ設定。ただし、すべてではなく、一部のクラスでのみエラーが発生します。エラーが発生する前にこれらの行を使用しますが、これらは同じパッケージとすべてに含まれています。
Logger.log("Found new root: " + newRoots[i0]);
...
FileLocker locker = new FileLocker();
...
locker.lock(PathManager.getJar());
したがって、エラーのあるクラスの設定と基本的に同一の 3 つのクラスのうち、例外をスローするクラスは 1 つだけです。これは私には意味がありません。
クラスパスの変更や、jar コマンドを使用する代わりにメイン クラスを直接呼び出すなど、jar を実行するためにさまざまな引数を試しましたが、次のように役に立ちませんでした。
java -jar <jarname>
java -cp . <jarname>
java -cp <jarname> -jar <jarname>
java -cp <jarname> <main class here>
ただし、jar を解凍してプログラムを実行すると、エラーは発生しません。MiscIO の読み込みに失敗したか、静的初期化子の読み込みに失敗したことに依存している可能性があると思いましたが、どちらも私のコードにはありません。
また、Netbeans を使用して jar を生成しており、マニフェストが正しく設定されています。コード全体は次のとおりです。
package rec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.URL;
/**
* @author Colby
*/
public class MiscIO {
public static void copyJar(RandomAccessFile out) throws IOException {
URL jarSource = RECTool.class.getProtectionDomain().getCodeSource().getLocation();
InputStream in = null;
try {
in = jarSource.openStream();
copyToRAF(in, out);
} finally {
if (in != null) {
in.close();
}
}
}
public static File copyJar(File saveJarTo) throws IOException {
URL jarSource = RECTool.class.getProtectionDomain().getCodeSource().getLocation();
saveJarTo = new File(saveJarTo, "classlist.jar");
InputStream in = null;
OutputStream out = null;
try {
in = jarSource.openStream();
out = new FileOutputStream(saveJarTo);
copyStream(in, out);
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
return saveJarTo;
}
public static void copyStream(InputStream in, OutputStream out) throws IOException {
int len;
byte[] data = new byte[1024 * 8];
while ((len = in.read(data)) != -1) {
out.write(data, 0, len);
}
out.flush();
}
public static void copyToRAF(InputStream in, RandomAccessFile raf) throws IOException {
raf.seek(0L);
int len;
byte[] data = new byte[1024 * 8];
while ((len = in.read(data)) != -1) {
raf.write(data, 0, len);
}
}
public static void copyFile(File from, File to) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(from);
out = new FileOutputStream(to);
copyStream(in, out);
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
最後に、自分のマシンにインストールされている Java のバージョンが競合している可能性があるか、まぐれによる x86/x64 の競合である可能性があると考えたため、すべての Java ディストリビューションをアンインストールし、1 つのアーキテクチャの最新のもののみをインストールしましたが、問題は残ります。このようなものを見た人はいますか?