Search in sources :

Example 11 with DuplicateMemberException

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

the class ResteasyTransformer method transform.

@Override
public boolean transform(final ClassLoader loader, final String className, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final ClassFile file, Set<Class<?>> classesToRetransform, ChangedClassImpl changedClass, Set<MethodInfo> modifiedMethods) throws IllegalClassFormatException, BadBytecode {
    try {
        if (file.getName().equals(ResteasyExtension.FILTER_DISPATCHER)) {
            FieldInfo field = new FieldInfo(file.getConstPool(), FIELD_NAME, FILTER_FIELD_TYPE);
            field.setAccessFlags(Modifier.PUBLIC);
            file.addField(field);
            field = new FieldInfo(file.getConstPool(), PARAMETER_FIELD_NAME, SET_TYPE);
            field.setAccessFlags(Modifier.PUBLIC);
            file.addField(field);
            for (final MethodInfo method : (List<MethodInfo>) file.getMethods()) {
                if (method.getName().equals("init") && method.getDescriptor().equals("(Ljavax/servlet/FilterConfig;)V")) {
                    method.setAccessFlags(method.getAccessFlags() | AccessFlag.SYNCHRONIZED);
                    modifiedMethods.add(method);
                    final Bytecode b = new Bytecode(file.getConstPool());
                    b.addAload(0);
                    b.addNew(RESTEASY_FILTER_CONFIG);
                    b.add(Opcode.DUP);
                    b.addAload(1);
                    b.addInvokespecial(RESTEASY_FILTER_CONFIG, "<init>", "(Ljavax/servlet/FilterConfig;)V");
                    b.addPutfield(ResteasyExtension.FILTER_DISPATCHER, FIELD_NAME, FILTER_FIELD_TYPE);
                    b.addAload(1);
                    b.addInvokeinterface("javax/servlet/FilterConfig", "getServletContext", "()Ljavax/servlet/ServletContext;", 1);
                    b.addAload(0);
                    b.addGetfield(ResteasyExtension.FILTER_DISPATCHER, PARAMETER_FIELD_NAME, SET_TYPE);
                    b.addInvokestatic(CONTEXT_PARAMS, "init", INIT_METHOD_DESC);
                    b.addAload(0);
                    b.add(Opcode.SWAP);
                    b.addPutfield(ResteasyExtension.FILTER_DISPATCHER, PARAMETER_FIELD_NAME, SET_TYPE);
                    method.getCodeAttribute().iterator().insert(b.get());
                    method.getCodeAttribute().computeMaxStack();
                } else if (method.getName().equals("<init>")) {
                    // no idea why this is needed
                    method.getCodeAttribute().setMaxStack(1);
                } else if (method.getName().equals("getDispatcher")) {
                    method.setAccessFlags(method.getAccessFlags() | AccessFlag.SYNCHRONIZED);
                    modifiedMethods.add(method);
                }
            }
            return true;
        } else if (file.getName().equals(ResteasyExtension.SERVLET_DISPATCHER)) {
            FieldInfo field = new FieldInfo(file.getConstPool(), FIELD_NAME, SERVLET_FIELD_TYPE);
            field.setAccessFlags(Modifier.PUBLIC);
            file.addField(field);
            field = new FieldInfo(file.getConstPool(), PARAMETER_FIELD_NAME, SET_TYPE);
            field.setAccessFlags(Modifier.PUBLIC);
            file.addField(field);
            for (final MethodInfo method : (List<MethodInfo>) file.getMethods()) {
                if (method.getName().equals("init") && method.getDescriptor().equals("(Ljavax/servlet/ServletConfig;)V")) {
                    method.setAccessFlags(method.getAccessFlags() | AccessFlag.SYNCHRONIZED);
                    modifiedMethods.add(method);
                    final Bytecode b = new Bytecode(file.getConstPool());
                    b.addAload(0);
                    b.addNew(RESTEASY_SERVLET_CONFIG);
                    b.add(Opcode.DUP);
                    b.addAload(1);
                    b.addInvokespecial(RESTEASY_SERVLET_CONFIG, "<init>", "(Ljavax/servlet/ServletConfig;)V");
                    b.addPutfield(ResteasyExtension.SERVLET_DISPATCHER, FIELD_NAME, SERVLET_FIELD_TYPE);
                    b.addAload(1);
                    b.addInvokeinterface("javax/servlet/ServletConfig", "getServletContext", "()Ljavax/servlet/ServletContext;", 1);
                    b.addAload(0);
                    b.addGetfield(ResteasyExtension.SERVLET_DISPATCHER, PARAMETER_FIELD_NAME, SET_TYPE);
                    b.addInvokestatic(CONTEXT_PARAMS, "init", INIT_METHOD_DESC);
                    b.addAload(0);
                    b.add(Opcode.SWAP);
                    b.addPutfield(ResteasyExtension.SERVLET_DISPATCHER, PARAMETER_FIELD_NAME, SET_TYPE);
                    method.getCodeAttribute().iterator().insert(b.get());
                    method.getCodeAttribute().computeMaxStack();
                } else if (method.getName().equals("<init>")) {
                    method.getCodeAttribute().setMaxStack(1);
                } else if (method.getName().equals("getDispatcher")) {
                    method.setAccessFlags(method.getAccessFlags() | AccessFlag.SYNCHRONIZED);
                    modifiedMethods.add(method);
                }
            }
            return true;
        }
    } catch (DuplicateMemberException e) {
        throw new RuntimeException(e);
    }
    return false;
}
Also used : DuplicateMemberException(javassist.bytecode.DuplicateMemberException) MethodInfo(javassist.bytecode.MethodInfo) List(java.util.List) BadBytecode(javassist.bytecode.BadBytecode) Bytecode(javassist.bytecode.Bytecode) FieldInfo(javassist.bytecode.FieldInfo)

