보통 bytecode instrumentation을 할 때 cglib, javassist등과 같은 도구를 사용하는 데 JVM 스펙상 이미 로드된 클래스코드에 대한 수정을 허용하지 않기 때문에(만약 조작한다 하더라도 그 코드는 의미가 없을 수 있다고 판단됩니다) javaagent의 premain을 이용하여 로드시점에 대상들에 대한 바이트 코드 조작이 필요합니다.

이 때 javassist를 사용하고 있는데 보통 WAS의 경우 다양한 클래스 로더(예 : EAR, Web, EJB 등)들을 가지고 있기 때문에 javassist에서 해당 클래스들에 대한 참조를 하지 못해 NotFoundException으로 인한 toClass등의 메소드에서 CannotCompileException이 발생합니다.

아래의 예제는 javaagent premain + ClassFileTransformer의 뼈대 코드로 WAS 클래스로더로 로딩되는 클래스를 참조할 수 있도록 합니다.


public static void premain(String agentArgs, Instrumentation inst) {
		if (agentArgs != null) {
			String[] args = agentArgs.split("(  *)|(, *)");
			parseArgs(args);
		}
		if( dbtrace ) {
			if( verbose ) {
				System.out.println("JDBC Query Monitoring turns on");
			}
			ClassFileTransformer transformer = new JDBCClassInstrumentor();
			inst.addTransformer(transformer);
		}
		
		if( packageName != null ) {
			if( verbose ) {
				System.out.println("Package Profiler Work Start for [" + packageName + "]");
				packageName = packageName.replace('.', '/');
			}
			ClassFileTransformer transformer = new HttpServletClassTransformer();
			inst.addTransformer(transformer);
		}
		
	}
public JDBCClassInstrumentor() {
		cp = ClassPool.getDefault();
	}

	HashMap loaderMap = new HashMap();

	@Override
	public byte[] transform(ClassLoader loader, String className,
			Class classBeingRedefined, ProtectionDomain protectionDomain,
			byte[] classfileBuffer) throws IllegalClassFormatException {
		try {

			if (loader != null && !loaderMap.containsValue(loader)) {
				// System.out.println(loader +
				// " is added as a new classloader");
				loaderMap.put(loader.toString(), loader);
				cp.insertClassPath(new LoaderClassPath(loader));
			}
	
			if (className.equals("org/jboss/resource/adapter/jdbc/WrappedConnection")) {
                           // Your Work!
                       }
               } catch (Exception e) {
			e.printStackTrace();
		}
              return modified_bytecode
         }
크리에이티브 커먼즈 라이센스
Creative Commons License
2010/02/22 07:51 2010/02/22 07:51
http://www.javapattern.info/trackback/327