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 130dad7e624..f6db661d974 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 @@ -17,6 +17,7 @@ package org.springframework.instrument.classloading.jboss; import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -26,12 +27,14 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; +import org.springframework.util.function.ThrowingFunction; /** * {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader. * Thanks to Ales Justin and Marius Bogoevici for the initial prototype. * - *

This weaver supports WildFly 13+. + *

This weaver supports WildFly 13-23 (DelegatingClassFileTransformer) as well as + * WildFly 24+ (DelegatingClassTransformer), as of Spring Framework 6.1.15. * * @author Costin Leau * @author Juergen Hoeller @@ -39,9 +42,15 @@ import org.springframework.util.ReflectionUtils; */ 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"; + 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 = "org.jboss.modules.JLIClassTransformer"; @@ -52,6 +61,8 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver { private final Method addTransformer; + private final ThrowingFunction adaptTransformer; + /** * Create a new instance of the {@link JBossLoadTimeWeaver} class using @@ -90,18 +101,29 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver { wrappedTransformer.setAccessible(true); 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( - "Transformer not of the expected type DelegatingClassFileTransformer: " + + "Transformer not of expected type DelegatingClass(File)Transformer: " + suggestedTransformer.getClass().getName()); } this.delegatingTransformer = suggestedTransformer; Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(), - "addTransformer", ClassFileTransformer.class); + "addTransformer", transformerType); if (addTransformer == null) { 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()); } addTransformer.setAccessible(true); @@ -116,7 +138,7 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver { @Override public void addTransformer(ClassFileTransformer transformer) { try { - this.addTransformer.invoke(this.delegatingTransformer, transformer); + this.addTransformer.invoke(this.delegatingTransformer, this.adaptTransformer.apply(transformer)); } catch (Throwable ex) { throw new IllegalStateException("Could not add transformer on JBoss ClassLoader: " + this.classLoader, ex); diff --git a/spring-core/src/main/java/org/springframework/util/function/ThrowingBiFunction.java b/spring-core/src/main/java/org/springframework/util/function/ThrowingBiFunction.java index 5f62862a592..54c9d635c7a 100644 --- a/spring-core/src/main/java/org/springframework/util/function/ThrowingBiFunction.java +++ b/spring-core/src/main/java/org/springframework/util/function/ThrowingBiFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -85,17 +85,14 @@ public interface ThrowingBiFunction extends BiFunction { */ default ThrowingBiFunction throwing(BiFunction exceptionWrapper) { return new ThrowingBiFunction<>() { - @Override public R applyWithException(T t, U u) throws Exception { return ThrowingBiFunction.this.applyWithException(t, u); } - @Override public R apply(T t, U u) { return apply(t, u, exceptionWrapper); } - }; } diff --git a/spring-core/src/main/java/org/springframework/util/function/ThrowingConsumer.java b/spring-core/src/main/java/org/springframework/util/function/ThrowingConsumer.java index b42d91f86b9..03d8ed2f275 100644 --- a/spring-core/src/main/java/org/springframework/util/function/ThrowingConsumer.java +++ b/spring-core/src/main/java/org/springframework/util/function/ThrowingConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -77,17 +77,14 @@ public interface ThrowingConsumer extends Consumer { */ default ThrowingConsumer throwing(BiFunction exceptionWrapper) { return new ThrowingConsumer<>() { - @Override public void acceptWithException(T t) throws Exception { ThrowingConsumer.this.acceptWithException(t); } - @Override public void accept(T t) { accept(t, exceptionWrapper); } - }; } diff --git a/spring-core/src/main/java/org/springframework/util/function/ThrowingFunction.java b/spring-core/src/main/java/org/springframework/util/function/ThrowingFunction.java index 5759ac22bff..f9ab0ea245f 100644 --- a/spring-core/src/main/java/org/springframework/util/function/ThrowingFunction.java +++ b/spring-core/src/main/java/org/springframework/util/function/ThrowingFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -80,17 +80,14 @@ public interface ThrowingFunction extends Function { */ default ThrowingFunction throwing(BiFunction exceptionWrapper) { return new ThrowingFunction<>() { - @Override public R applyWithException(T t) throws Exception { return ThrowingFunction.this.applyWithException(t); } - @Override public R apply(T t) { return apply(t, exceptionWrapper); } - }; }