Search in sources :

Example 51 with BadBytecode

use of javassist.bytecode.BadBytecode in project UniverseCore by EB-wilson.

the class MapMaker method make.

/**
 * Runs an analyzer (Phase 1 and 2).
 */
void make(TypedBlock[] blocks, byte[] code) throws BadBytecode {
    make(code, blocks[0]);
    findDeadCatchers(code, blocks);
    try {
        fixTypes(code, blocks);
    } catch (NotFoundException e) {
        throw new BadBytecode("failed to resolve types", e);
    }
}
Also used : NotFoundException(javassist.NotFoundException) BadBytecode(javassist.bytecode.BadBytecode)

Example 52 with BadBytecode

use of javassist.bytecode.BadBytecode in project hibernate-orm by hibernate.

the class PersistentAttributesEnhancer method enhanceAttributesAccess.

protected void enhanceAttributesAccess(CtClass managedCtClass, IdentityHashMap<String, PersistentAttributeAccessMethods> attributeDescriptorMap) {
    final ConstPool constPool = managedCtClass.getClassFile().getConstPool();
    final ClassPool classPool = managedCtClass.getClassPool();
    for (Object oMethod : managedCtClass.getClassFile().getMethods()) {
        final MethodInfo methodInfo = (MethodInfo) oMethod;
        final String methodName = methodInfo.getName();
        // skip methods added by enhancement and abstract methods (methods without any code)
        if (methodName.startsWith("$$_hibernate_") || methodInfo.getCodeAttribute() == null) {
            continue;
        }
        try {
            final CodeIterator itr = methodInfo.getCodeAttribute().iterator();
            while (itr.hasNext()) {
                final int index = itr.next();
                final int op = itr.byteAt(index);
                if (op != Opcode.PUTFIELD && op != Opcode.GETFIELD) {
                    continue;
                }
                // only transform access to fields of the entity being enhanced
                if (!managedCtClass.getName().equals(constPool.getFieldrefClassName(itr.u16bitAt(index + 1)))) {
                    continue;
                }
                final String fieldName = constPool.getFieldrefName(itr.u16bitAt(index + 1));
                final PersistentAttributeAccessMethods attributeMethods = attributeDescriptorMap.get(fieldName);
                // its not a field we have enhanced for interception, so skip it
                if (attributeMethods == null) {
                    continue;
                }
                // System.out.printf( "Transforming access to field [%s] from method [%s]%n", fieldName, methodName );
                log.debugf("Transforming access to field [%s] from method [%s]", fieldName, methodName);
                if (op == Opcode.GETFIELD) {
                    final int methodIndex = MethodWriter.addMethod(constPool, attributeMethods.getReader());
                    itr.writeByte(Opcode.INVOKEVIRTUAL, index);
                    itr.write16bit(methodIndex, index + 1);
                } else {
                    final int methodIndex = MethodWriter.addMethod(constPool, attributeMethods.getWriter());
                    itr.writeByte(Opcode.INVOKEVIRTUAL, index);
                    itr.write16bit(methodIndex, index + 1);
                }
            }
            methodInfo.getCodeAttribute().setAttribute(MapMaker.make(classPool, methodInfo));
        } catch (BadBytecode bb) {
            final String msg = String.format("Unable to perform field access transformation in method [%s]", methodName);
            throw new EnhancementException(msg, bb);
        }
    }
}
Also used : ConstPool(javassist.bytecode.ConstPool) CodeIterator(javassist.bytecode.CodeIterator) ClassPool(javassist.ClassPool) EnhancementException(org.hibernate.bytecode.enhance.spi.EnhancementException) MethodInfo(javassist.bytecode.MethodInfo) BadBytecode(javassist.bytecode.BadBytecode)

Example 53 with BadBytecode

use of javassist.bytecode.BadBytecode in project hibernate-orm by hibernate.

the class PersistentAttributesEnhancer method extendedEnhancement.

// --- //
/**
 * Replace access to fields of entities (for example, entity.field) with a call to the enhanced getter / setter
 * (in this example, entity.$$_hibernate_read_field()). It's assumed that the target entity is enhanced as well.
 *
 * @param aCtClass Class to enhance (not an entity class).
 */
