ClassNotFoundException: org.apache.commons.io.IOUtils
在以下情况下,我面临着一个奇怪的问题:
我有一个在 Websphere Application Server 8.0 中运行的 Web 应用程序,它使用 commons-io 2.0.1(这个 jar 正确放置在类路径中)。
我正在使用org.apache.commons.io.input.Tailer
尾随日志文件并在屏幕上显示其内容。Tailer 实现了 Runnable,因此它在自己的线程中运行。
在应用程序关闭时,我调用 tailer.stop() 来停止线程。然后 Tailer 执行的最后一件事是关闭日志阅读器的 finally 块。
} finally {
IOUtils.closeQuietly(reader);
}
当它执行该行时,会有一个ClassNotFoundException: org.apache.commons.io.IOUtils
.
我做了一些测试,将一些代码添加到 Tailer 类中(并在 jar 中替换它)以确定它是否是 ClassLoader 问题:
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
这是正确的罐子
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