尝试/捕获未捕获异常

3

我正在尝试进行Java类加载。我在使用macOS Yosemite上的eclipse(luna)和1.8.0_25。

我正在使用以下代码来实现它。它可以正常工作,直到它到达一个具有未包含在我从中加载类的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);
        }
    }
}

1
堆栈跟踪中出现了什么问题?原因是:java.lang.ClassNotFoundException。 - committedandroider
2
修复你的类路径。看起来你的类路径中缺少 aspectj.jar 文件。 - JB Nizet
1
这是真的吗?该行以“Exception in thread”开头。 - user3282276
1
快来看看这个类的名称和它的javadoc:https://docs.oracle.com/javase/7/docs/api/java/lang/NoClassDefFoundError.html - JB Nizet
3个回答

7
NoClassDefFoundError是一个Error,而不是一个Exception,你绝不能1尝试去catch一个error,正如官方文档中所述,捕获它也没有用处。

请检查你的classpath并进行修复。

1在某些情况下,您可能希望尝试捕获错误并相应地处理,正如评论中所述,也许“绝不能”这个说法有点过于严格了。


2
永远是一个很强的话语。尝试 { array = new byte[bufsize]; } 捕获 (final OutOfMemoryError e) { // ... } 这看起来对我来说完全没问题。 - Christian Hujer

3
好的,请尝试以下方法:
catch (Throwable e) {
LOGGER.error(e.getMessage(), e);
}

尽管使用上述代码可以为您处理错误和异常(两者都扩展自Throwable),但这不是正确的做法,只有在非常特殊的情况下,我们才使用try-catch来处理错误,错误是我们需要在代码中检查并解决的问题。


1
捕获错误并不能解决问题,只会掩盖它。原始问题需要修复其类路径。捕获Throwble是一种不好的做法,这样做什么都解决不了。 - JB Nizet
1
@JB,没错,但那个人似乎只是捕捉了错误而没有以正确的方式修复它,所以我发布了这个解决方案,我认为我应该编辑我的答案并告诉他。 - Sarthak Mittal

2
似乎你正在使用的类之一,很可能是你试图用loadClass加载的类,对来自AspectJ的类有一个依赖关系,但是ClassLoader无法找到AspectJ的类。可能的解决方案是,在执行此操作时确保AspectJ在你的类路径上

也有可能AspectJ已经在classpath中。如果是这种情况,只是你的URLClassLoader不知道你的ClassPath。你可能想要构造一个带有父ClassLoaderURLClassLoader,像这样:

ucl = new URLClassLoader(urls, getClass().getClassLoader());

程序不继续执行的原因是你捕获了Exception。继承关系为class Throwableclass Exception extends Throwableclass Error extends Throwable,所以catch (Exception e)无法捕获Error。在这种特殊情况下,您可能需要使用catch(Exception | NoClassDefFoundError e)。通常,捕获错误并不是一个好主意,但有时候像NoClassDefFoundErrorOutOfMemoryErrorStackOverflowError这样的错误也有合理的例外。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接