public void extendedEnhancement(CtClass aCtClass) {
    final ConstPool constPool = aCtClass.getClassFile().getConstPool();
    final ClassPool classPool = aCtClass.getClassPool();
    for (Object oMethod : aCtClass.getClassFile().getMethods()) {
        final MethodInfo methodInfo = (MethodInfo) oMethod;
        final String methodName = methodInfo.getName();
        // skip methods added by enhancement and abstract methods (methods without any code)
        if (methodName.startsWith("$$_hibernate_") || methodInfo.getCodeAttribute() == null) {
            continue;
        }
        try {
            final CodeIterator itr = methodInfo.getCodeAttribute().iterator();
            while (itr.hasNext()) {
                int index = itr.next();
                int op = itr.byteAt(index);
                if (op != Opcode.PUTFIELD && op != Opcode.GETFIELD) {
                    continue;
                }
                String fieldName = constPool.getFieldrefName(itr.u16bitAt(index + 1));
                String fieldClassName = constPool.getClassInfo(constPool.getFieldrefClass(itr.u16bitAt(index + 1)));
                CtClass targetCtClass = classPool.getCtClass(fieldClassName);
                if (!enhancementContext.isEntityClass(targetCtClass) && !enhancementContext.isCompositeClass(targetCtClass)) {
                    continue;
                }
                if (targetCtClass == aCtClass || !enhancementContext.isPersistentField(targetCtClass.getField(fieldName)) || PersistentAttributesHelper.hasAnnotation(targetCtClass, fieldName, Id.class) || "this$0".equals(fieldName)) {
                    continue;
                }
                log.debugf("Extended enhancement: Transforming access to field [%s.%s] from method [%s#%s]", fieldClassName, fieldName, aCtClass.getName(), methodName);
                if (op == Opcode.GETFIELD) {
                    int fieldReaderMethodIndex = constPool.addMethodrefInfo(constPool.addClassInfo(fieldClassName), EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + fieldName, "()" + constPool.getFieldrefType(itr.u16bitAt(index + 1)));
                    itr.writeByte(Opcode.INVOKEVIRTUAL, index);
                    itr.write16bit(fieldReaderMethodIndex, index + 1);
                } else {
                    int fieldWriterMethodIndex = constPool.addMethodrefInfo(constPool.addClassInfo(fieldClassName), EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + fieldName, "(" + constPool.getFieldrefType(itr.u16bitAt(index + 1)) + ")V");
                    itr.writeByte(Opcode.INVOKEVIRTUAL, index);
                    itr.write16bit(fieldWriterMethodIndex, index + 1);
                }
            }
            methodInfo.getCodeAttribute().setAttribute(MapMaker.make(classPool, methodInfo));
        } catch (BadBytecode bb) {
            final String msg = String.format("Unable to perform extended enhancement in method [%s]", methodName);
            throw new EnhancementException(msg, bb);
        } catch (NotFoundException nfe) {
            final String msg = String.format("Unable to perform extended enhancement in method [%s]", methodName);
            throw new EnhancementException(msg, nfe);
        }
    }
}
Also used : ConstPool(javassist.bytecode.ConstPool) CtClass(javassist.CtClass) CodeIterator(javassist.bytecode.CodeIterator) ClassPool(javassist.ClassPool) EnhancementException(org.hibernate.bytecode.enhance.spi.EnhancementException) NotFoundException(javassist.NotFoundException) MethodInfo(javassist.bytecode.MethodInfo) BadBytecode(javassist.bytecode.BadBytecode)

Example 54 with BadBytecode

use of javassist.bytecode.BadBytecode in project fakereplace by fakereplace.

the class WeldClassTransformer method transform.

