Browse Source

Ignore unloadable includes rather than failing

Fixes gh-48981
pull/49222/head
Andy Wilkinson 1 month ago
parent
commit
94fc407e07
  1. 8
      core/spring-boot-test/src/main/java/org/springframework/boot/test/context/filter/annotation/TypeIncludes.java
  2. 56
      core/spring-boot-test/src/test/java/org/springframework/boot/test/context/filter/annotation/TypeIncludesTests.java

8
core/spring-boot-test/src/main/java/org/springframework/boot/test/context/filter/annotation/TypeIncludes.java

@ -27,10 +27,13 @@ import java.util.HashSet; @@ -27,10 +27,13 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.core.io.UrlResource;
import org.springframework.core.log.LogMessage;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -49,6 +52,8 @@ final class TypeIncludes implements Iterable<Class<?>> { @@ -49,6 +52,8 @@ final class TypeIncludes implements Iterable<Class<?>> {
private static final String COMMENT_START = "#";
private static final Log logger = LogFactory.getLog(TypeIncludes.class);
private final Set<Class<?>> includes;
private TypeIncludes(Set<Class<?>> includes) {
@ -111,7 +116,8 @@ final class TypeIncludes implements Iterable<Class<?>> { @@ -111,7 +116,8 @@ final class TypeIncludes implements Iterable<Class<?>> {
includes.add(ClassUtils.forName(includeName, classLoader));
}
catch (Exception ex) {
throw new IllegalArgumentException("Failed to load include '" + includeName + "' declared in " + url);
logger.debug(LogMessage.format("Include '%s' declared in '%s' could not be loaded and has been ignored",
includeName, url), ex);
}
}
return includes;

56
core/spring-boot-test/src/test/java/org/springframework/boot/test/context/filter/annotation/TypeIncludesTests.java

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
/*
* Copyright 2012-present 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.test.context.filter.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Test;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link TypeIncludes}.
*
* @author Moritz Halbritter
*/
class TypeIncludesTests {
private static final String IMPORTS_FILE = "META-INF/spring/org.springframework.boot.test.context.filter.annotation.TypeIncludesTests$TestAnnotation.includes";
@Test
@WithResource(name = IMPORTS_FILE, content = """
org.springframework.boot.test.context.filter.annotation.TypeIncludesTests
org.springframework.boot.test.context.filter.annotation.DoesNotExist
""")
void loadReadsFromClasspathFileIgnoringNonExistentIncludes() {
TypeIncludes candidates = TypeIncludes.load(TestAnnotation.class,
Thread.currentThread().getContextClassLoader());
assertThat(candidates).containsExactly(TypeIncludesTests.class);
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
}
Loading…
Cancel
Save