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