import javassist.NotFoundException
import javassist.LoaderClassPath
import javassist.ClassClassPath
+import java.util.concurrent.locks.Lock
+import java.util.concurrent.locks.ReentrantLock
+import org.slf4j.LoggerFactory
+import java.util.HashMap
+import java.util.WeakHashMap
class JavassistUtils {
+ private static val LOG = LoggerFactory.getLogger(JavassistUtils);
+
+ private val loaderClassPaths = new WeakHashMap<ClassLoader,LoaderClassPath>();
+
ClassPool classPool
+
+ @Property
+ val Lock lock = new ReentrantLock();
new(ClassPool pool) {
classPool = pool;
}
def CtClass createClass(String fqn, ClassGenerator cls) {
+
val target = classPool.makeClass(fqn);
cls.process(target);
return target;
}
def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
+
val target = classPool.makeClass(fqn);
target.implementsType(superInterface);
cls.process(target);
addField(field);
return field;
}
+
+ def CtField staticField(CtClass it, String name, Class<?> returnValue) {
+ val field = new CtField(returnValue.asCtClass, name, it);
+ field.modifiers = Modifier.PUBLIC + Modifier.STATIC
+ addField(field);
+ return field;
+ }
def get(ClassPool pool, Class<?> cls) {
try {
return pool.get(cls.name)
} catch (NotFoundException e) {
- pool.appendClassPath(new LoaderClassPath(cls.classLoader));
+ appendClassLoaderIfMissing(cls.classLoader)
try {
return pool.get(cls.name)
-
} catch (NotFoundException ef) {
+ LOG.warn("Appending ClassClassPath for {}",cls);
pool.appendClassPath(new ClassClassPath(cls));
+
return pool.get(cls.name)
}
}
}
+
+ def void appendClassLoaderIfMissing(ClassLoader loader) {
+ if(loaderClassPaths.containsKey(loader)) {
+ return;
+ }
+ val ctLoader = new LoaderClassPath(loader);
+ classPool.appendClassPath(ctLoader);
+ }
+
+ def void ensureClassLoader(Class<?> child) {
+ appendClassLoaderIfMissing(child.classLoader);
+ }
}