Example usage for org.objectweb.asm.tree ClassNode ClassNode

List of usage examples for org.objectweb.asm.tree ClassNode ClassNode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree ClassNode ClassNode.

Prototype

public ClassNode(final int api) 

Source Link

Document

Constructs a new ClassNode .

Usage

From source file:org.coldswap.asm.method.PublicObjectMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);/*from   www  . j  av  a2 s. c om*/
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createObjectHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter
                        // Object[].
                        if (mParamType.length == 1
                                && mParamType[0].equals(Type.getType("[Ljava/lang/Object;"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(
                                        new PublicMethodReferenceReplacer(cn.name, mNode.name, mRetType,
                                                mParamType, Constants.VAROBJECT, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.VAROBJECT, counter));
                            }
                            // remove this method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }
    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.method.PublicStringMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);/*from   ww  w .j  av a 2s  .  c o m*/
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createStringHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter int.
                        if (mParamType.length == 1
                                && mParamType[0].equals(Type.getType("Ljava/lang/String;"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(new PublicMethodReferenceReplacer(
                                        cn.name, mNode.name, mRetType, mParamType, Constants.STRING, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.STRING, counter));
                            }
                            // remove method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }

    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.tracker.ClassListener.java

License:Open Source License

@Override
public void fileModified(int i, String root, String className) {
    if ((!"".equals(className)) && (null != className))
        if (filter.accept(new File(className))) {
            Map<String, Class<?>> loaded = ClassInstrumenter.getInstance().getLoadedClasses();
            byte[] bytes = ByteCodeClassLoader.loadClassBytes(root + sep + className);
            // first eight bytes for versioning
            if (bytes.length < 8) {
                return;
            }//  w w w.j  a  v a 2 s .c  o m
            ClassNode classNode = new ClassNode(Opcodes.ASM5);
            ClassReader classReader = new ClassReader(bytes);
            classReader.accept(classNode, 0);
            String clsName = classNode.name.replace('/', '.').replace(".class", "");

            logger.info("Class " + clsName + " has been modified on the disk");

            if ((!"".equals(clsName)) && (null != clsName)) {
                Class<?> clazz = loaded.get(clsName);
                if (clazz == null) {
                    logger.info(clsName + " is new class file!");
                    try {
                        Class<?> cla = Class.forName(clsName);
                        // run reference replacer
                        bytes = refManager.runReferenceReplacer(bytes);
                        ClassDefinition def = new ClassDefinition(cla, bytes);
                        Instrumentation inst = ClassInstrumenter.getInstance().getInstrumenter();
                        inst.redefineClasses(def);
                    } catch (ClassNotFoundException e) {
                        // it means that the class was not loaded yet into machine
                        // so no worries here
                    } catch (UnmodifiableClassException e) {
                        logger.warning(toString());
                    }

                    return;
                }
                ClassRedefiner redefiner = new ClassRedefiner(clsName, root + sep + className,
                        maxNumberOfMethods);
                try {
                    redefiner.redefineClass(clazz);
                } catch (UnmodifiableClassException e) {
                    logger.severe(e.toString());
                } catch (ClassNotFoundException e) {
                    logger.severe(e.toString());
                }
            }
        }
}

From source file:org.coldswap.transformer.ClInitTransformer.java

License:Open Source License

@SuppressWarnings("unchecked")
@Override//from   w  ww .  java  2 s .  co m
public byte[] transform(ClassLoader classLoader, String s, Class<?> aClass, ProtectionDomain protectionDomain,
        byte[] bytes) throws IllegalClassFormatException {
    if (s != null && !"".equals(s)) {
        for (String pack : ClassUtil.skipTransforming) {
            if (s.startsWith(pack)) {
                return bytes;
            }
        }

        ClassNode cn = new ClassNode(Opcodes.ASM5);
        ClassReader cr = new ClassReader(bytes);
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        // create adapter for method insertion.
        cr.accept(cn, 0);
        // insert <clinit>V if it is not inserted
        List methods = cn.methods;
        boolean clInitFound = false;
        for (MethodNode methodNode : (List<MethodNode>) methods) {
            if ("<clinit>".equals(methodNode.name)) {
                clInitFound = true;
            }
        }

        if (!clInitFound) {
            MethodNode mn = new MethodNode(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
            InsnList insnList = mn.instructions;
            insnList.add(new LabelNode());
            insnList.add(new InsnNode(Opcodes.RETURN));
            cn.methods.add(mn);
        }

        cn.accept(cw);
        byte[] toRet = cw.toByteArray();
        if (toRet != null) {
            logger.info("Successful transformation!");
            return toRet;
        } else {
            logger.severe("Could not transform class");
            return bytes;
        }
    }
    return bytes;
}

From source file:org.coldswap.transformer.FloatMethodTransformer.java

License:Open Source License

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (className != null && !"".equals(className)) {
        for (String pack : ClassUtil.skipTransforming) {
            if (className.startsWith(pack)) {
                return classfileBuffer;
            }//from   w w  w.  ja v a 2 s  .c  om
        }

        ClassNode cn = new ClassNode(Opcodes.ASM5);
        ClassReader cr = new ClassReader(classfileBuffer);
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        // create adapter for method insertion.
        cr.accept(cn, 0);
        // create a list of method name's so that we resolve method collision
        List<MethodNode> methodNodes = cn.methods;
        Iterator it = methodNodes.iterator();
        List<String> methodNames = new ArrayList<String>(methodNodes.size());
        while (it.hasNext()) {
            MethodNode methodNode = (MethodNode) it.next();
            methodNames.add(methodNode.name);
        }
        // insert helper methods if they do not exist.
        for (int i = 0; i < maxNumberOfMethods; i++) {
            String name = TransformerNameGenerator.getFloatMethodNameWithCounter(className, i);
            if (!methodNames.contains(name)) {
                MethodNode mn = MethodUtil.createFloatHelperMethod(className, i);
                cn.methods.add(mn);
            }
        }
        cn.accept(cw);
        byte[] toRet = cw.toByteArray();
        if (toRet != null) {
            logger.info("Successful transformation!");
            return toRet;
        } else {
            logger.severe("Could not transform class");
            return classfileBuffer;
        }
    }
    return classfileBuffer;

}

From source file:org.coldswap.transformer.IntMethodTransformer.java

License:Open Source License

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (className != null && !"".equals(className)) {
        for (String pack : ClassUtil.skipTransforming) {
            if (className.startsWith(pack)) {
                return classfileBuffer;
            }// w  ww  . j a  v  a  2 s.  c om
        }

        ClassNode cn = new ClassNode(Opcodes.ASM5);
        ClassReader cr = new ClassReader(classfileBuffer);
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        // create adapter for method insertion.
        cr.accept(cn, 0);
        // create a list of method name's so that we resolve method collision
        List<MethodNode> methodNodes = cn.methods;
        Iterator it = methodNodes.iterator();
        List<String> methodNames = new ArrayList<String>(methodNodes.size());
        while (it.hasNext()) {
            MethodNode methodNode = (MethodNode) it.next();
            methodNames.add(methodNode.name);
        }
        // insert helper methods if they do not exist.
        for (int i = 0; i < maxNumberOfMethods; i++) {
            String name = TransformerNameGenerator.getIntMethodNameWithCounter(className, i);
            if (!methodNames.contains(name)) {
                MethodNode mn = MethodUtil.createIntHelperMethod(className, i);
                cn.methods.add(mn);
            }
        }
        cn.accept(cw);
        byte[] toRet = cw.toByteArray();
        if (toRet != null) {
            logger.info("Successful transformation!");
            return toRet;
        } else {
            logger.severe("Could not transform class");
            return classfileBuffer;
        }
    }
    return classfileBuffer;

}

From source file:org.coldswap.transformer.LongMethodTransformer.java

License:Open Source License

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (className != null && !"".equals(className)) {
        for (String pack : ClassUtil.skipTransforming) {
            if (className.startsWith(pack)) {
                return classfileBuffer;
            }//from   www. ja  v a2 s  .  c  o  m
        }

        ClassNode cn = new ClassNode(Opcodes.ASM5);
        ClassReader cr = new ClassReader(classfileBuffer);
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        // create adapter for method insertion.
        cr.accept(cn, 0);
        // create a list of method name's so that we resolve method collision
        List<MethodNode> methodNodes = cn.methods;
        Iterator it = methodNodes.iterator();
        List<String> methodNames = new ArrayList<String>(methodNodes.size());
        while (it.hasNext()) {
            MethodNode methodNode = (MethodNode) it.next();
            methodNames.add(methodNode.name);
        }
        // insert helper methods if they do not exist.
        for (int i = 0; i < maxNumberOfMethods; i++) {
            String name = TransformerNameGenerator.getLongMethodNameWithCounter(className, i);
            if (!methodNames.contains(name)) {
                MethodNode mn = MethodUtil.createLongHelperMethod(className, i);
                cn.methods.add(mn);
            }
        }
        cn.accept(cw);
        byte[] toRet = cw.toByteArray();
        if (toRet != null) {
            logger.info("Successful transformation!");
            return toRet;
        } else {
            logger.severe("Could not transform class");
            return classfileBuffer;
        }
    }
    return classfileBuffer;

}

From source file:org.coldswap.transformer.ObjectMethodTransformer.java

License:Open Source License

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (className != null && !"".equals(className)) {
        for (String pack : ClassUtil.skipTransforming) {
            if (className.startsWith(pack)) {
                return classfileBuffer;
            }// w w w  . j a  v  a 2  s .c  om
        }

        ClassNode cn = new ClassNode(Opcodes.ASM5);
        ClassReader cr = new ClassReader(classfileBuffer);
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        // create adapter for method insertion.
        cr.accept(cn, 0);
        // create a list of method name's so that we resolve method collision
        List<MethodNode> methodNodes = cn.methods;
        Iterator it = methodNodes.iterator();
        List<String> methodNames = new ArrayList<String>(methodNodes.size());
        while (it.hasNext()) {
            MethodNode methodNode = (MethodNode) it.next();
            methodNames.add(methodNode.name);
        }
        // insert helper methods if they do not exist.
        for (int i = 0; i < maxNumberOfMethods; i++) {
            String name = TransformerNameGenerator.getObjectMethodNameWithCounter(className, i);
            if (!methodNames.contains(name)) {
                MethodNode mn = MethodUtil.createObjectHelperMethod(className, i);
                cn.methods.add(mn);
            }
        }
        cn.accept(cw);
        byte[] toRet = cw.toByteArray();
        if (toRet != null) {
            logger.info("Successful transformation!");
            return toRet;
        } else {
            logger.severe("Could not transform class");
            return classfileBuffer;
        }
    }
    return classfileBuffer;

}

