1

ClassNotFoundException: org.apache.commons.io.IOUtils次の状況で奇妙なことに直面しています。

commons-io 2.0.1 を使用する Websphere Application Server 8.0 で実行されている Web アプリケーションがあります (この jar はクラスパスに正しく配置されています)。

org.apache.commons.io.input.Tailerログファイルを追跡し、その内容を画面に表示するために使用しています。Tailer は Runnable を実装しているため、独自のスレッドで実行されます。

アプリケーションのシャットダウン時に、tailer.stop() を呼び出してスレッドを停止します。Tailer が最後に実行するのは、ログ リーダーを閉じる finally ブロックです。

} finally {
    IOUtils.closeQuietly(reader);
}

その行を実行すると、ClassNotFoundException: org.apache.commons.io.IOUtils.

ClassLoader の問題かどうかを判断するために、いくつかのコードを Tailer クラスに追加して (そして jar に置き換えて) いくつかのテストを行いました。

1. Tailer のリソースを決定します。

Tailer.class.getClassLoader().getResource("org/apache/commons/io/input/Tailer.class");

出力:wsjar:file:/home/myuser/.m2/repository/commons-io/commons-io/2.0.1/commons-io-2.0.1.jar!/org/apache/commons/io/input/Tailer.class これは正しい jar です

2. 使用しているクラスローダーは?: Tailer.class.getClassLoader();

com.ibm.ws.classloader.CompoundClassLoader@8d336acd[war:application/myApp.war]繰り返しますが、これは正しいです。

3. 前の ClassLoader から IOUtils を直接ロードしてみます。 Tailer.class.getClassLoader().loadClass("org.apache.commons.io.IOUtils");

再び ClassNotFoundException

4. ここで、最も驚くべきこと: 以下のように run メソッドの先頭に Class.forName() を追加すると、クラスが正しくロードされ、finally ブロックの IOUtils 呼び出しが機能するようになりました。どうして??

public void run() {
     RandomAccessFile reader = null;
     try {
         Class.forName("org.apache.commons.io.IOUtils");
     }catch(Exception e){
         e.printStackTrace();
     }         
     try {
         ...
         while (run) {
            ...
         }
     } catch (Exception e) {
         listener.handle(e);
     } finally {
         IOUtils.closeQuietly(reader);
     }
 }

 /**
 * Allows the tailer to complete its current loop and return.
 */
 public void stop() {
     this.run = false;
 }

意味がありません!commons-io-2.0.1.jar の Tailer を使用していますが、まったく同じ jar 内にあるクラスを使用することはできません。しかし、run() の開始時にクラスのロードを強制すると、もう失敗しなくなります。何か案は?

これはスタックトレース全体です:

Exception in thread "Thread-88" java.lang.NoClassDefFoundError: org.apache.commons.io.IOUtils
    at org.apache.commons.io.input.Tailer.run(Tailer.java:319)
    at java.lang.Thread.run(Thread.java:784)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.IOUtils
    at java.net.URLClassLoader.findClass(URLClassLoader.java:434)
    at com.ibm.ws.bootstrap.ExtClassLoader.findClass(ExtClassLoader.java:230)
    at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:703)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:682)
    at com.ibm.ws.bootstrap.ExtClassLoader.loadClass(ExtClassLoader.java:123)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:665)
    at com.ibm.ws.classloader.ProtectionClassLoader.loadClass(ProtectionClassLoader.java:62)
    at com.ibm.ws.classloader.ProtectionClassLoader.loadClass(ProtectionClassLoader.java:58)
    at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:566)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:665)
    at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:566)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:665)
    ... 2 more
4

1 に答える 1