From b6970d3504c433571ce43ac758256be77ae4af9f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 16 Dec 2013 20:21:34 +0100 Subject: [PATCH] Removed obsolete JBoss 5.x support code from JBossLoadTimeWeaver --- .../jboss/JBossLoadTimeWeaver.java | 6 +- .../classloading/jboss/JBossMCAdapter.java | 106 ++++++------------ .../jboss/JBossMCTranslatorAdapter.java | 38 ++++--- .../jboss/JBossModulesAdapter.java | 51 +++++---- .../classloading/jboss/package-info.java | 2 +- 5 files changed, 86 insertions(+), 117 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java index b8125405df..f3bb67c2f3 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossLoadTimeWeaver.java @@ -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. @@ -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). * *

NOTE: On JBoss 6.0, to avoid the container loading the classes before the * application actually starts, one needs to add a WEB-INF/jboss-scanning.xml @@ -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); } } diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java index b8cfccee1d..1cdc29ad7e 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCAdapter.java @@ -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 @@ * 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; } + } diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java index ebb3ded551..8b9560a970 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossMCTranslatorAdapter.java @@ -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 @@ * 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(); } + } diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java index 7319ec74f3..4181bcb39e 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/JBossModulesAdapter.java @@ -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. @@ -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; } + } diff --git a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java index 4072d51f6c..78b581c225 100644 --- a/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java +++ b/spring-context/src/main/java/org/springframework/instrument/classloading/jboss/package-info.java @@ -1,7 +1,7 @@ /** * - * 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;