From f68df82b30a9d73b629c62c66e22956c64eaa73e Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 20 Nov 2023 15:50:06 -0800 Subject: [PATCH] Support lenient ContainerConnectionDetailsFactory hint registration Update `ContainerConnectionDetailsFactory` hint registration logic so that types are optional on the classpath. See gh-36606 Fixes gh-38392 --- .../ContainerConnectionDetailsFactory.java | 34 +++++++++++---- .../resources/META-INF/spring/aot.factories | 9 +--- ...ontainerConnectionDetailsFactoryHints.java | 33 +++++++++++++++ ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 4 +- ...ionDetailsFactoryWithoutActuatorTests.java | 41 +++++++++++++++++++ .../ModifiedClassPathClassLoader.java | 6 ++- 13 files changed, 123 insertions(+), 32 deletions(-) create mode 100644 spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java create mode 100644 spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactory.java b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactory.java index 174b84d103d..2a41db031fd 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactory.java +++ b/spring-boot-project/spring-boot-testcontainers/src/main/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactory.java @@ -17,7 +17,10 @@ package org.springframework.boot.testcontainers.service.connection; import java.util.Arrays; +import java.util.stream.Stream; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.testcontainers.containers.Container; import org.springframework.aot.hint.RuntimeHints; @@ -28,6 +31,8 @@ import org.springframework.boot.autoconfigure.service.connection.ConnectionDetai import org.springframework.boot.origin.Origin; import org.springframework.boot.origin.OriginProvider; import org.springframework.core.ResolvableType; +import org.springframework.core.io.support.SpringFactoriesLoader; +import org.springframework.core.io.support.SpringFactoriesLoader.FailureHandler; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -44,7 +49,7 @@ import org.springframework.util.ObjectUtils; * @since 3.1.0 */ public abstract class ContainerConnectionDetailsFactory, D extends ConnectionDetails> - implements ConnectionDetailsFactory, D>, RuntimeHintsRegistrar { + implements ConnectionDetailsFactory, D> { /** * Constant passed to the constructor when any connection name is accepted. @@ -92,12 +97,6 @@ public abstract class ContainerConnectionDetailsFactory, return null; } - @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - Arrays.stream(this.requiredClassNames) - .forEach((clazz) -> hints.reflection().registerTypeIfPresent(classLoader, clazz)); - } - private boolean hasRequiredClasses() { return ObjectUtils.isEmpty(this.requiredClassNames) || Arrays.stream(this.requiredClassNames) .allMatch((requiredClassName) -> ClassUtils.isPresent(requiredClassName, null)); @@ -161,4 +160,25 @@ public abstract class ContainerConnectionDetailsFactory, } + static class ContainerConnectionDetailsFactoriesRuntimeHints implements RuntimeHintsRegistrar { + + private static final Log logger = LogFactory.getLog(ContainerConnectionDetailsFactoriesRuntimeHints.class); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + SpringFactoriesLoader.forDefaultResourceLocation(classLoader) + .load(ConnectionDetailsFactory.class, FailureHandler.logging(logger)) + .stream() + .flatMap(this::requiredClassNames) + .forEach((requiredClassName) -> hints.reflection() + .registerTypeIfPresent(classLoader, requiredClassName)); + } + + private Stream requiredClassNames(ConnectionDetailsFactory connectionDetailsFactory) { + return (connectionDetailsFactory instanceof ContainerConnectionDetailsFactory containerConnectionDetailsFactory) + ? Stream.of(containerConnectionDetailsFactory.requiredClassNames) : Stream.empty(); + } + + } + } diff --git a/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring/aot.factories b/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring/aot.factories index a4aa3dfc74e..5b3d49bd502 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring/aot.factories +++ b/spring-boot-project/spring-boot-testcontainers/src/main/resources/META-INF/spring/aot.factories @@ -2,11 +2,4 @@ org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=\ org.springframework.boot.testcontainers.service.connection.ConnectionDetailsRegistrar.ServiceConnectionBeanRegistrationExcludeFilter org.springframework.aot.hint.RuntimeHintsRegistrar=\ -org.springframework.boot.testcontainers.service.connection.mongo.MongoContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.neo4j.Neo4jContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.MariaDbR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.MySqlR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.OracleR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.PostgresR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.r2dbc.SqlServerR2dbcContainerConnectionDetailsFactory,\ -org.springframework.boot.testcontainers.service.connection.zipkin.ZipkinContainerConnectionDetailsFactory +org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory.ContainerConnectionDetailsFactoriesRuntimeHints diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java new file mode 100644 index 00000000000..0ce8a7acf5d --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/ContainerConnectionDetailsFactoryHints.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-2023 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 + * + * https://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.boot.testcontainers.service.connection; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory.ContainerConnectionDetailsFactoriesRuntimeHints; + +public final class ContainerConnectionDetailsFactoryHints { + + private ContainerConnectionDetailsFactoryHints() { + } + + public static RuntimeHints getRegisteredHints(ClassLoader classLoader) { + RuntimeHints hints = new RuntimeHints(); + new ContainerConnectionDetailsFactoriesRuntimeHints().registerHints(hints, classLoader); + return hints; + } + +} diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java index 812ce2b9dcd..85c08223c67 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/mongo/MongoContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class MongoContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new MongoContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ConnectionString.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java index f1f962745a0..9c59c3e42be 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/neo4j/Neo4jContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.neo4j.driver.AuthToken; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class Neo4jContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new Neo4jContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(AuthToken.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java index ed4d79b46a5..f9b7ee2717b 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MariaDbR2dbcContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class MariaDbR2dbcContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new MariaDbR2dbcContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ConnectionFactoryOptions.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java index d7717c5b9d6..36642f20e90 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/MySqlR2dbcContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class MySqlR2dbcContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new MySqlR2dbcContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ConnectionFactoryOptions.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleR2dbcContainerConnectionDetailsFactoryTests.java index a21ec3c6e45..5aff194a1bf 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/OracleR2dbcContainerConnectionDetailsFactoryTests.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration; import org.springframework.boot.jdbc.DatabaseDriver; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.junit.DisabledOnOs; import org.springframework.boot.testsupport.testcontainers.DockerImageNames; @@ -72,8 +73,7 @@ class OracleR2dbcContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new OracleR2dbcContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ConnectionFactoryOptions.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java index 2780f04d8ef..a5fdf5d351d 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/PostgresR2dbcContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class PostgresR2dbcContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new PostgresR2dbcContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ConnectionFactoryOptions.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java index 73a5f3a6307..30e0348f0ab 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/r2dbc/SqlServerR2dbcContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class SqlServerR2dbcContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new SqlServerR2dbcContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ConnectionFactoryOptions.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java index 6e9def4f46f..9853b8d2daf 100644 --- a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; import static org.assertj.core.api.Assertions.assertThat; @@ -33,8 +34,7 @@ class ZipkinContainerConnectionDetailsFactoryTests { @Test void shouldRegisterHints() { - RuntimeHints hints = new RuntimeHints(); - new ZipkinContainerConnectionDetailsFactory().registerHints(hints, getClass().getClassLoader()); + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ZipkinAutoConfiguration.class)).accepts(hints); } diff --git a/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java new file mode 100644 index 00000000000..f4f03994dc1 --- /dev/null +++ b/spring-boot-project/spring-boot-testcontainers/src/test/java/org/springframework/boot/testcontainers/service/connection/zipkin/ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2023 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 + * + * https://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.boot.testcontainers.service.connection.zipkin; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactoryHints; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ZipkinContainerConnectionDetailsFactory}. + * + * @author Moritz Halbritter + */ +@ClassPathExclusions("spring-boot-actuator-*") +class ZipkinContainerConnectionDetailsFactoryWithoutActuatorTests { + + @Test + void shouldRegisterHints() { + RuntimeHints hints = ContainerConnectionDetailsFactoryHints.getRegisteredHints(getClass().getClassLoader()); + assertThat(hints).isNotNull(); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/ModifiedClassPathClassLoader.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/ModifiedClassPathClassLoader.java index ce8b3155907..53dd3b99dfc 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/ModifiedClassPathClassLoader.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/classpath/ModifiedClassPathClassLoader.java @@ -20,6 +20,7 @@ import java.io.File; import java.lang.management.ManagementFactory; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; @@ -297,7 +298,10 @@ final class ModifiedClassPathClassLoader extends URLClassLoader { private boolean isExcluded(URL url) { if ("file".equals(url.getProtocol())) { try { - String name = new File(url.toURI()).getName(); + URI uri = url.toURI(); + File file = new File(uri); + String name = (!uri.toString().endsWith("/")) ? file.getName() + : file.getParentFile().getParentFile().getName(); for (String exclusion : this.exclusions) { if (this.matcher.match(exclusion, name)) { return true;