Example 12 with DuplicateMemberException

use of javassist.bytecode.DuplicateMemberException in project powermock by powermock.

the class PowerMockExpressionEditor method addNewDeferConstructor.

/**
 * Create a defer constructor in the class which will be called when the
 * constructor is suppressed.
 *
 * @param clazz The class whose super constructor will get a new defer
 *              constructor if it doesn't already have one.
 * @throws CannotCompileException If an unexpected compilation error occurs.
 */
private void addNewDeferConstructor(final CtClass clazz) throws CannotCompileException {
    final CtClass superClass;
    try {
        superClass = clazz.getSuperclass();
    } catch (NotFoundException e1) {
        throw new IllegalArgumentException("Internal error: Failed to get superclass for " + clazz.getName() + " when about to create a new default constructor.");
    }
    ClassPool classPool = clazz.getClassPool();
    /*
         * To make a unique defer constructor we create a new constructor
         * with one argument (IndicateReloadClass). So we get this class a
         * Javassist class below.
         */
    final CtClass constructorType;
    try {
        constructorType = classPool.get(IndicateReloadClass.class.getName());
    } catch (NotFoundException e) {
        throw new IllegalArgumentException("Internal error: failed to get the " + IndicateReloadClass.class.getName() + " when added defer constructor.");
    }
    clazz.defrost();
    if (superClass.getName().equals(Object.class.getName())) {
        try {
            clazz.addConstructor(CtNewConstructor.make(new CtClass[] { constructorType }, new CtClass[0], "{super();}", clazz));
        } catch (DuplicateMemberException e) {
        // OK, the constructor has already been added.
        }
    } else {
        addNewDeferConstructor(superClass);
        try {
            clazz.addConstructor(CtNewConstructor.make(new CtClass[] { constructorType }, new CtClass[0], "{super($$);}", clazz));
        } catch (DuplicateMemberException e) {
        // OK, the constructor has already been added.
        }
    }
}
Also used : DuplicateMemberException(javassist.bytecode.DuplicateMemberException) CtClass(javassist.CtClass) ClassPool(javassist.ClassPool) NotFoundException(javassist.NotFoundException)

Aggregations

DuplicateMemberException (javassist.bytecode.DuplicateMemberException)12 MethodInfo (javassist.bytecode.MethodInfo)9 BadBytecode (javassist.bytecode.BadBytecode)8 Bytecode (javassist.bytecode.Bytecode)8 IOException (java.io.IOException)6 CodeAttribute (javassist.bytecode.CodeAttribute)5 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 DataOutputStream (java.io.DataOutputStream)3 ClassFile (javassist.bytecode.ClassFile)3 FieldInfo (javassist.bytecode.FieldInfo)3 Method (java.lang.reflect.Method)2 HashSet (java.util.HashSet)2 BaseClassData (org.fakereplace.data.BaseClassData)2 Field (java.lang.reflect.Field)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1 ClassPool (javassist.ClassPool)1 CtClass (javassist.CtClass)1 NotFoundException (javassist.NotFoundException)1