Java ClassLoader.defineClass上的NoClassDefFoundError(名称错误)

Java ClassLoader.defineClass上的NoClassDefFoundError(名称错误),java,class,byte,noclassdeffounderror,Java,Class,Byte,Noclassdeffounderror,我有一个类文件,通过对ClassLoader.defineClass的反射调用从中读取字节并定义到类对象中 我收到的NoClassDefFoundError消息是: Caused by: java.lang.NoClassDefFoundError: com/foo/sub/Foo (wrong name: com.foo.sub.Foo) 类文件是用包“com.foo.sub”编译的,因此类的完全限定名是“com.foo.sub.foo” 对defineClass的调用: byte[] fi

我有一个类文件,通过对ClassLoader.defineClass的反射调用从中读取字节并定义到类对象中

我收到的NoClassDefFoundError消息是:

Caused by: java.lang.NoClassDefFoundError: com/foo/sub/Foo (wrong name: com.foo.sub.Foo)
类文件是用包“com.foo.sub”编译的,因此类的完全限定名是“com.foo.sub.foo”

对defineClass的调用:

byte[] fileBytes;
//... read file
Method defineClass;
//... initialize and prepare Method for reflective call
Class clazz = defineClass.invoke("com.foo.sub.Foo", fileBytes, 0, fileBytes.length);
javadocs状态(关于defineClass的name参数):“名称-类的预期名称,如果未知,则为null,使用“.”和“/”作为分隔符,并且不带尾随的.class后缀。

我不明白为什么会抛出异常,以及消息应该指示什么。非常感谢您的帮助。

根据,如果您指定的名称(在您的示例中是
com.foo.sub.foo
)与类定义自身的名称(在
文件字节中)不匹配,则会引发
NoClassDefFoundError

要找到正确的名称,请尝试以下操作

System.out.println(defineClass.invoke(null, fileBytes, 0, fileBytes.length));

(应该打印类似于
class com.foo.sub.foo
)的内容。

有趣的是,它打印出的名称与我之前作为参数提供的名称相同。我没有意识到name参数可以为null。。。这是可以接受的,还是应该提供一个名称?@Matt:Re:你的第一句话:这很奇怪,不过想想看,这可能也是异常消息中的
com.foo.sub.foo
告诉我们的。我想知道是否有一些细微的区别,比如非ASCII字符或其他什么?回复:你的问题是:可以接受。在我链接到的文档中,它明确表示在名称“未知”时使用
null
。我假设预期的用例是“不知道,因为我们正在做有趣的动态事情”,而不是“不知道,因为出了问题”,但如果不知道,我不会告诉类加载器@马特:也许可以尝试
System.out.println(((Class)defineClass.invoke(null,fileBytes,0,fileBytes.length)).getName().equals(“com.foo.sub.foo”)
,只是为了确保键入的内容与所看到的内容完全匹配?