10 changed files with 82 additions and 360 deletions
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2011 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* 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; |
||||
|
||||
/** |
||||
* Simple interface used for handling the different JBoss class loader adapters. |
||||
* |
||||
* @author Costin Leau |
||||
* @since 3.1 |
||||
*/ |
||||
interface JBossClassLoaderAdapter { |
||||
|
||||
void addTransformer(ClassFileTransformer transformer); |
||||
|
||||
ClassLoader getInstrumentableClassLoader(); |
||||
|
||||
} |
@ -1,105 +0,0 @@
@@ -1,105 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* 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; |
||||
import java.lang.reflect.InvocationHandler; |
||||
import java.lang.reflect.Method; |
||||
import java.lang.reflect.Proxy; |
||||
|
||||
import org.springframework.util.ReflectionUtils; |
||||
|
||||
/** |
||||
* 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 LOADER_NAME = "org.jboss.classloader.spi.base.BaseClassLoader"; |
||||
|
||||
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; |
||||
|
||||
|
||||
public JBossMCAdapter(ClassLoader classLoader) { |
||||
try { |
||||
// Resolve BaseClassLoader.class
|
||||
Class<?> clazzLoaderType = classLoader.loadClass(LOADER_NAME); |
||||
|
||||
ClassLoader clazzLoader = null; |
||||
// 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; |
||||
} |
||||
} |
||||
|
||||
if (clazzLoader == null) { |
||||
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
|
||||
classLoader = clazzLoader.getClass().getClassLoader(); |
||||
|
||||
// BaseClassLoader#getPolicy
|
||||
Method method = clazzLoaderType.getDeclaredMethod("getPolicy"); |
||||
ReflectionUtils.makeAccessible(method); |
||||
this.target = method.invoke(this.classLoader); |
||||
|
||||
// Check existence of BaseClassLoaderPolicy#addTranslator(Translator)
|
||||
this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME); |
||||
this.addTranslator = this.target.getClass().getMethod("addTranslator", this.translatorClass); |
||||
} |
||||
catch (Exception ex) { |
||||
throw new IllegalStateException( |
||||
"Could not initialize JBoss LoadTimeWeaver because the JBoss 6 API classes are not available", ex); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void addTransformer(ClassFileTransformer transformer) { |
||||
InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer); |
||||
Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(), |
||||
new Class<?>[] {this.translatorClass}, adapter); |
||||
try { |
||||
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 this.classLoader; |
||||
} |
||||
|
||||
} |
@ -1,87 +0,0 @@
@@ -1,87 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* 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; |
||||
import java.lang.reflect.InvocationHandler; |
||||
import java.lang.reflect.Method; |
||||
import java.security.ProtectionDomain; |
||||
|
||||
/** |
||||
* Adapter that implements JBoss Translator interface, delegating to a |
||||
* standard JDK {@link ClassFileTransformer} underneath. |
||||
* |
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is |
||||
* being used. |
||||
* |
||||
* @author Costin Leau |
||||
* @since 3.1 |
||||
*/ |
||||
class JBossMCTranslatorAdapter implements InvocationHandler { |
||||
|
||||
private final ClassFileTransformer transformer; |
||||
|
||||
|
||||
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 proxy == args[0]; |
||||
} |
||||
else if ("hashCode".equals(name)) { |
||||
return hashCode(); |
||||
} |
||||
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)) { |
||||
unregisterClassLoader((ClassLoader) args[0]); |
||||
return null; |
||||
} |
||||
else { |
||||
throw new IllegalArgumentException("Unknown method: " + method); |
||||
} |
||||
} |
||||
|
||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, |
||||
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception { |
||||
|
||||
return this.transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer); |
||||
} |
||||
|
||||
public void unregisterClassLoader(ClassLoader loader) { |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public String toString() { |
||||
StringBuilder builder = new StringBuilder(getClass().getName()); |
||||
builder.append(" for transformer: "); |
||||
builder.append(this.transformer); |
||||
return builder.toString(); |
||||
} |
||||
|
||||
} |
@ -1,80 +0,0 @@
@@ -1,80 +0,0 @@
|
||||
/* |
||||
* 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. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* 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; |
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Method; |
||||
|
||||
import org.springframework.util.ReflectionUtils; |
||||
|
||||
/** |
||||
* 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 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 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); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void addTransformer(ClassFileTransformer transformer) { |
||||
try { |
||||
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 this.classLoader; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue