Search in sources :

Example 51 with ClassPool

use of javassist.ClassPool in project powermock by powermock.

the class MethodsMockTransformerTest method should_ignore_call_to_synthetic_non_bridge_methods.

@Test
public void should_ignore_call_to_synthetic_non_bridge_methods() throws Throwable {
    final ClassPool classPool = new ClassPool(true);
    CtClass ctClass = prepareClassesForTest(classPool, "syntheticMethodIsCalled = true;");
    final Class<?> clazz = loadWithMockClassLoader(ctClass);
    final Object instance = WhiteboxImpl.newInstance(clazz);
    clazz.getMethod("doSomething", Object.class).invoke(instance, new Object());
    assertThat(methodCalls()).isNot(registered().forMethod(SYNTHETIC_METHOD_NAME));
    assertThat(WhiteboxImpl.getInternalState(clazz, "syntheticMethodIsCalled")).isEqualTo(true);
}
Also used : CtClass(javassist.CtClass) ClassPool(javassist.ClassPool) Test(org.junit.Test)

Example 52 with ClassPool

use of javassist.ClassPool in project powermock by powermock.

the class ClassReplicaCreator method createInstanceReplica.

/**
 * Create a class that is a replica of type {@code T}. To allow for
 * partial mocking all calls to non-mocked methods will be delegated to the
 * {@code delegator}.
 *
 * @param <T>       The type of the replica class to be created.
 * @param delegator The delegator object that will be invoked to allow for partial
 *                  mocking.
 * @return A replica class that can be used to duck-type an instance.
 */
