|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2019 the original author or authors. |
|
|
|
* Copyright 2002-2024 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -17,6 +17,7 @@ |
|
|
|
package org.springframework.instrument.classloading.jboss; |
|
|
|
package org.springframework.instrument.classloading.jboss; |
|
|
|
|
|
|
|
|
|
|
|
import java.lang.instrument.ClassFileTransformer; |
|
|
|
import java.lang.instrument.ClassFileTransformer; |
|
|
|
|
|
|
|
import java.lang.reflect.Constructor; |
|
|
|
import java.lang.reflect.Field; |
|
|
|
import java.lang.reflect.Field; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
import java.lang.reflect.Method; |
|
|
|
|
|
|
|
|
|
|
|
@ -26,13 +27,14 @@ import org.springframework.lang.Nullable; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
import org.springframework.util.ReflectionUtils; |
|
|
|
|
|
|
|
import org.springframework.util.function.ThrowingFunction; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader. |
|
|
|
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader. |
|
|
|
* Thanks to Ales Justin and Marius Bogoevici for the initial prototype. |
|
|
|
* Thanks to Ales Justin and Marius Bogoevici for the initial prototype. |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>As of Spring Framework 5.0, this weaver supports WildFly 8+. |
|
|
|
* <p>This weaver supports WildFly 13-23 (DelegatingClassFileTransformer) as well as |
|
|
|
* As of Spring Framework 5.1.5, it also supports WildFly 13+. |
|
|
|
* WildFly 24+ (DelegatingClassTransformer), as of Spring Framework 6.1.15. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Costin Leau |
|
|
|
* @author Costin Leau |
|
|
|
* @author Juergen Hoeller |
|
|
|
* @author Juergen Hoeller |
|
|
|
@ -40,9 +42,15 @@ import org.springframework.util.ReflectionUtils; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class JBossLoadTimeWeaver implements LoadTimeWeaver { |
|
|
|
public class JBossLoadTimeWeaver implements LoadTimeWeaver { |
|
|
|
|
|
|
|
|
|
|
|
private static final String DELEGATING_TRANSFORMER_CLASS_NAME = |
|
|
|
private static final String LEGACY_DELEGATING_TRANSFORMER_CLASS_NAME = |
|
|
|
"org.jboss.as.server.deployment.module.DelegatingClassFileTransformer"; |
|
|
|
"org.jboss.as.server.deployment.module.DelegatingClassFileTransformer"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String DELEGATING_TRANSFORMER_CLASS_NAME = |
|
|
|
|
|
|
|
"org.jboss.as.server.deployment.module.DelegatingClassTransformer"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String CLASS_TRANSFORMER_CLASS_NAME = |
|
|
|
|
|
|
|
"org.jboss.modules.ClassTransformer"; |
|
|
|
|
|
|
|
|
|
|
|
private static final String WRAPPER_TRANSFORMER_CLASS_NAME = |
|
|
|
private static final String WRAPPER_TRANSFORMER_CLASS_NAME = |
|
|
|
"org.jboss.modules.JLIClassTransformer"; |
|
|
|
"org.jboss.modules.JLIClassTransformer"; |
|
|
|
|
|
|
|
|
|
|
|
@ -53,6 +61,8 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver { |
|
|
|
|
|
|
|
|
|
|
|
private final Method addTransformer; |
|
|
|
private final Method addTransformer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final ThrowingFunction<Object, Object> adaptTransformer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Create a new instance of the {@link JBossLoadTimeWeaver} class using |
|
|
|
* Create a new instance of the {@link JBossLoadTimeWeaver} class using |
|
|
|
@ -91,18 +101,29 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver { |
|
|
|
wrappedTransformer.setAccessible(true); |
|
|
|
wrappedTransformer.setAccessible(true); |
|
|
|
suggestedTransformer = wrappedTransformer.get(suggestedTransformer); |
|
|
|
suggestedTransformer = wrappedTransformer.get(suggestedTransformer); |
|
|
|
} |
|
|
|
} |
|
|
|
if (!suggestedTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) { |
|
|
|
|
|
|
|
|
|
|
|
Class<?> transformerType = ClassFileTransformer.class; |
|
|
|
|
|
|
|
if (suggestedTransformer.getClass().getName().equals(LEGACY_DELEGATING_TRANSFORMER_CLASS_NAME)) { |
|
|
|
|
|
|
|
this.adaptTransformer = (t -> t); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (suggestedTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) { |
|
|
|
|
|
|
|
transformerType = classLoader.loadClass(CLASS_TRANSFORMER_CLASS_NAME); |
|
|
|
|
|
|
|
Constructor<?> adaptedTransformer = classLoader.loadClass(WRAPPER_TRANSFORMER_CLASS_NAME) |
|
|
|
|
|
|
|
.getConstructor(ClassFileTransformer.class); |
|
|
|
|
|
|
|
this.adaptTransformer = adaptedTransformer::newInstance; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
throw new IllegalStateException( |
|
|
|
throw new IllegalStateException( |
|
|
|
"Transformer not of the expected type DelegatingClassFileTransformer: " + |
|
|
|
"Transformer not of expected type DelegatingClass(File)Transformer: " + |
|
|
|
suggestedTransformer.getClass().getName()); |
|
|
|
suggestedTransformer.getClass().getName()); |
|
|
|
} |
|
|
|
} |
|
|
|
this.delegatingTransformer = suggestedTransformer; |
|
|
|
this.delegatingTransformer = suggestedTransformer; |
|
|
|
|
|
|
|
|
|
|
|
Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(), |
|
|
|
Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(), |
|
|
|
"addTransformer", ClassFileTransformer.class); |
|
|
|
"addTransformer", transformerType); |
|
|
|
if (addTransformer == null) { |
|
|
|
if (addTransformer == null) { |
|
|
|
throw new IllegalArgumentException( |
|
|
|
throw new IllegalArgumentException( |
|
|
|
"Could not find 'addTransformer' method on JBoss DelegatingClassFileTransformer: " + |
|
|
|
"Could not find 'addTransformer' method on JBoss DelegatingClass(File)Transformer: " + |
|
|
|
this.delegatingTransformer.getClass().getName()); |
|
|
|
this.delegatingTransformer.getClass().getName()); |
|
|
|
} |
|
|
|
} |
|
|
|
addTransformer.setAccessible(true); |
|
|
|
addTransformer.setAccessible(true); |
|
|
|
@ -117,7 +138,7 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void addTransformer(ClassFileTransformer transformer) { |
|
|
|
public void addTransformer(ClassFileTransformer transformer) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
this.addTransformer.invoke(this.delegatingTransformer, transformer); |
|
|
|
this.addTransformer.invoke(this.delegatingTransformer, this.adaptTransformer.apply(transformer)); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Throwable ex) { |
|
|
|
catch (Throwable ex) { |
|
|
|
throw new IllegalStateException("Could not add transformer on JBoss ClassLoader: " + this.classLoader, ex); |
|
|
|
throw new IllegalStateException("Could not add transformer on JBoss ClassLoader: " + this.classLoader, ex); |
|
|
|
|