2012-07-09 51 views
0

因此,这里是字节码的片段,我正在尝试使用ASM的类验证,验证:ClassNotFound的错误

public <init>(Ljava/io/InputStream;)V 
    ALOAD 0 
    ALOAD 1 
    SIPUSH 2048 
    NEW org/apache/xerces/impl/msg/XMLMessageFormatter 
    DUP 
    INVOKESPECIAL org/apache/xerces/impl/msg/XMLMessageFormatter.<init>()V 
    INVOKESTATIC java/util/Locale.getDefault()Ljava/util/Locale; 
    INVOKESPECIAL org/apache/xerces/impl/io/UTF8Reader.<init> (Ljava/io/InputStream;ILorg/apache/xerces/util/MessageFormatter;Ljava/util/Locale;)V 
    RETURN 
    MAXSTACK = 5 
    MAXLOCALS = 2 

这是属于较大类org/apache/xerces/impl/io/UTF8Reader的一部分。现在,当我通过ASM提供的验证类运行这个类的字节码,我得到如下结果:

org.objectweb.asm.tree.analysis.AnalyzerException: **Error at instruction 7: java.lang.ClassNotFoundException: org.apache.xerces.util.MessageFormatter** 
    at org.objectweb.asm.tree.analysis.Analyzer.analyze(Unknown Source) 
    at org.objectweb.asm.util.CheckClassAdapter.verify(Unknown Source) 
    at org.objectweb.asm.util.CheckClassAdapter.verify(Unknown Source) 
    at org.objectweb.asm.util.CheckClassAdapter.main(Unknown Source) 
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.xerces.util.MessageFormatter 
    at org.objectweb.asm.tree.analysis.SimpleVerifier.getClass(Unknown Source) 
    at org.objectweb.asm.tree.analysis.SimpleVerifier.isAssignableFrom(Unknown Source) 
    at org.objectweb.asm.tree.analysis.SimpleVerifier.isSubTypeOf(Unknown Source) 
    at org.objectweb.asm.tree.analysis.BasicVerifier.naryOperation(Unknown Source) 
    at org.objectweb.asm.tree.analysis.BasicVerifier.naryOperation(Unknown Source) 
    at org.objectweb.asm.tree.analysis.Frame.execute(Unknown Source) 
    ... 4 more 
<init>(Ljava/io/InputStream;)V 
00000 UTF8Reader InputStream : :  ALOAD 0 
00001 UTF8Reader InputStream : UTF8Reader :  ALOAD 1 
00002 UTF8Reader InputStream : UTF8Reader InputStream :  SIPUSH 2048 
00003 UTF8Reader InputStream : UTF8Reader InputStream I :  NEW org/apache/xerces/impl/msg/XMLMessageFormatter 
00004 UTF8Reader InputStream : UTF8Reader InputStream I XMLMessageFormatter :  DUP 
00005 UTF8Reader InputStream : UTF8Reader InputStream I XMLMessageFormatter XMLMessageFormatter :  INVOKESPECIAL org/apache/xerces/impl/msg/XMLMessageFormatter.<init>()V 
00006 UTF8Reader InputStream : UTF8Reader InputStream I XMLMessageFormatter :  INVOKESTATIC java/util/Locale.getDefault()Ljava/util/Locale; 
00007 UTF8Reader InputStream : UTF8Reader InputStream I XMLMessageFormatter Locale :  INVOKESPECIAL org/apache/xerces/impl/io/UTF8Reader.<init> (Ljava/io/InputStream;ILorg/apache/xerces/util/MessageFormatter;Ljava/util/Locale;)V 
00008 ?  :  RETURN 

我深受这最后有点迷茫......为什么它给了ClassNotFound的第7行的org/apache/xerces/util/MessageFormatter对象异常?

谢谢。

+0

我熟悉Java而不是ASM。一些想法(道歉,如果这些太明显):所以你通过ASM加载UTF8Reader字节码?整个xerces jar是以这种方式加载的吗?或者只是一些课程? MessageFormatter如何?如果没有,你期望它进入classpath并加载? (可以帮助你知道你是如何调用ASM的。) – Will 2012-07-09 21:19:29

+0

所以我通过java.lang.instrument加载UTF8Reader和MessageFormatter。我基本上是编写一个java代理,它可以加载类的时间检测。现在,在加载类的字节码时,我将它们分别存储在它们自己的文件中,我将其用于稍后在脱机过程中进行验证,即在程序成功执行后进行验证。请注意,程序正在成功执行。谢谢。 – vijay 2012-07-09 21:46:36

+0

也,这可能也有帮助,http://mail-archive.ow2.org/asm/2011-08/msg00051.html这是否有任何意义?再次感谢。 – vijay 2012-07-09 21:49:51

回答

1

ASM的验证工具根据JVM规范检查每个堆栈和可变槽的有效性。其中一项检查是所有变量和堆栈槽中的值在合并点处具有相同的类型。所以,这个实现加载类来找到常见的超类型。

+0

谢谢!你是对的。检查器无法在加载它时找到org/apache/xerces/util/MessageFormatter的类文件,因此无法正确验证它。一旦我将它包含在类路径中,它就全部解决了。 – vijay 2012-07-10 17:31:02