Fixes java.lang.VerifyError by building StackMapTables at appropriate
places.
This commit is contained in:
Dustin Schultz 2012-08-24 13:53:34 -06:00 committed by Strong Liu
parent ca9079f654
commit c5eeaf71c1
2 changed files with 43 additions and 14 deletions

View File

@ -25,9 +25,13 @@ package org.hibernate.bytecode.buildtime.internal;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Set;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.bytecode.ClassFile;
import org.hibernate.bytecode.buildtime.spi.AbstractInstrumenter;
@ -44,6 +48,7 @@ import org.hibernate.bytecode.spi.ClassTransformer;
*
* @author Steve Ebersole
* @author Muga Nishizawa
* @author Dustin Schultz
*/
public class JavassistInstrumenter extends AbstractInstrumenter {
@ -70,6 +75,20 @@ public class JavassistInstrumenter extends AbstractInstrumenter {
return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor, classNames ) );
}
}
@Override
public void execute(Set<File> files) {
ClassPool cp = ClassPool.getDefault();
cp.insertClassPath(new ClassClassPath(this.getClass()));
try {
for (File file : files) {
cp.makeClass(new FileInputStream(file));
}
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
super.execute(files);
}
private static class CustomClassDescriptor implements ClassDescriptor {
private final byte[] bytes;

View File

@ -32,6 +32,7 @@ import java.util.Iterator;
import java.util.List;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.bytecode.AccessFlag;
import javassist.bytecode.BadBytecode;
import javassist.bytecode.Bytecode;
@ -43,6 +44,8 @@ import javassist.bytecode.Descriptor;
import javassist.bytecode.FieldInfo;
import javassist.bytecode.MethodInfo;
import javassist.bytecode.Opcode;
import javassist.bytecode.StackMapTable;
import javassist.bytecode.stackmap.MapMaker;
/**
* The thing that handles actual class enhancement in regards to
@ -50,6 +53,7 @@ import javassist.bytecode.Opcode;
*
* @author Muga Nishizawa
* @author Steve Ebersole
* @author Dustin Schultz
*/
public class FieldTransformer {
@ -130,7 +134,7 @@ public class FieldTransformer {
}
private void addGetFieldHandlerMethod(ClassFile classfile)
throws CannotCompileException {
throws CannotCompileException, BadBytecode {
ConstPool cp = classfile.getConstPool();
int this_class_index = cp.getThisClassInfo();
MethodInfo minfo = new MethodInfo(cp, GETFIELDHANDLER_METHOD_NAME,
@ -148,11 +152,13 @@ public class FieldTransformer {
code.addOpcode(Opcode.ARETURN);
minfo.setCodeAttribute(code.toCodeAttribute());
minfo.setAccessFlags(AccessFlag.PUBLIC);
StackMapTable smt = MapMaker.make(ClassPool.getDefault(), minfo);
minfo.getCodeAttribute().setAttribute(smt);
classfile.addMethod(minfo);
}
private void addSetFieldHandlerMethod(ClassFile classfile)
throws CannotCompileException {
throws CannotCompileException, BadBytecode {
ConstPool cp = classfile.getConstPool();
int this_class_index = cp.getThisClassInfo();
MethodInfo minfo = new MethodInfo(cp, SETFIELDHANDLER_METHOD_NAME,
@ -172,6 +178,8 @@ public class FieldTransformer {
code.addOpcode(Opcode.RETURN);
minfo.setCodeAttribute(code.toCodeAttribute());
minfo.setAccessFlags(AccessFlag.PUBLIC);
StackMapTable smt = MapMaker.make(ClassPool.getDefault(), minfo);
minfo.getCodeAttribute().setAttribute(smt);
classfile.addMethod(minfo);
}
@ -185,7 +193,7 @@ public class FieldTransformer {
}
private void addReadWriteMethods(ClassFile classfile)
throws CannotCompileException {
throws CannotCompileException, BadBytecode {
List fields = classfile.getFields();
for (Iterator field_iter = fields.iterator(); field_iter.hasNext();) {
FieldInfo finfo = (FieldInfo) field_iter.next();
@ -205,7 +213,7 @@ public class FieldTransformer {
}
private void addReadMethod(ClassFile classfile, FieldInfo finfo)
throws CannotCompileException {
throws CannotCompileException, BadBytecode {
ConstPool cp = classfile.getConstPool();
int this_class_index = cp.getThisClassInfo();
String desc = "()" + finfo.getDescriptor();
@ -254,11 +262,13 @@ public class FieldTransformer {
minfo.setCodeAttribute(code.toCodeAttribute());
minfo.setAccessFlags(AccessFlag.PUBLIC);
StackMapTable smt = MapMaker.make(ClassPool.getDefault(), minfo);
minfo.getCodeAttribute().setAttribute(smt);
classfile.addMethod(minfo);
}
private void addWriteMethod(ClassFile classfile, FieldInfo finfo)
throws CannotCompileException {
throws CannotCompileException, BadBytecode {
ConstPool cp = classfile.getConstPool();
int this_class_index = cp.getThisClassInfo();
String desc = "(" + finfo.getDescriptor() + ")V";
@ -320,11 +330,13 @@ public class FieldTransformer {
minfo.setCodeAttribute(code.toCodeAttribute());
minfo.setAccessFlags(AccessFlag.PUBLIC);
StackMapTable smt = MapMaker.make(ClassPool.getDefault(), minfo);
minfo.getCodeAttribute().setAttribute(smt);
classfile.addMethod(minfo);
}
private void transformInvokevirtualsIntoPutAndGetfields(ClassFile classfile)
throws CannotCompileException {
throws CannotCompileException, BadBytecode {
List methods = classfile.getMethods();
for (Iterator method_iter = methods.iterator(); method_iter.hasNext();) {
MethodInfo minfo = (MethodInfo) method_iter.next();
@ -341,15 +353,13 @@ public class FieldTransformer {
}
CodeIterator iter = codeAttr.iterator();
while (iter.hasNext()) {
try {
int pos = iter.next();
pos = transformInvokevirtualsIntoGetfields(classfile, iter, pos);
pos = transformInvokevirtualsIntoPutfields(classfile, iter, pos);
} catch (BadBytecode e) {
throw new CannotCompileException(e);
}
int pos = iter.next();
pos = transformInvokevirtualsIntoGetfields(classfile, iter, pos);
pos = transformInvokevirtualsIntoPutfields(classfile, iter, pos);
}
StackMapTable smt = MapMaker.make(ClassPool.getDefault(), minfo);
minfo.getCodeAttribute().setAttribute(smt);
}
}