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);
}
}
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);
}
}
}
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);
}
}
}
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;
}
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));
}
Aggregations