@SuppressWarnings("unchecked")
public <T> Class<T> createInstanceReplica(T delegator) {
    if (delegator == null) {
        throw new IllegalArgumentException("delegator cannot be null");
    }
    final Class<T> clazz = (Class<T>) delegator.getClass();
    ClassPool classpool = ClassPool.getDefault();
    final String originalClassName = clazz.getName();
    CtClass originalClassAsCtClass;
    final CtClass newClass = classpool.makeClass(generateReplicaClassName(clazz));
    try {
        originalClassAsCtClass = classpool.get(originalClassName);
        copyFields(originalClassAsCtClass, newClass);
        addDelegatorField(delegator, newClass);
        CtMethod[] declaredMethods = originalClassAsCtClass.getDeclaredMethods();
        for (CtMethod ctMethod : declaredMethods) {
            @SuppressWarnings("unused") final String code = getReplicaMethodDelegationCode(delegator.getClass(), ctMethod, POWERMOCK_INSTANCE_DELEGATOR_FIELD_NAME);
            CtMethod make2 = CtNewMethod.copy(ctMethod, newClass, null);
            newClass.addMethod(make2);
        }
        CtConstructor[] declaredConstructors = originalClassAsCtClass.getDeclaredConstructors();
        for (CtConstructor ctConstructor : declaredConstructors) {
            CtConstructor copy = CtNewConstructor.copy(ctConstructor, newClass, null);
            newClass.addConstructor(copy);
        }
        return (Class<T>) newClass.toClass(this.getClass().getClassLoader(), this.getClass().getProtectionDomain());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : ClassPool(javassist.ClassPool) CannotCompileException(javassist.CannotCompileException) NotFoundException(javassist.NotFoundException) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) CtClass(javassist.CtClass) CtMethod(javassist.CtMethod)

Example 53 with ClassPool

use of javassist.ClassPool in project yyl_example by Relucent.

the class CreateSimpleBeanTest method create.

@SuppressWarnings("unchecked")
public static Class<? extends SimpleBean> create(String className, String... fields) throws CannotCompileException, NotFoundException {
    ClassPool pool = ClassPool.getDefault();
    CtClass cc = pool.makeClass(className);
    cc.setInterfaces(new CtClass[] { pool.get(SimpleBean.class.getName()) });
    CtClass stringctClass = pool.get("java.lang.String");
    {
        for (String field : fields) {
            cc.addField(new CtField(stringctClass, field, cc));
        }
    }
    {
        CtMethod setCtMethod = new CtMethod(CtClass.voidType, "set", new CtClass[] { stringctClass, stringctClass }, cc);
        setCtMethod.setModifiers(Modifier.PUBLIC);
        StringBuilder vSetBody = new StringBuilder();
        vSetBody.append("if(null == $1){ throw new NullPointerException(\" key can not be NULL \"); }");
        for (String field : fields) {
            vSetBody.append("else if(\"").append(field).append("\".equals($1)){ $0.").append(field).append("=$2; }");
        }
        vSetBody.append("else { throw new IllegalArgumentException(\"Object does not exist in the \" + $1 + \" field\"); }");
        setCtMethod.setBody(vSetBody.toString());
        cc.addMethod(setCtMethod);
    }
    {
        CtMethod getCtMethod = new CtMethod(stringctClass, "get", new CtClass[] { stringctClass }, cc);
        getCtMethod.setModifiers(Modifier.PUBLIC);
        StringBuilder vGetBody = new StringBuilder();
        vGetBody.append("if(null == $1){ throw new NullPointerException(\" key can not be NULL \"); }");
        for (String field : fields) {
            vGetBody.append("else if(\"").append(field).append("\".equals($1)){ return $0.").append(field).append("; }");
        }
        vGetBody.append("else { throw new IllegalArgumentException(\"Object does not exist in the \" + $1 + \" field\"); }");
        getCtMethod.setBody(vGetBody.toString());
        cc.addMethod(getCtMethod);
    }
    {
        CtConstructor cons = new CtConstructor(new CtClass[] {}, cc);
        cons.setBody("{}");
        cc.addConstructor(cons);
    }
    cc.detach();
    return (Class<? extends SimpleBean>) cc.toClass();
}
Also used : CtClass(javassist.CtClass) CtField(javassist.CtField) ClassPool(javassist.ClassPool) CtClass(javassist.CtClass) CtMethod(javassist.CtMethod) CtConstructor(javassist.CtConstructor)

Example 54 with ClassPool

use of javassist.ClassPool in project yyl_example by Relucent.

the class JavassistGeneratorTest method main.

public static void main(String[] args) throws CannotCompileException, NotFoundException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
    // ClassPool是缓存CtClass对象的容器,所有的CtClass对象都在ClassPool中,为了避免内存的消耗,创建ClassPool对象时可以使用单例模式。
    // 可以调用CtClass对的detach方法将其从ClassPool中移除。(但是这样的话CtClass就不可用了)
    ClassPool classPool = ClassPool.getDefault();
    // 新增一个类定义
    CtClass ctClass = classPool.makeClass("yyl.TestClass");
    // 定义类的字段
    CtField ctField = new CtField(classPool.get("java.lang.String"), "name", ctClass);
    // 定义字段的修饰符号(这里定义为PRIVATE)
    ctField.setModifiers(Modifier.PRIVATE);
    // 添加字段
    ctClass.addField(ctField, Initializer.constant(""));
    // 添加私有成员name及其getter、setter方法
    ctClass.addMethod(CtNewMethod.setter("setName", ctField));
    ctClass.addMethod(CtNewMethod.getter("getName", ctField));
    // 创建无参的构造体
    CtConstructor cons = new CtConstructor(new CtClass[] {}, ctClass);
    cons.setBody("{name= \"Adam\";}");
    ctClass.addConstructor(cons);
    // 添加有参的构造体
    cons = new CtConstructor(new CtClass[] { classPool.get("java.lang.String") }, ctClass);
    cons.setBody("{$0.name = $1;}");
    ctClass.addConstructor(cons);
    // 调用toClass() 方法时,会将类加载到内存中,类似的方法还有:
    // writeFile() 将class写入到文件中 toBytecode() 输出类的字节码
    // 当CtClass调用writeFile/toClass/toBytecode方法时,Javassist会冻结CtClass(修改将不允许)。
    // 这个主要是为了警告开发者该类已经被加载,而JVM是不允许重新加载该类的。
    // 如果要突破该限制,可以 调用 defrost方法
    // 加载类并打印类名
    System.out.println(ctClass.toClass());
    // #
    // 通过反射获得Class实例
    Class<?> testClass = Class.forName("yyl.TestClass");
    // 创建无参的实例,并调用getName方法
    Object o = testClass.newInstance();
    Method getter = testClass.getMethod("getName");
    System.out.println(getter.invoke(o));
    // 调用其setName方法
    Method setter = testClass.getMethod("setName", new Class[] { String.class });
    setter.invoke(o, "Dante");
    System.out.println(getter.invoke(o));
    // 通过反射创建有参的实例,并调用getName方法
    o = Class.forName("yyl.TestClass").getConstructor(String.class).newInstance("Raphael");
    getter = testClass.getMethod("getName");
    System.out.println(getter.invoke(o));
}
Also used : CtClass(javassist.CtClass) CtField(javassist.CtField) ClassPool(javassist.ClassPool) CtNewMethod(javassist.CtNewMethod) Method(java.lang.reflect.Method) CtConstructor(javassist.CtConstructor)

