我试图做java类加载。我在macos yosemite上使用了带有1.8.0_25的eclipse(luna)。
我使用以下代码来执行此操作。它正在工作,直到它到达一个具有依赖关系的类,该依赖关系不包含在我从中加载类的jar中。对环境都没有。
我对这个课程不感兴趣,因此,忽略它是安全的。所以,我把它放在try / catch中,然后记录它。
但是,当发生异常时,执行将被取消。
例外(总结)是:
Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/runtime/internal/AroundClosure
Caused by: java.lang.ClassNotFoundException: org.aspectj.runtime.internal.AroundClosure
它在内部try / catch块内的确切线上升。
为什么呢?不应该尝试使用try / catch来记录它并继续前进吗?
URLClassLoader ucl = null;
try {
URL url = Utils.getURIFromPath(jarFilePath).toURL();
URL[] urls = new URL[] { url };
ucl = new URLClassLoader(urls);
for (String tmp : classes) {
String clazz = tmp.substring(0, tmp.indexOf(".class")).replaceAll("/", ".");
try {
ucl.loadClass(clazz);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
} catch (MalformedURLException e) {
LOGGER.error(e.getMessage(), e);
} finally {
if (ucl != null) {
try {
ucl.close();
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
答案 0 :(得分:6)
NoClassDefFoundError
是错误,而不是Exception
,你应该从不 1 尝试{{1错误,as stated here,抓住它对你没有帮助。
检查你的类路径并修复它。
1 在某些情况下,您可能希望catch
出现错误并相应地处理,如评论中所述,可能“ never ”有点有点强烈
答案 1 :(得分:2)
好的,试试这个:
catch (Throwable e) {
LOGGER.error(e.getMessage(), e);
}
虽然使用上面的代码会同时处理错误和异常(都来自Throwable
),但这不是正确的方法,只有在非常特殊的情况下我们才能使用try-catch处理错误,错误是我们需要检查我们的代码并解决它们。
答案 2 :(得分:1)
您正在使用的其中一个类(可能是您尝试使用loadClass
加载的类之一)似乎具有依赖来自 AspectJ 的类,但ClassLoader没有找到AspectJ类。一个可能的解决方案是在执行此操作时确保AspectJ在您的类路径。
也可能是AspectJ已经在类路径上了。如果是这种情况,那只是因为URLClassLoader
不了解您的ClassPath。您可能希望使用父URLClassLoader
构建ClassLoader
,如下所示:
ucl = new URLClassLoader(urls, getClass().getClassLoader());
该计划之所以没有继续下去,是因为您正在抓住Exception
。层次结构为class Throwable
,class Exception extends Throwable
和class Error extends Throwable
,因此catch (Exception e)
将无法捕获Error
。在这种特殊情况下,您可能希望使用catch(Exception | NoClassDefFoundError e)
。通常,捕获错误不是一个好主意,但有时会出现NoClassDefFoundError
,OutOfMemoryError
或StackOverflowError
等错误的合理例外情况。