Search in sources :

Example 26 with CtField

use of javassist.CtField in project javassist-maven-plugin by icon-Systemhaus-GmbH.

the class TestJavassistTransformerExecuter method applyStamp_on_Interface.

@Test
public void applyStamp_on_Interface() throws CannotCompileException, NotFoundException {
    // given
    final String className = "test.TestClass";
    final CtClass candidateClass = mock("candidateClass", CtClass.class);
    final Capture<CtField> fieldCaptures = newInstance();
    // createStampField
    expect(candidateClass.isInterface()).andReturn(true);
    expect(candidateClass.getClassPool()).andReturn(classPool).anyTimes();
    expect(candidateClass.getClassFile2()).andReturn(new ClassFile(false, className, null));
    expect(candidateClass.isFrozen()).andReturn(false);
    expect(candidateClass.getName()).andReturn(className).anyTimes();
    candidateClass.addField(capture(fieldCaptures), anyObject(CtField.Initializer.class));
    replay(candidateClass, classPool);
    // when
    sut.applyStamp(candidateClass);
    // then
    verify(candidateClass, classPool);
    assertThat("generated stamp field starts with the constant prefix.", fieldCaptures.getValue().getName(), org.hamcrest.core.StringStartsWith.startsWith(JavassistTransformerExecutor.STAMP_FIELD_NAME));
    assertThat("generated stamp field must have the right modifiers.", fieldCaptures.getValue().getModifiers(), is(STATIC | FINAL | PUBLIC));
    assertThat("generated stamp field is a boolean.", fieldCaptures.getValue().getType(), is(booleanType));
}
Also used : CtClass(javassist.CtClass) ClassFile(javassist.bytecode.ClassFile) CtField(javassist.CtField) Test(org.junit.Test)

Example 27 with CtField

use of javassist.CtField in project powermock by powermock.

the class InstrumentMockTransformerTest method addSyntheticField.

private void addSyntheticField(ClassPool classPool, CtClass ctClass) throws CannotCompileException, NotFoundException {
    CtField field = new CtField(classPool.get(String.class.getName()), SYNTH_FIELD, ctClass);
    field.setModifiers(AccessFlag.SYNTHETIC);
    ctClass.addField(field, CtField.Initializer.constant(SYNTHETIC_FIELD_VALUE));
}
Also used : CtField(javassist.CtField)

Example 28 with CtField

use of javassist.CtField 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 29 with CtField

use of javassist.CtField 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 30 with CtField

use of javassist.CtField 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

CtField (javassist.CtField)76 CtClass (javassist.CtClass)47 CtMethod (javassist.CtMethod)27 CannotCompileException (javassist.CannotCompileException)24 NotFoundException (javassist.NotFoundException)22 ClassPool (javassist.ClassPool)20 CtConstructor (javassist.CtConstructor)15 Test (org.junit.Test)12 ClassFile (javassist.bytecode.ClassFile)9 IOException (java.io.IOException)7 Method (java.lang.reflect.Method)7 ArrayList (java.util.ArrayList)6 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)5 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)4 ConstPool (javassist.bytecode.ConstPool)4 SMethod (org.bimserver.shared.meta.SMethod)4 SParameter (org.bimserver.shared.meta.SParameter)4 InsertableMethod (com.github.stephanenicolas.afterburner.inserts.InsertableMethod)3 SimpleInsertableMethod (com.github.stephanenicolas.afterburner.inserts.SimpleInsertableMethod)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3