@Override
public boolean transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, ClassFile file, Set<Class<?>> classesToRetransform, ChangedClassImpl changedClass, Set<MethodInfo> modifiedMethods) throws IllegalClassFormatException, BadBytecode {
    // Hack up the proxy factory so it stores the proxy ClassFile. We need this to regenerate proxies.
    if (file.getName().equals(ORG_JBOSS_WELD_BEAN_PROXY_PROXY_FACTORY)) {
        for (final MethodInfo method : (List<MethodInfo>) file.getMethods()) {
            if (method.getName().equals("createProxyClass")) {
                modifiedMethods.add(method);
                final VirtualToStaticManipulator virtualToStaticManipulator = new VirtualToStaticManipulator();
                virtualToStaticManipulator.replaceVirtualMethodInvokationWithStatic(ClassLoader.class.getName(), WELD_PROXY_CLASS_LOADING_DELEGATE, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;", loader);
                virtualToStaticManipulator.replaceVirtualMethodInvokationWithStatic("org.jboss.weld.util.bytecode.ClassFileUtils", WELD_PROXY_CLASS_LOADING_DELEGATE, "toClass", "(Lorg/jboss/classfilewriter/ClassFile;Ljava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", "(Lorg/jboss/classfilewriter/ClassFile;Ljava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;", loader);
                virtualToStaticManipulator.transformClass(file, loader, true, modifiedMethods);
                return true;
            } else if (method.getName().equals("<init>")) {
                modifiedMethods.add(method);
                Integer beanArgument = null;
                int count = 1;
                for (final String paramType : DescriptorUtils.descriptorStringToParameterArray(method.getDescriptor())) {
                    if (paramType.equals("Ljavax/enterprise/inject/spi/Bean")) {
                        beanArgument = count;
                        break;
                    } else if (paramType.equals("D") || paramType.equals("J")) {
                        count += 2;
                    } else {
                        count++;
                    }
                }
                if (beanArgument == null) {
                    log.error("Constructor org.jboss.weld.bean.proxy.ProxyFactory.<init>" + method.getDescriptor() + " does not have a bean parameter, proxies produced by this factory will not be reloadable");
                    continue;
                }
                // similar to other tracked instances
                // but we need a strong ref
                Bytecode code = new Bytecode(file.getConstPool());
                code.addAload(0);
                code.addAload(beanArgument);
                code.addInvokestatic(WeldClassChangeAware.class.getName(), "addProxyFactory", "(Ljava/lang/Object;Ljava/lang/Object;)V");
                CodeIterator it = method.getCodeAttribute().iterator();
                it.skipConstructor();
                it.insert(code.get());
            }
        }
    }
    return false;
}
Also used : VirtualToStaticManipulator(org.fakereplace.manip.VirtualToStaticManipulator) CodeIterator(javassist.bytecode.CodeIterator) MethodInfo(javassist.bytecode.MethodInfo) List(java.util.List) BadBytecode(javassist.bytecode.BadBytecode) Bytecode(javassist.bytecode.Bytecode)

Example 55 with BadBytecode

use of javassist.bytecode.BadBytecode in project fakereplace by fakereplace.

the class WildflyClassTransformer method transform.

@Override
public boolean transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, ClassFile file, Set<Class<?>> classesToRetransform, ChangedClassImpl changedClass, Set<MethodInfo> modifiedMethods) throws IllegalClassFormatException, BadBytecode, DuplicateMemberException {
    if (!file.getName().equals("org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService")) {
        return false;
    }
    for (MethodInfo method : (List<MethodInfo>) file.getMethods()) {
        if (method.getName().equals("createServletConfig")) {
            CodeAttribute code = method.getCodeAttribute();
            code.setMaxStack(code.getMaxStack() + 1);
            CodeIterator it = code.iterator();
            modifiedMethods.add(method);
            while (it.hasNext()) {
                int pos = it.next();
                int inst = it.byteAt(pos);
                if (inst == CodeAttribute.ARETURN) {
                    Bytecode b = new Bytecode(method.getConstPool());
                    b.addGetstatic("org.fakereplace.integration.wildfly.autoupdate.WebUpdateHandlerWrapper", "INSTANCE", "Lio/undertow/server/HandlerWrapper;");
                    b.addInvokevirtual("io.undertow.servlet.api.DeploymentInfo", "addInnerHandlerChainWrapper", "(Lio/undertow/server/HandlerWrapper;)Lio/undertow/servlet/api/DeploymentInfo;");
                    it.insert(pos, b.get());
                }
            }
        }
    }
    return true;
}
Also used : CodeAttribute(javassist.bytecode.CodeAttribute) CodeIterator(javassist.bytecode.CodeIterator) MethodInfo(javassist.bytecode.MethodInfo) List(java.util.List) BadBytecode(javassist.bytecode.BadBytecode) Bytecode(javassist.bytecode.Bytecode)

Aggregations

BadBytecode (javassist.bytecode.BadBytecode)135 Bytecode (javassist.bytecode.Bytecode)57 CodeAttribute (javassist.bytecode.CodeAttribute)56 CodeIterator (javassist.bytecode.CodeIterator)43 MethodInfo (javassist.bytecode.MethodInfo)38 CtClass (javassist.CtClass)32 NotFoundException (javassist.NotFoundException)32 ConstPool (javassist.bytecode.ConstPool)30 Javac (javassist.compiler.Javac)27 CompileError (javassist.compiler.CompileError)26 CannotCompileException (javassist.CannotCompileException)22 ClassPool (javassist.ClassPool)12 List (java.util.List)11 Type (javassist.bytecode.analysis.Type)8 DuplicateMemberException (javassist.bytecode.DuplicateMemberException)7 IOException (java.io.IOException)6 CtMethod (javassist.CtMethod)5 ClassFile (javassist.bytecode.ClassFile)5 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)4 Method (java.lang.reflect.Method)4