我想了解为什么我们会遇到以下异常:
java.lang.NoClassDefFoundError: java/sql/Connection
首先,我要提供一些有关正在发生的事情的背景信息。我有一组包含在jar文件中的类,该文件被添加到引导类路径中。现在这些类具有传递给它们的实例,并且它们在这些实例上调用方法。在某些情况下,我们为传递的java.sql.Connection实例调用isClosed方法。此实例不是引导类路径的一部分,因此对我的类不可见。我了解如果我执行 Class.forName("java.sql.Connection");
,它将无法找到该类。这是可以理解的,但奇怪的是,如果我使用反射,那么我能够成功调用isClosed方法。这让我想知道是否必须更新线程上下文类加载器。检查上下文类加载器。它包含平台类加载器,允许我根据java 9迁移文档访问这些类。
好吧,这让我想知道是否有一个异常被抛出然后被捕获并抛出一个新的异常,而不是封装原始异常。我启用了jvmti异常回调并打印出已经引发/捕获的不同异常。此信息未提供与例外相关的任何信息。这是与该堆栈跟踪相关的唯一抛出的异常。看起来这是热点投掷的东西,而不是由java层生成的。
然后我尝试使用以下设置将 Add-Exports 属性添加到清单中 java.logging / java.util.logging = ALL-UNNAMED java.sql / java。 sql = ALL-UNNAMED java.xml / java.xml = ALL-UNNAMED java.xml / org.xml = ALL-UNNAMED java.xml / org.w3c = ALL-UNNAMED 但这没有帮助。
我甚至克隆了jdk 9来源,但无法找到任何关于如何调试此问题的线索。
顺便说一下,我尝试启用调试,但是jdwp代理中存在导致应用程序崩溃的错误,所以我甚至无法使用调试器来帮助我确定发生了什么。
任何想法,建议或线索都会受到高度赞赏,因为我已经没有关于如何解决这个问题的想法。
请注意,只有在使用java 9时才会出现此问题。我们的jar文件是使用java 5生成的,因为我们支持java 5或更高版本。