use of javassist.ClassPool in project fakereplace by fakereplace.
the class MainTransformer method transform.
@Override
public byte[] transform(final ClassLoader loader, final String className, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] classfileBuffer) throws IllegalClassFormatException {
if (className == null) {
// TODO: deal with lambdas
return classfileBuffer;
}
boolean replaceable = Fakereplace.isClassReplaceable(className, loader);
if (classBeingRedefined != null) {
retransformationStarted = true;
if (logClassRetransformation && replaceable) {
log.info("Fakereplace is replacing class " + className);
}
}
ChangedClassImpl changedClass = null;
if (classBeingRedefined != null) {
changedClass = new ChangedClassImpl(classBeingRedefined);
}
boolean changed = false;
if (!replaceable && UnmodifiedFileIndex.isClassUnmodified(className)) {
return null;
}
Set<Class<?>> classesToRetransform = new HashSet<>();
final ClassFile file;
try {
Set<MethodInfo> modifiedMethods = new HashSet<>();
file = new ClassFile(new DataInputStream(new ByteArrayInputStream(classfileBuffer)));
for (final FakereplaceTransformer transformer : transformers) {
if (transformer.transform(loader, className, classBeingRedefined, protectionDomain, file, classesToRetransform, changedClass, modifiedMethods)) {
changed = true;
}
}
if (!changed) {
UnmodifiedFileIndex.markClassUnmodified(className);
return null;
} else {
try {
if (!modifiedMethods.isEmpty()) {
ClassPool classPool = new ClassPool();
if (loader == null) {
classPool.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader()));
} else {
classPool.appendClassPath(new LoaderClassPath(loader));
}
classPool.appendSystemPath();
for (MethodInfo method : modifiedMethods) {
if (method.getCodeAttribute() != null) {
method.getCodeAttribute().computeMaxStack();
try {
method.rebuildStackMap(classPool);
} catch (BadBytecode e) {
Throwable root = e;
while (!(root instanceof NotFoundException) && root != null && root.getCause() != root) {
root = root.getCause();
}
if (root instanceof NotFoundException) {
NotFoundException cause = (NotFoundException) root;
Bytecode bytecode = new Bytecode(file.getConstPool());
bytecode.addNew(NoClassDefFoundError.class.getName());
bytecode.add(Opcode.DUP);
bytecode.addLdc(cause.getMessage());
bytecode.addInvokespecial(NoClassDefFoundError.class.getName(), "<init>", "(Ljava/lang/String;)V");
bytecode.add(Opcode.ATHROW);
method.setCodeAttribute(bytecode.toCodeAttribute());
method.getCodeAttribute().computeMaxStack();
method.getCodeAttribute().setMaxLocals(DescriptorUtils.maxLocalsFromParameters(method.getDescriptor()) + 1);
method.rebuildStackMap(classPool);
} else {
throw e;
}
}
}
}
}
} catch (BadBytecode e) {
throw new RuntimeException(e);
}
ByteArrayOutputStream bs = new ByteArrayOutputStream();
file.write(new DataOutputStream(bs));
// dump the class for debugging purposes
final String dumpDir = AgentOptions.getOption(AgentOption.DUMP_DIR);
if (dumpDir != null) {
try {
File dump = new File(dumpDir + '/' + file.getName() + ".class");
dump.getParentFile().mkdirs();
FileOutputStream s = new FileOutputStream(dump);
DataOutputStream dos = new DataOutputStream(s);
file.write(dos);
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (!classesToRetransform.isEmpty()) {
synchronized (this) {
retransformationOutstandingCount++;
}
Thread t = new Thread(() -> {
try {
Fakereplace.getInstrumentation().retransformClasses(classesToRetransform.toArray(new Class[classesToRetransform.size()]));
} catch (UnmodifiableClassException e) {
log.error("Failed to retransform classes", e);
} finally {
synchronized (MainTransformer.this) {
retransformationOutstandingCount--;
notifyAll();
}
}
});
t.setDaemon(true);
t.start();
}
if (classBeingRedefined != null) {
changedClasses.add(changedClass);
queueIntegration();
}
return bs.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
throw new IllegalClassFormatException(e.getMessage());
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
use of javassist.ClassPool in project motech by motech.
the class EntityMetadataBuilderTest method shouldAddBaseEntityMetadata.
@Test
public void shouldAddBaseEntityMetadata() throws Exception {
CtField ctField = mock(CtField.class);
CtClass ctClass = mock(CtClass.class);
CtClass superClass = mock(CtClass.class);
ClassData classData = mock(ClassData.class);
ClassPool pool = mock(ClassPool.class);
PowerMockito.mockStatic(MotechClassPool.class);
PowerMockito.when(MotechClassPool.getDefault()).thenReturn(pool);
when(classData.getClassName()).thenReturn(CLASS_NAME);
when(classData.getModule()).thenReturn(MODULE);
when(classData.getNamespace()).thenReturn(NAMESPACE);
when(entity.getTableName()).thenReturn(TABLE_NAME);
when(pool.getOrNull(CLASS_NAME)).thenReturn(ctClass);
when(ctClass.getField("id")).thenReturn(ctField);
when(ctClass.getSuperclass()).thenReturn(superClass);
when(superClass.getName()).thenReturn(Object.class.getName());
when(jdoMetadata.newPackageMetadata(PACKAGE)).thenReturn(packageMetadata);
when(packageMetadata.newClassMetadata(ENTITY_NAME)).thenReturn(classMetadata);
entityMetadataBuilder.addBaseMetadata(jdoMetadata, classData, EntityType.STANDARD, Sample.class);
verify(jdoMetadata).newPackageMetadata(PACKAGE);
verify(packageMetadata).newClassMetadata(ENTITY_NAME);
verify(classMetadata).setTable(TABLE_NAME_3);
verifyCommonClassMetadata();
}
use of javassist.ClassPool in project ignite by apache.
the class IgniteExamplesMLTestSuite method makeTestClass.
/**
* Creates test class for given example.
*
* @param exampleCls Class of the example to be tested.
* @return Test class.
*/
private static Class<?> makeTestClass(Class<?> exampleCls) {
ClassPool cp = ClassPool.getDefault();
cp.insertClassPath(new ClassClassPath(IgniteExamplesMLTestSuite.class));
CtClass cl = cp.makeClass(basePkgForTests + "." + exampleCls.getSimpleName() + "SelfTest");
try {
cl.setSuperclass(cp.get(GridAbstractExamplesTest.class.getName()));
CtMethod mtd = CtNewMethod.make("public void testExample() { " + exampleCls.getCanonicalName() + ".main(" + MLExamplesCommonArgs.class.getName() + ".EMPTY_ARGS_ML); }", cl);
// Create and add annotation.
ClassFile ccFile = cl.getClassFile();
ConstPool constpool = ccFile.getConstPool();
AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
Annotation annot = new Annotation("org.junit.Test", constpool);
attr.addAnnotation(annot);
mtd.getMethodInfo().addAttribute(attr);
cl.addMethod(mtd);
return cl.toClass();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of javassist.ClassPool in project dubbo by alibaba.
the class JValidator method generateMethodParameterClass.
/**
* try to generate methodParameterClass.
*
* @param clazz interface class
* @param method invoke method
* @param parameterClassName generated parameterClassName
* @return Class<?> generated methodParameterClass
* @throws Exception
*/
private static Class<?> generateMethodParameterClass(Class<?> clazz, Method method, String parameterClassName) throws Exception {
ClassPool pool = ClassGenerator.getClassPool(clazz.getClassLoader());
synchronized (parameterClassName.intern()) {
CtClass ctClass = null;
try {
ctClass = pool.getCtClass(parameterClassName);
} catch (NotFoundException ignore) {
}
if (null == ctClass) {
ctClass = pool.makeClass(parameterClassName);
ClassFile classFile = ctClass.getClassFile();
classFile.setVersionToJava5();
ctClass.addConstructor(CtNewConstructor.defaultConstructor(pool.getCtClass(parameterClassName)));
// parameter fields
Class<?>[] parameterTypes = method.getParameterTypes();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = 0; i < parameterTypes.length; i++) {
Class<?> type = parameterTypes[i];
Annotation[] annotations = parameterAnnotations[i];
AnnotationsAttribute attribute = new AnnotationsAttribute(classFile.getConstPool(), AnnotationsAttribute.visibleTag);
for (Annotation annotation : annotations) {
if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
javassist.bytecode.annotation.Annotation ja = new javassist.bytecode.annotation.Annotation(classFile.getConstPool(), pool.getCtClass(annotation.annotationType().getName()));
Method[] members = annotation.annotationType().getMethods();
for (Method member : members) {
if (Modifier.isPublic(member.getModifiers()) && member.getParameterTypes().length == 0 && member.getDeclaringClass() == annotation.annotationType()) {
Object value = member.invoke(annotation);
if (null != value) {
MemberValue memberValue = createMemberValue(classFile.getConstPool(), pool.get(member.getReturnType().getName()), value);
ja.addMemberValue(member.getName(), memberValue);
}
}
}
attribute.addAnnotation(ja);
}
}
String fieldName = method.getName() + "Argument" + i;
CtField ctField = CtField.make("public " + type.getCanonicalName() + " " + fieldName + ";", pool.getCtClass(parameterClassName));
ctField.getFieldInfo().addAttribute(attribute);
ctClass.addField(ctField);
}
return ctClass.toClass(clazz.getClassLoader(), null);
} else {
return Class.forName(parameterClassName, true, clazz.getClassLoader());
}
}
}
use of javassist.ClassPool in project dubbo by alibaba.
the class CtClassBuilder method build.
/**
* build CtClass object
*/
public CtClass build(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
ClassPool pool = new ClassPool(true);
pool.appendClassPath(new LoaderClassPath(classLoader));
// create class
CtClass ctClass = pool.makeClass(className, pool.get(superClassName));
// add imported packages
imports.forEach(pool::importPackage);
// add implemented interfaces
for (String iface : ifaces) {
ctClass.addInterface(pool.get(iface));
}
// add constructors
for (String constructor : constructors) {
ctClass.addConstructor(CtNewConstructor.make(constructor, ctClass));
}
// add fields
for (String field : fields) {
ctClass.addField(CtField.make(field, ctClass));
}
// add methods
for (String method : methods) {
ctClass.addMethod(CtNewMethod.make(method, ctClass));
}
return ctClass;
}
Aggregations