From source file:org.coldswap.transformer.ReferenceReplacerManager.java

License:Open Source License

/**
 * Starts the process of find and replace for the given class node.
 *
 * @param clazz where to find and replace.
 * @return transformed class byte array.
 *//*from w  ww  . j  av  a  2s  .  com*/
public byte[] runReferenceReplacer(byte[] clazz) {
    ClassNode classNode = new ClassNode(Opcodes.ASM5);
    ClassReader classReader = new ClassReader(clazz);
    ClassWriter classWriter = new ClassWriter(classReader,
            ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classReader.accept(classNode, 0);
    for (ReferenceReplacer replacer : fieldReferences) {
        replacer.findAndReplace(classNode);
    }

    classNode.accept(classWriter);
    return classWriter.toByteArray();
}

From source file:org.coldswap.transformer.StringMethodTransformer.java

License:Open Source License

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (className != null && !"".equals(className)) {
        for (String pack : ClassUtil.skipTransforming) {
            if (className.startsWith(pack)) {
                return classfileBuffer;
            }/*from ww w . j a v  a2  s.c o m*/
        }

        ClassNode cn = new ClassNode(Opcodes.ASM5);
        ClassReader cr = new ClassReader(classfileBuffer);
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        // create adapter for method insertion.
        cr.accept(cn, 0);
        // create a list of method name's so that we resolve method collision
        List<MethodNode> methodNodes = cn.methods;
        Iterator it = methodNodes.iterator();
        List<String> methodNames = new ArrayList<String>(methodNodes.size());
        while (it.hasNext()) {
            MethodNode methodNode = (MethodNode) it.next();
            methodNames.add(methodNode.name);
        }
        // insert helper methods if they do not exist.
        for (int i = 0; i < maxNumberOfMethods; i++) {
            String name = TransformerNameGenerator.getStringMethodNameWithCounter(className, i);
            if (!methodNames.contains(name)) {
                MethodNode mn = MethodUtil.createStringHelperMethod(className, i);
                cn.methods.add(mn);
            }
        }
        cn.accept(cw);
        byte[] toRet = cw.toByteArray();
        if (toRet != null) {
            logger.info("Successful transformation!");
            return toRet;
        } else {
            logger.severe("Could not transform class");
            return classfileBuffer;
        }
    }
    return classfileBuffer;

}