Search code examples
bytecodejava-bytecode-asm

ClassNotFound error during class verification with ASM's Class Verifier (org.objectweb.asm.util.CheckClassAdapter)


So here is a snippet of bytecode which i am trying to verify using ASM's class Verifier:

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

this is part of a larger class org/apache/xerces/impl/io/UTF8Reader. Now, when i run the the bytecode of this class through the Class verifier provided by ASM, I get the following results:

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

I am highly confused by this last bit... why is it giving out a ClassNotFound exception for the org/apache/xerces/util/MessageFormatter object at line 7?

Thanks.


Solution

  • ASM's verifier tool does check validity of each stack and variable slot as per JVM specification. One of the checks is that values in all variable and stack slots have the same types at merge points. So, this implementation loads classes to find common super types.