public class CheckClassAdapter
extends org.objectweb.asm.ClassVisitor
ClassVisitor
that checks that its methods are properly used. More precisely this class
adapter checks each method call individually, based only on its arguments, but does
not check the sequence of method calls. For example, the invalid sequence
visitField(ACC_PUBLIC, "i", "I", null) visitField(ACC_PUBLIC, "i", "D", null)
will not be detected by this class adapter.
CheckClassAdapter
can be also used to verify bytecode transformations in order to
make sure that the transformed bytecode is sane. For example:
InputStream inputStream = ...; // get bytes for the source class ClassReader classReader = new ClassReader(inputStream); ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS); ClassVisitor classVisitor = new MyClassAdapter(new CheckClassAdapter(classWriter, true)); classReader.accept(classVisitor, 0); StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); CheckClassAdapter.verify(new ClassReader(classWriter.toByteArray()), false, printWriter); assertTrue(stringWriter.toString().isEmpty());The above code pass the transformed bytecode through a
CheckClassAdapter
, with data
flow checks enabled. These checks are not exactly the same as the JVM verification, but provide
some basic type checking for each method instruction. If the bytecode has errors, the output text
shows the erroneous instruction number, and a dump of the failed method with information about
the type of the local variables and of the operand stack slots for each instruction. For example
(format is - insnNumber locals : stack):
org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found . at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:...) at org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:...) ... remove()V 00000 LinkedBlockingQueue$Itr . . . . . . . . : ICONST_0 00001 LinkedBlockingQueue$Itr . . . . . . . . : I ISTORE 2 00001 LinkedBlockingQueue$Itr . I . . . . . . : ... 00071 LinkedBlockingQueue$Itr . I . . . . . . : ILOAD 1 00072 ? INVOKESPECIAL java/lang/Integer.<init> (I)V ...The above output shows that the local variable 1, loaded by the
ILOAD 1
instruction
at position 00071
is not initialized, whereas the local variable 2 is initialized
and contains an int value.Modifier | Constructor and Description |
---|---|
|
CheckClassAdapter(org.objectweb.asm.ClassVisitor classVisitor)
Constructs a new
CheckClassAdapter . |
|
CheckClassAdapter(org.objectweb.asm.ClassVisitor classVisitor,
boolean checkDataFlow)
Constructs a new
CheckClassAdapter . |
protected |
CheckClassAdapter(int api,
org.objectweb.asm.ClassVisitor classVisitor,
boolean checkDataFlow)
Constructs a new
CheckClassAdapter . |
Modifier and Type | Method and Description |
---|---|
static void |
checkClassSignature(java.lang.String signature)
Checks a class signature.
|
static void |
checkFieldSignature(java.lang.String signature)
Checks a field signature.
|
static void |
checkMethodSignature(java.lang.String signature)
Checks a method signature.
|
static void |
main(java.lang.String[] args)
Checks the given class.
|
static void |
verify(org.objectweb.asm.ClassReader classReader,
boolean printResults,
java.io.PrintWriter printWriter)
Checks the given class.
|
static void |
verify(org.objectweb.asm.ClassReader classReader,
java.lang.ClassLoader loader,
boolean printResults,
java.io.PrintWriter printWriter)
Checks the given class.
|
void |
visit(int version,
int access,
java.lang.String name,
java.lang.String signature,
java.lang.String superName,
java.lang.String[] interfaces) |
org.objectweb.asm.AnnotationVisitor |
visitAnnotation(java.lang.String descriptor,
boolean visible) |
void |
visitAttribute(org.objectweb.asm.Attribute attribute) |
void |
visitEnd() |
org.objectweb.asm.FieldVisitor |
visitField(int access,
java.lang.String name,
java.lang.String descriptor,
java.lang.String signature,
java.lang.Object value) |
void |
visitInnerClass(java.lang.String name,
java.lang.String outerName,
java.lang.String innerName,
int access) |
org.objectweb.asm.MethodVisitor |
visitMethod(int access,
java.lang.String name,
java.lang.String descriptor,
java.lang.String signature,
java.lang.String[] exceptions) |
org.objectweb.asm.ModuleVisitor |
visitModule(java.lang.String name,
int access,
java.lang.String version) |
void |
visitOuterClass(java.lang.String owner,
java.lang.String name,
java.lang.String descriptor) |
void |
visitSource(java.lang.String file,
java.lang.String debug) |
org.objectweb.asm.AnnotationVisitor |
visitTypeAnnotation(int typeRef,
org.objectweb.asm.TypePath typePath,
java.lang.String descriptor,
boolean visible) |
public CheckClassAdapter(org.objectweb.asm.ClassVisitor classVisitor)
CheckClassAdapter
. Subclasses must not use this constructor.
Instead, they must use the CheckClassAdapter(int, ClassVisitor, boolean)
version.classVisitor
- the class visitor to which this adapter must delegate calls.public CheckClassAdapter(org.objectweb.asm.ClassVisitor classVisitor, boolean checkDataFlow)
CheckClassAdapter
. Subclasses must not use this constructor.
Instead, they must use the CheckClassAdapter(int, ClassVisitor, boolean)
version.classVisitor
- the class visitor to which this adapter must delegate calls.checkDataFlow
- whether to perform basic data flow checks. This option requires valid
maxLocals and maxStack values.java.lang.IllegalStateException
- If a subclass calls this constructor.protected CheckClassAdapter(int api, org.objectweb.asm.ClassVisitor classVisitor, boolean checkDataFlow)
CheckClassAdapter
.api
- the ASM API version implemented by this visitor. Must be one of Opcodes.ASM4
, Opcodes.ASM5
or Opcodes.ASM6
.classVisitor
- the class visitor to which this adapter must delegate calls.checkDataFlow
- true to perform basic data flow checks, or false to not
perform any data flow check (see CheckMethodAdapter
). This option requires valid
maxLocals and maxStack values.public static void main(java.lang.String[] args) throws java.io.IOException
Usage: CheckClassAdapter <binary class name or class file name>
args
- the command line arguments.java.io.IOException
- if the class cannot be found, or if an IO exception occurs.public static void verify(org.objectweb.asm.ClassReader classReader, boolean printResults, java.io.PrintWriter printWriter)
classReader
- the class to be checked.printResults
- whether to print the results of the bytecode verification.printWriter
- where the results (or the stack trace in case of error) must be printed.public static void verify(org.objectweb.asm.ClassReader classReader, java.lang.ClassLoader loader, boolean printResults, java.io.PrintWriter printWriter)
classReader
- the class to be checked.loader
- a ClassLoader
which will be used to load referenced classes. May be
null.printResults
- whether to print the results of the bytecode verification.printWriter
- where the results (or the stack trace in case of error) must be printed.public void visit(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces)
visit
in class org.objectweb.asm.ClassVisitor
public void visitSource(java.lang.String file, java.lang.String debug)
visitSource
in class org.objectweb.asm.ClassVisitor
public org.objectweb.asm.ModuleVisitor visitModule(java.lang.String name, int access, java.lang.String version)
visitModule
in class org.objectweb.asm.ClassVisitor
public void visitOuterClass(java.lang.String owner, java.lang.String name, java.lang.String descriptor)
visitOuterClass
in class org.objectweb.asm.ClassVisitor
public void visitInnerClass(java.lang.String name, java.lang.String outerName, java.lang.String innerName, int access)
visitInnerClass
in class org.objectweb.asm.ClassVisitor
public org.objectweb.asm.FieldVisitor visitField(int access, java.lang.String name, java.lang.String descriptor, java.lang.String signature, java.lang.Object value)
visitField
in class org.objectweb.asm.ClassVisitor
public org.objectweb.asm.MethodVisitor visitMethod(int access, java.lang.String name, java.lang.String descriptor, java.lang.String signature, java.lang.String[] exceptions)
visitMethod
in class org.objectweb.asm.ClassVisitor
public org.objectweb.asm.AnnotationVisitor visitAnnotation(java.lang.String descriptor, boolean visible)
visitAnnotation
in class org.objectweb.asm.ClassVisitor
public org.objectweb.asm.AnnotationVisitor visitTypeAnnotation(int typeRef, org.objectweb.asm.TypePath typePath, java.lang.String descriptor, boolean visible)
visitTypeAnnotation
in class org.objectweb.asm.ClassVisitor
public void visitAttribute(org.objectweb.asm.Attribute attribute)
visitAttribute
in class org.objectweb.asm.ClassVisitor
public void visitEnd()
visitEnd
in class org.objectweb.asm.ClassVisitor
public static void checkClassSignature(java.lang.String signature)
signature
- a string containing the signature that must be checked.public static void checkMethodSignature(java.lang.String signature)
signature
- a string containing the signature that must be checked.public static void checkFieldSignature(java.lang.String signature)
signature
- a string containing the signature that must be checked.