From c5eeaf71c1a9f7c285a72bf9ac940106e0af61cd Mon Sep 17 00:00:00 2001 From: Dustin Schultz Date: Fri, 24 Aug 2012 13:53:34 -0600 Subject: [PATCH] HHH-7544 Fixes java.lang.VerifyError by building StackMapTables at appropriate places. --- .../internal/JavassistInstrumenter.java | 19 ++++++++++ .../internal/javassist/FieldTransformer.java | 38 ++++++++++++------- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java index 1182ed9d18..e3c4bd8513 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java @@ -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 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; diff --git a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java index 4757612b80..300238fee4 100644 --- a/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java +++ b/hibernate-core/src/main/java/org/hibernate/bytecode/internal/javassist/FieldTransformer.java @@ -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); } }