Merge pull request #50383 from SebTardif

Closes gh-50383

* pr/50383:
  Remove compatibility code for EOL dependency versions
This commit is contained in:
Phillip Webb
2026-05-12 10:12:17 -07:00
7 changed files with 16 additions and 118 deletions
@@ -16,22 +16,10 @@
package org.springframework.boot.cache.metrics;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import com.hazelcast.spring.cache.HazelcastCache;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics;
import org.jspecify.annotations.Nullable;
import org.springframework.aot.hint.ExecutableMode;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.boot.cache.metrics.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* {@link CacheMeterBinderProvider} implementation for Hazelcast.
@@ -39,51 +27,11 @@ import org.springframework.util.ReflectionUtils;
* @author Stephane Nicoll
* @since 4.0.0
*/
@ImportRuntimeHints(HazelcastCacheMeterBinderProviderRuntimeHints.class)
public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvider<HazelcastCache> {
@Override
public MeterBinder getMeterBinder(HazelcastCache cache, Iterable<Tag> tags) {
try {
return new HazelcastCacheMetrics(cache.getNativeCache(), tags);
}
catch (NoSuchMethodError ex) {
// Hazelcast 4
return createHazelcast4CacheMetrics(cache, tags);
}
}
private MeterBinder createHazelcast4CacheMetrics(HazelcastCache cache, Iterable<Tag> tags) {
try {
Method nativeCacheAccessor = ReflectionUtils.findMethod(HazelcastCache.class, "getNativeCache");
Assert.state(nativeCacheAccessor != null, "'nativeCacheAccessor' must not be null");
Object nativeCache = ReflectionUtils.invokeMethod(nativeCacheAccessor, cache);
return HazelcastCacheMetrics.class.getConstructor(Object.class, Iterable.class)
.newInstance(nativeCache, tags);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to create MeterBinder for Hazelcast", ex);
}
}
static class HazelcastCacheMeterBinderProviderRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
try {
Method getNativeCacheMethod = ReflectionUtils.findMethod(HazelcastCache.class, "getNativeCache");
Assert.state(getNativeCacheMethod != null, "Unable to find 'getNativeCache' method");
Constructor<?> constructor = HazelcastCacheMetrics.class.getConstructor(Object.class, Iterable.class);
hints.reflection()
.registerMethod(getNativeCacheMethod, ExecutableMode.INVOKE)
.registerConstructor(constructor, ExecutableMode.INVOKE);
}
catch (NoSuchMethodException ex) {
throw new IllegalStateException(ex);
}
}
return new HazelcastCacheMetrics(cache.getNativeCache(), tags);
}
}
@@ -24,10 +24,6 @@ import io.micrometer.core.instrument.binder.MeterBinder;
import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.boot.cache.metrics.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -51,13 +47,4 @@ class HazelcastCacheMeterBinderProviderTests {
assertThat(meterBinder).isInstanceOf(HazelcastCacheMetrics.class);
}
@Test
void shouldRegisterHints() {
RuntimeHints runtimeHints = new RuntimeHints();
new HazelcastCacheMeterBinderProviderRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader());
assertThat(RuntimeHintsPredicates.reflection().onMethodInvocation(HazelcastCache.class, "getNativeCache"))
.accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.reflection().onType(HazelcastCacheMetrics.class)).accepts(runtimeHints);
}
}
@@ -319,7 +319,7 @@ public final class FlywayAutoConfiguration {
map.from(properties.isExecuteInTransaction()).to(configuration::executeInTransaction);
}
catch (NoSuchMethodError ex) {
// Flyway < 9.14
// Flyway < 10.x/11.x compatibility
}
}
@@ -67,7 +67,7 @@ public class FlywayMigrationInitializer implements InitializingBean, Ordered {
this.flyway.migrate();
}
catch (NoSuchMethodError ex) {
// Flyway < 7.0
// Flyway < 10.x/11.x compatibility
this.flyway.getClass().getMethod("migrate").invoke(this.flyway);
}
}
@@ -16,8 +16,6 @@
package org.springframework.boot.jetty;
import java.lang.reflect.Method;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Supplier;
@@ -30,7 +28,6 @@ import org.eclipse.jetty.server.Server;
import org.springframework.boot.web.server.GracefulShutdownCallback;
import org.springframework.boot.web.server.GracefulShutdownResult;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Handles Jetty graceful shutdown.
@@ -56,44 +53,22 @@ final class GracefulShutdown {
void shutDownGracefully(GracefulShutdownCallback callback) {
logger.info("Commencing graceful shutdown. Waiting for active requests to complete");
new Thread(() -> awaitShutdown(callback), "jetty-shutdown").start();
boolean jetty10 = isJetty10();
for (Connector connector : this.server.getConnectors()) {
shutdown(connector, !jetty10);
}
}
@SuppressWarnings("unchecked")
private void shutdown(Connector connector, boolean getResult) {
Future<Void> result;
try {
result = connector.shutdown();
}
catch (NoSuchMethodError ex) {
Method shutdown = ReflectionUtils.findMethod(connector.getClass(), "shutdown");
Assert.state(shutdown != null, "'shutdown' must not be null");
result = (Future<Void>) ReflectionUtils.invokeMethod(shutdown, connector);
}
if (getResult) {
try {
Assert.state(result != null, "'result' must not be null");
result.get();
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
catch (ExecutionException ex) {
// Continue
}
shutdown(connector);
}
}
private boolean isJetty10() {
private void shutdown(Connector connector) {
try {
return CompletableFuture.class.equals(Connector.class.getMethod("shutdown").getReturnType());
Future<Void> result = connector.shutdown();
Assert.state(result != null, "'result' must not be null");
result.get();
}
catch (Exception ex) {
return false;
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
catch (ExecutionException ex) {
// Continue
}
}
@@ -33,14 +33,8 @@ public class DisableReferenceClearingContextCustomizer implements TomcatContextC
if (!(context instanceof StandardContext standardContext)) {
return;
}
try {
standardContext.setClearReferencesRmiTargets(false);
standardContext.setClearReferencesThreadLocals(false);
}
catch (NoSuchMethodError ex) {
// Earlier version of Tomcat (probably without
// setClearReferencesThreadLocals). Continue.
}
standardContext.setClearReferencesRmiTargets(false);
standardContext.setClearReferencesThreadLocals(false);
}
}
@@ -274,13 +274,7 @@ public class TomcatWebServerFactoryCustomizer
valve.setTrustedProxies(remoteIpProperties.getTrustedProxies());
// The internal proxies default to a list of "safe" internal IP addresses
valve.setInternalProxies(remoteIpProperties.getInternalProxies());
try {
valve.setHostHeader(remoteIpProperties.getHostHeader());
}
catch (NoSuchMethodError ex) {
// Avoid failure with war deployments to Tomcat 8.5 before 8.5.44 and
// Tomcat 9 before 9.0.23
}
valve.setHostHeader(remoteIpProperties.getHostHeader());
valve.setPortHeader(remoteIpProperties.getPortHeader());
valve.setProtocolHeaderHttpsValue(remoteIpProperties.getProtocolHeaderHttpsValue());
// ... so it's safe to add this valve by default.