byte code transformation corrupts classes
Hello,
working with the ASM library I bumped into strange issue, the trivial
transformation might corrupt classes:
ClassReader cr = new ClassReader(buffer);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
cr.accept(cw, 0);
byte[] res = cw.toByteArray();
a stack size in particular, that causes VerifyError.
I minimized the test as possible. The steps below allows to reproduce the error.
----- Trans.java - code to perform class transformation ------
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
public class Trans {
public static void main(String[] args) {
String s = args[0];
try {
FileInputStream fis = new FileInputStream(s);
int size = fis.available();
byte[] buffer = new byte[size];
fis.read(buffer);
ClassReader cr = new ClassReader(buffer);
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
cr.accept(cw, 0);
byte[] res = cw.toByteArray();
FileOutputStream fos = new FileOutputStream(s + ".i");
fos.write(res);
fos.flush();
fos.close();
System.out.println("Created: " + s + ".i");
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
----- HelloWorld.java - subject of transformation ----
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello world");
}
public void meth1() throws MyException {
}
public void meth2() {
try {
meth1();
} catch (MyException re) {
}
}
public void meth3() throws MyException {
try {
} finally {
}
}
static class MyException extends Exception {
}
}
------------------
Steps to reproduce:
# cp ../asm-3.3.1.jar .
# javac -cp asm-3.3.1.jar Trans.java
# javac HelloWorld.java
# java -cp .:asm-3.3.1.jar Trans HelloWorld.class
Created: HelloWorld.class.i
# java -cp . HelloWorld
Hello world
# mv HelloWorld.class HelloWorld.class.o
# cp HelloWorld.class.i HelloWorld.class
# java -cp . HelloWorld
Exception in threadjava "main" java.lang.VerifyError: (class: HelloWorld,
method: meth3 signature: ()V) Stack size too large
Could not find the main class: HelloWorld. Program will exit.
# java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Server VM (build 19.1-b02, mixed mode)
Note, the problem is reprosible as of jdk6u4.
I disassembled classes (with own tools) and there is only difference in the
stack size for 'meth3()'
public Method meth3:"()V"
throws HelloWorld$MyException
stack 1 locals 2
{...}
-->
public Method meth3:"()V"
throws HelloWorld$MyException
stack 0 locals 2
{...}
Should you have any question: feel free to ask me at: dmitry.fazunenko@oracle.com