Search in sources :

Example 16 with ClassPool

use of javassist.ClassPool in project HikariCP by brettwooldridge.

the class JavassistProxyFactory method main.

public static void main(String... args) {
    classPool = new ClassPool();
    classPool.importPackage("java.sql");
    classPool.appendClassPath(new LoaderClassPath(JavassistProxyFactory.class.getClassLoader()));
    try {
        // Cast is not needed for these
        String methodBody = "{ try { return delegate.method($$); } catch (SQLException e) { throw checkException(e); } }";
        generateProxyClass(Connection.class, ProxyConnection.class.getName(), methodBody);
        generateProxyClass(Statement.class, ProxyStatement.class.getName(), methodBody);
        generateProxyClass(ResultSet.class, ProxyResultSet.class.getName(), methodBody);
        // For these we have to cast the delegate
        methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { throw checkException(e); } }";
        generateProxyClass(PreparedStatement.class, ProxyPreparedStatement.class.getName(), methodBody);
        generateProxyClass(CallableStatement.class, ProxyCallableStatement.class.getName(), methodBody);
        modifyProxyFactory();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : ProxyResultSet(com.zaxxer.hikari.pool.ProxyResultSet) ProxyStatement(com.zaxxer.hikari.pool.ProxyStatement) ProxyConnection(com.zaxxer.hikari.pool.ProxyConnection) ClassPool(javassist.ClassPool) LoaderClassPath(javassist.LoaderClassPath) ProxyPreparedStatement(com.zaxxer.hikari.pool.ProxyPreparedStatement) NotFoundException(javassist.NotFoundException) ProxyCallableStatement(com.zaxxer.hikari.pool.ProxyCallableStatement)

Example 17 with ClassPool

use of javassist.ClassPool 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 18 with ClassPool

use of javassist.ClassPool 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 19 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)

Example 20 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)

Aggregations

ClassPool (javassist.ClassPool)44 CtClass (javassist.CtClass)32 CtMethod (javassist.CtMethod)16 NotFoundException (javassist.NotFoundException)15 CannotCompileException (javassist.CannotCompileException)10 LoaderClassPath (javassist.LoaderClassPath)9 CtField (javassist.CtField)8 IOException (java.io.IOException)7 Test (org.junit.Test)7 File (java.io.File)6 CtConstructor (javassist.CtConstructor)6 FileNotFoundException (java.io.FileNotFoundException)5 MethodInfo (javassist.bytecode.MethodInfo)4 Method (java.lang.reflect.Method)3 ConstPool (javassist.bytecode.ConstPool)3 DirectoryInput (com.android.build.api.transform.DirectoryInput)2 JarInput (com.android.build.api.transform.JarInput)2 InjectParam (com.taobao.android.builder.tools.classinject.InjectParam)2 FileFilter (java.io.FileFilter)2 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)2