为静态方法而不是静态成员抛出java.lang.NoClassDefFoundError

为静态方法而不是静态成员抛出java.lang.NoClassDefFoundError,java,exception,dnsjava,Java,Exception,Dnsjava,使用该库时,我遇到了一个令人沮丧和困惑的问题,我可以正确调用Type.a,但调用Type.value(str)会抛出java.lang.NoClassDefFoundError System.out.println(org.xbill.DNS.Type.A); // works if (org.xbill.DNS.Type.value(type) == -1) { // throws NoClassDefFoundError /* logic */ } 此代码是从jar执行的,j

使用该库时,我遇到了一个令人沮丧和困惑的问题,我可以正确调用
Type.a
,但调用
Type.value(str)
会抛出
java.lang.NoClassDefFoundError

System.out.println(org.xbill.DNS.Type.A);    // works

if (org.xbill.DNS.Type.value(type) == -1) {  // throws NoClassDefFoundError
  /* logic */
}
此代码是从
jar执行的
,jar中的其他类正确使用库

为什么会发生这种情况,又是如何发生的?我如何进一步调试它

谢谢

编辑

乔恩·斯基特是对的。一位朋友向我展示了如何使用
javap-c
,我将值更改为更独特的Type.AAAA,它的值为28:

878: getstatic       #116; //Field java/lang/System.out:Ljava/io/PrintStream;
881: bipush  28

您可能缺少运行时上的
Type
类。您需要使用
-cp
参数运行jar。

引发运行时异常时
类型的值是多少?如果您阅读java文档,它将
将类型的字符串表示形式转换为其数值。它可能通过反射性地实例化它或通过一些垃圾来实现这一点。如果您对没有关联的
type
的类型字符串运行此方法,我认为您得到此错误是完全合理的


步骤1:打印字符串类型,并确保该类型的类位于类路径上

听起来您在执行时缺少了
dnsjava


这对于
Type.A来说并不重要,因为这是一个常量-编译器会将该值提取出来并直接嵌入到代码中,就像您将其指定为整数文本一样。它不需要库在执行时出现。但是,当您调用一个方法时,情况显然不是这样。

添加
-verbose:class
命令行参数是否揭示了什么?通常,当您遇到此错误时,会丢失另一个类,该类由您要加载的类引用。能否显示NoClassDefFoundError的完整堆栈跟踪?至少在三种不同的情况下会引发此错误。没错,键入.A是一个
int
,因此可以直接将值拉入。仅仅是常量这一事实是不够的,如果它是
类型
的常量,它就不会工作。@biziclop:在JLS术语中它不会是常量在这种情况下:)“原语类型或字符串类型的变量,是最终的,并用编译时常量表达式(§15.28)初始化,称为常量变量。”@Jon没有说过其他类在运行时正确地使用了这个库的某些部分?@nsfyn55:我错过了这一点-但我怀疑这不是真的:)(或者,他们可能正在使用一些旧版本或类似的东西。)@JonSkeet谢谢,我确信这正是发生的事情。