[강운덕] [LUCYSUS-1744] interceptor 강제 classLoader define시 superClass가 추상 클래스 일 경우, 추가적으로 로드하도록 함.

- 완전한 계층 구조를 다 포함하려면, 코드가 복잡해서 제한적으로 class를 로드시키도록 되어 있음.  


git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@2530 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Woonduk Kang
2013-10-16 05:25:17 +00:00
parent 5b74a24266
commit 398e6a4e00
@@ -2,6 +2,7 @@ package com.nhn.pinpoint.profiler.interceptor.bci;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.ProtectionDomain;
@@ -112,14 +113,18 @@ public class JavaAssistByteCodeInstrumentor implements ByteCodeInstrumentor {
logger.info("defineClass class:{}, cl:{}", defineClass, classLoader);
}
try {
// 아래 classLoaderChecker가 생겼으니 classLoader 를 같이 락으로 잡아야 되지 않는가?
// synchronized (classLoader)
if (this.classLoadChecker.exist(classLoader, defineClass)) {
return classLoader.loadClass(defineClass);
} else {
CtClass clazz = childClassPool.get(defineClass);
defineNestedClass(clazz, classLoader, protectedDomain);
return clazz.toClass(classLoader, protectedDomain);
// classLoader로 락을 잡는게 안전함.
// 어차피 classLoader에서 락을 잡고 들어오는점도 있고. 예외 사항이 발생할수 있기 때문에.
// classLoader의 재진입 락을 잡고 들어오는게 무난함.
synchronized (classLoader) {
if (this.classLoadChecker.exist(classLoader, defineClass)) {
return classLoader.loadClass(defineClass);
} else {
final CtClass clazz = childClassPool.get(defineClass);
defineAbstractSuperClass(clazz, classLoader, protectedDomain);
defineNestedClass(clazz, classLoader, protectedDomain);
return clazz.toClass(classLoader, protectedDomain);
}
}
} catch (NotFoundException e) {
throw new InstrumentException(defineClass + " class not fund. Cause:" + e.getMessage(), e);
@@ -130,6 +135,21 @@ public class JavaAssistByteCodeInstrumentor implements ByteCodeInstrumentor {
}
}
private void defineAbstractSuperClass(CtClass clazz, ClassLoader classLoader, ProtectionDomain protectedDomain) throws NotFoundException, CannotCompileException {
final CtClass superClass = clazz.getSuperclass();
if (superClass == null) {
// java.lang.Object가 아닌 경우 null은 안나올듯.
return;
}
final int modifiers = superClass.getModifiers();
if (Modifier.isAbstract(modifiers)) {
if (isInfo) {
logger.info("defineAbstractSuperClass class:{} cl:{}", superClass.getName(), classLoader);
}
superClass.toClass(classLoader, protectedDomain);
}
}
private void defineNestedClass(CtClass clazz, ClassLoader classLoader, ProtectionDomain protectedDomain) throws NotFoundException, CannotCompileException {
CtClass[] nestedClasses = clazz.getNestedClasses();
if (nestedClasses.length == 0) {