Example 55 with ClassPool

use of javassist.ClassPool in project yyl_example by Relucent.

the class VoBeanFactoryTest method createConstructor.

/**
 * 创建构造函数
 * @param fields 类的字段
 * @return 新创建类的构造函数
 */
@SuppressWarnings("unchecked")
private static Constructor<? extends VO> createConstructor(String... fields) throws Exception {
    ClassPool pool = ClassPool.getDefault();
    String interfaceName = VO.class.getName();
    final int count = COUNT.incrementAndGet();
    CtClass cc = pool.makeClass(interfaceName + "$" + count);
    cc.setInterfaces(new CtClass[] { pool.get(interfaceName) });
    CtClass stringCtClass = pool.get("java.lang.String");
    CtClass objectCtClass = pool.get("java.lang.Object");
    StringBuilder smb = new StringBuilder("if(null == $1){ throw new NullPointerException(\" key can not be NULL \"); }");
    StringBuilder gmb = new StringBuilder("if(null == $1){ throw new NullPointerException(\" key can not be NULL \"); }");
    for (String field : fields) {
        cc.addField(new CtField(objectCtClass, field, cc));
        smb.append("else if(\"").append(field).append("\".equals($1)){ $0.").append(field).append("=$2; }");
        gmb.append("else if(\"").append(field).append("\".equals($1)){ return $0.").append(field).append("; }");
    }
    smb.append("else { throw new IllegalArgumentException(\"Object does not exist in the \" + $1 + \" field\"); }");
    gmb.append("else { throw new IllegalArgumentException(\"Object does not exist in the \" + $1 + \" field\"); }");
    cc.addMethod(CtNewMethod.make(CtClass.voidType, "set", new CtClass[] { stringCtClass, objectCtClass }, null, smb.toString(), cc));
    cc.addMethod(CtNewMethod.make(objectCtClass, "get", new CtClass[] { stringCtClass }, null, gmb.toString(), cc));
    cc.addConstructor(CtNewConstructor.make(new CtClass[] {}, null, "{}", cc));
    cc.detach();
    final class CustomClassLoader extends ClassLoader {

        public Class<?> defineClass(byte[] code) {
            return defineClass(null, code, 0, code.length);
        }

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println("GC->CL_" + count);
        }
    }
    Constructor<? extends VO> constructor = (Constructor<? extends VO>) new CustomClassLoader().defineClass(cc.toBytecode()).getConstructor();
    constructor.setAccessible(true);
    return constructor;
}
Also used : CtClass(javassist.CtClass) CtField(javassist.CtField) Constructor(java.lang.reflect.Constructor) CtNewConstructor(javassist.CtNewConstructor) ClassPool(javassist.ClassPool)

Aggregations

ClassPool (javassist.ClassPool)120 CtClass (javassist.CtClass)93 CtMethod (javassist.CtMethod)48 NotFoundException (javassist.NotFoundException)40 CannotCompileException (javassist.CannotCompileException)28 IOException (java.io.IOException)23 LoaderClassPath (javassist.LoaderClassPath)21 CtField (javassist.CtField)20 CtConstructor (javassist.CtConstructor)17 Test (org.junit.Test)17 ClassFile (javassist.bytecode.ClassFile)15 File (java.io.File)13 Method (java.lang.reflect.Method)13 ByteArrayInputStream (java.io.ByteArrayInputStream)12 ConstPool (javassist.bytecode.ConstPool)12 FileNotFoundException (java.io.FileNotFoundException)11 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)9 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)9 ClassClassPath (javassist.ClassClassPath)7 MethodInfo (javassist.bytecode.MethodInfo)7