提交 b6970d35 编写于 作者: J Juergen Hoeller

Removed obsolete JBoss 5.x support code from JBossLoadTimeWeaver

上级 8a3b4c69
/*
* 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.
......@@ -26,7 +26,7 @@ import org.springframework.util.ClassUtils;
/**
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader.
* Autodetects the specific JBoss version at runtime: currently supports
* JBoss AS 5, 6 and 7 (as of Spring 3.1).
* JBoss AS 6 and 7 (as of Spring 4.0).
*
* <p><b>NOTE:</b> On JBoss 6.0, to avoid the container loading the classes before the
* application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt>
......@@ -66,7 +66,7 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
this.adapter = new JBossModulesAdapter(classLoader);
}
else {
// JBoss AS 5 or JBoss AS 6
// JBoss AS 6
this.adapter = new JBossMCAdapter(classLoader);
}
}
......
/*
* 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 @@
* 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;
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 {
// resolve BaseClassLoader.class
clazzLoaderType = classLoader.loadClass(LOADER_NAME);
// Resolve BaseClassLoader.class
Class<?> clazzLoaderType = classLoader.loadClass(LOADER_NAME);
ClassLoader clazzLoader = null;
// walk the hierarchy to detect the instrumentation aware classloader
// Walk the hierarchy to detect the instrumentation aware ClassLoader
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 {
}
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 {
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;
}
}
/*
* 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 @@
* 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;
......@@ -34,45 +35,47 @@ class JBossMCTranslatorAdapter implements InvocationHandler {
private final ClassFileTransformer transformer;
/**
* Creates a new {@link JBossMCTranslatorAdapter}.
* @param transformer the {@link ClassFileTransformer} to be adapted (must
* not be {@code null})
*/
public JBossMCTranslatorAdapter(ClassFileTransformer transformer) {
this.transformer = transformer;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
if ("equals".equals(name)) {
return (Boolean.valueOf(proxy == args[0]));
} else if ("hashCode".equals(name)) {
return proxy == args[0];
}
else if ("hashCode".equals(name)) {
return hashCode();
} else if ("toString".equals(name)) {
}
else if ("toString".equals(name)) {
return toString();
} else if ("transform".equals(name)) {
return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3],
(byte[]) args[4]);
} else if ("unregisterClassLoader".equals(name)) {
}
else if ("transform".equals(name)) {
return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2],
(ProtectionDomain) args[3], (byte[]) args[4]);
}
else if ("unregisterClassLoader".equals(name)) {
unregisterClassLoader((ClassLoader) args[0]);
return null;
} else {
}
else {
throw new IllegalArgumentException("Unknown method: " + method);
}
}
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception {
return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
return this.transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
}
public void unregisterClassLoader(ClassLoader loader) {
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(getClass().getName());
......@@ -80,4 +83,5 @@ class JBossMCTranslatorAdapter implements InvocationHandler {
builder.append(this.transformer);
return builder.toString();
}
}
/*
* 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.
......@@ -20,39 +20,44 @@ import java.lang.instrument.ClassFileTransformer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* JBoss 7 adapter.
* Reflective wrapper around a JBoss 7 class loader methods
* (discovered and called through reflection) for load-time weaving.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
class JBossModulesAdapter implements JBossClassLoaderAdapter {
private static final String TRANSFORMER_FIELD_NAME = "transformer";
private static final String TRANSFORMER_ADD_METHOD_NAME = "addTransformer";
private static final String DELEGATING_TRANSFORMER_CLASS_NAME = "org.jboss.as.server.deployment.module.DelegatingClassFileTransformer";
private static final String DELEGATING_TRANSFORMER_CLASS_NAME =
"org.jboss.as.server.deployment.module.DelegatingClassFileTransformer";
private final ClassLoader classLoader;
private final Method addTransformer;
private final Object delegatingTransformer;
public JBossModulesAdapter(ClassLoader loader) {
this.classLoader = loader;
try {
Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME);
transformers.setAccessible(true);
delegatingTransformer = transformers.get(classLoader);
Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME),
"Transformer not of the expected type: " + delegatingTransformer.getClass().getName());
addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME,
ClassFileTransformer.class);
addTransformer.setAccessible(true);
} catch (Exception ex) {
Field transformer = ReflectionUtils.findField(loader.getClass(), "transformer");
transformer.setAccessible(true);
this.delegatingTransformer = transformer.get(loader);
if (!this.delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
throw new IllegalStateException("Transformer not of the expected type DelegatingClassFileTransformer: " +
this.delegatingTransformer.getClass().getName());
}
this.addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(),
"addTransformer", ClassFileTransformer.class);
this.addTransformer.setAccessible(true);
}
catch (Exception ex) {
throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex);
}
}
......@@ -60,14 +65,16 @@ class JBossModulesAdapter implements JBossClassLoaderAdapter {
@Override
public void addTransformer(ClassFileTransformer transformer) {
try {
addTransformer.invoke(delegatingTransformer, transformer);
} catch (Exception ex) {
throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex);
this.addTransformer.invoke(this.delegatingTransformer, transformer);
}
catch (Exception ex) {
throw new IllegalStateException("Could not add transformer on JBoss 7 ClassLoader " + this.classLoader, ex);
}
}
@Override
public ClassLoader getInstrumentableClassLoader() {
return classLoader;
return this.classLoader;
}
}
/**
*
* Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x.
* Support for class instrumentation on JBoss AS 6 and 7.
*
*/
package org.springframework.instrument.classloading.jboss;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册