@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 2012 the original author or authors .
* Copyright 2002 - 2013 the original author or authors .
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
@ -13,6 +13,7 @@
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License .
* /
package org.springframework.instrument.classloading.jboss ;
import java.lang.instrument.ClassFileTransformer ;
@ -20,46 +21,39 @@ import java.lang.reflect.InvocationHandler;
@@ -20,46 +21,39 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method ;
import java.lang.reflect.Proxy ;
import org.springframework.util.Assert ;
import org.springframework.util.ReflectionUtils ;
/ * *
* Reflective wrapper around a JBoss 5 and 6 class loader methods ( discovered and called
* through reflection ) for load time weaving .
* Reflective wrapper around a JBoss 6 class loader methods
* ( discovered and called through reflection ) for load - time weaving .
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3 . 1
* /
class JBossMCAdapter implements JBossClassLoaderAdapter {
private static final String TRANSLATOR_NAME = "org.jboss.util.loading.Translator" ;
private static final String POLICY_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderPolicy" ;
private static final String DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain" ;
private static final String DEDICATED_SYSTEM = "org.jboss.classloader.spi.ClassLoaderSystem" ;
private static final String LOADER_NAME = "org.jboss.classloader.spi.base.BaseClassLoader" ;
private static final String GET_POLICY = "getPolicy" ;
private static final String GET_DOMAIN = "getClassLoaderDomain" ;
private static final String GET_SYSTEM = "getClassLoaderSystem" ;
// available since JBoss AS 5.1.0 / MC 2.0.6 (allows multiple transformers to be added)
private static final String ADD_TRANSLATOR_NAME = "addTranslator" ;
// available since JBoss AS 5.0.0 / MC 2.0.1 (allows only one transformer to be added)
private static final String SET_TRANSLATOR_NAME = "setTranslator" ;
private static final String TRANSLATOR_NAME = "org.jboss.util.loading.Translator" ;
private final ClassLoader classLoader ;
private final Object target ;
private final Class < ? > translatorClass ;
private final Method addTranslator ;
private final Object target ;
JBossMCAdapter ( ClassLoader classLoader ) {
Class < ? > clazzLoaderType = null ;
public JBossMCAdapter ( ClassLoader classLoader ) {
try {
// r esolve BaseClassLoader.class
clazzLoaderType = classLoader . loadClass ( LOADER_NAME ) ;
// R esolve BaseClassLoader.class
Class < ? > clazzLoaderType = classLoader . loadClass ( LOADER_NAME ) ;
ClassLoader clazzLoader = null ;
// walk the hierarchy to detect the instrumentation aware classl oader
// Walk the hierarchy to detect the instrumentation aware ClassL oader
for ( ClassLoader cl = classLoader ; cl ! = null & & clazzLoader = = null ; cl = cl . getParent ( ) ) {
if ( clazzLoaderType . isInstance ( cl ) ) {
clazzLoader = cl ;
@ -67,63 +61,26 @@ class JBossMCAdapter implements JBossClassLoaderAdapter {
@@ -67,63 +61,26 @@ class JBossMCAdapter implements JBossClassLoaderAdapter {
}
if ( clazzLoader = = null ) {
throw new IllegalArgumentException ( classLoader + " and its parents are not suitable ClassLoaders: "
+ "A [" + LOADER_NAME + "] implementation is required." ) ;
throw new IllegalArgumentException ( classLoader + " and its parents are not suitable ClassLoaders: " +
"A [" + LOADER_NAME + "] implementation is required." ) ;
}
this . classLoader = clazzLoader ;
// use the classloader that loaded the classloader to load
// the types for reflection purposes
// Use the ClassLoader that loaded the ClassLoader to load the types for reflection purposes
classLoader = clazzLoader . getClass ( ) . getClassLoader ( ) ;
// BaseClassLoader#getPolicy
Method method = clazzLoaderType . getDeclaredMethod ( GET_POLICY ) ;
Method method = clazzLoaderType . getDeclaredMethod ( "getPolicy" ) ;
ReflectionUtils . makeAccessible ( method ) ;
Object policy = method . invoke ( this . classLoader ) ;
this . target = method . invoke ( this . classLoader ) ;
Object addTarget = null ;
Method addMethod = null ;
// try the 5.1.x hooks
// check existence of BaseClassLoaderPolicy#addTranslator(Translator)
// Check existence of BaseClassLoaderPolicy#addTranslator(Translator)
this . translatorClass = classLoader . loadClass ( TRANSLATOR_NAME ) ;
Class < ? > clazz = classLoader . loadClass ( POLICY_NAME ) ;
try {
addMethod = clazz . getDeclaredMethod ( ADD_TRANSLATOR_NAME , translatorClass ) ;
addTarget = policy ;
} catch ( NoSuchMethodException ex ) {
}
// fall back to 5.0.x method
if ( addMethod = = null ) {
// BaseClassLoaderPolicy#getClassLoaderDomain
method = clazz . getDeclaredMethod ( GET_DOMAIN ) ;
ReflectionUtils . makeAccessible ( method ) ;
Object domain = method . invoke ( policy ) ;
// BaseClassLoaderDomain#getClassLoaderSystem
clazz = classLoader . loadClass ( DOMAIN_NAME ) ;
method = clazz . getDeclaredMethod ( GET_SYSTEM ) ;
ReflectionUtils . makeAccessible ( method ) ;
Object system = method . invoke ( domain ) ;
// resolve ClassLoaderSystem
clazz = classLoader . loadClass ( DEDICATED_SYSTEM ) ;
Assert . isInstanceOf ( clazz , system , "JBoss LoadTimeWeaver requires JBoss loader system of type "
+ clazz . getName ( ) + " on JBoss 5.0.x" ) ;
// ClassLoaderSystem#setTranslator
addMethod = clazz . getDeclaredMethod ( SET_TRANSLATOR_NAME , translatorClass ) ;
addTarget = system ;
}
this . addTranslator = addMethod ;
this . target = addTarget ;
} catch ( Exception ex ) {
this . addTranslator = this . target . getClass ( ) . getMethod ( "addTranslator" , this . translatorClass ) ;
}
catch ( Exception ex ) {
throw new IllegalStateException (
"Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available" , ex ) ;
"Could not initialize JBoss LoadTimeWeaver because the JBoss 6 API classes are not available" , ex ) ;
}
}
@ -131,17 +88,18 @@ class JBossMCAdapter implements JBossClassLoaderAdapter {
@@ -131,17 +88,18 @@ class JBossMCAdapter implements JBossClassLoaderAdapter {
public void addTransformer ( ClassFileTransformer transformer ) {
InvocationHandler adapter = new JBossMCTranslatorAdapter ( transformer ) ;
Object adapterInstance = Proxy . newProxyInstance ( this . translatorClass . getClassLoader ( ) ,
new Class < ? > [ ] { this . translatorClass } , adapter ) ;
new Class < ? > [ ] { this . translatorClass } , adapter ) ;
try {
addTranslator . invoke ( target , adapterInstance ) ;
} catch ( Exception ex ) {
throw new IllegalStateException ( "Could not add transformer on JBoss 5/6 classloader " + classLoader , ex ) ;
this . addTranslator . invoke ( this . target , adapterInstance ) ;
}
catch ( Exception ex ) {
throw new IllegalStateException ( "Could not add transformer on JBoss 6 ClassLoader " + this . classLoader , ex ) ;
}
}
@Override
public ClassLoader getInstrumentableClassLoader ( ) {
return classLoader ;
return this . classLoader ;
}
}