Browse Source

Consistent default ClassLoader fallback in hint classes

Closes gh-34470
6.1.x
Juergen Hoeller 10 months ago
parent
commit
7460be617b
  1. 19
      spring-core/src/main/java/org/springframework/aot/hint/ResourceHints.java
  2. 9
      spring-core/src/main/java/org/springframework/aot/hint/RuntimeHintsRegistrar.java
  3. 28
      spring-core/src/main/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrar.java
  4. 11
      spring-core/src/main/java/org/springframework/aot/hint/support/SpringFactoriesLoaderRuntimeHints.java

19
spring-core/src/main/java/org/springframework/aot/hint/ResourceHints.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2023 the original author or authors. * Copyright 2002-2025 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.
@ -27,6 +27,7 @@ import java.util.stream.Stream;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/** /**
* Gather the need for resources available at runtime. * Gather the need for resources available at runtime.
@ -50,14 +51,14 @@ public class ResourceHints {
this.resourceBundleHints = new LinkedHashSet<>(); this.resourceBundleHints = new LinkedHashSet<>();
} }
/** /**
* Return the resources that should be made available at runtime. * Return the resources that should be made available at runtime.
* @return a stream of {@link ResourcePatternHints} * @return a stream of {@link ResourcePatternHints}
*/ */
public Stream<ResourcePatternHints> resourcePatternHints() { public Stream<ResourcePatternHints> resourcePatternHints() {
Stream<ResourcePatternHints> patterns = this.resourcePatternHints.stream(); Stream<ResourcePatternHints> patterns = this.resourcePatternHints.stream();
return (this.types.isEmpty() ? patterns return (this.types.isEmpty() ? patterns : Stream.concat(Stream.of(typesPatternResourceHint()), patterns));
: Stream.concat(Stream.of(typesPatternResourceHint()), patterns));
} }
/** /**
@ -70,18 +71,18 @@ public class ResourceHints {
/** /**
* Register a pattern if the given {@code location} is available on the * Register a pattern if the given {@code location} is available on the
* classpath. This delegates to {@link ClassLoader#getResource(String)} * classpath. This delegates to {@link ClassLoader#getResource(String)} which
* which validates directories as well. The location is not included in * validates directories as well. The location is not included in the hint.
* the hint. * @param classLoader the ClassLoader to use, or {@code null} for the default
* @param classLoader the classloader to use
* @param location a '/'-separated path name that should exist * @param location a '/'-separated path name that should exist
* @param resourceHint a builder to customize the resource pattern * @param resourceHint a builder to customize the resource pattern
* @return {@code this}, to facilitate method chaining * @return {@code this}, to facilitate method chaining
*/ */
public ResourceHints registerPatternIfPresent(@Nullable ClassLoader classLoader, String location, public ResourceHints registerPatternIfPresent(@Nullable ClassLoader classLoader, String location,
Consumer<ResourcePatternHints.Builder> resourceHint) { Consumer<ResourcePatternHints.Builder> resourceHint) {
ClassLoader classLoaderToUse = (classLoader != null ? classLoader : getClass().getClassLoader());
if (classLoaderToUse.getResource(location) != null) { ClassLoader classLoaderToUse = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
if (classLoaderToUse != null && classLoaderToUse.getResource(location) != null) {
registerPattern(resourceHint); registerPattern(resourceHint);
} }
return this; return this;

9
spring-core/src/main/java/org/springframework/aot/hint/RuntimeHintsRegistrar.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2022 the original author or authors. * Copyright 2002-2025 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.
@ -25,8 +25,9 @@ import org.springframework.lang.Nullable;
* *
* <p>Implementations of this interface can be registered dynamically by using * <p>Implementations of this interface can be registered dynamically by using
* {@link org.springframework.context.annotation.ImportRuntimeHints @ImportRuntimeHints} * {@link org.springframework.context.annotation.ImportRuntimeHints @ImportRuntimeHints}
* or statically in {@code META-INF/spring/aot.factories} by using the FQN of this * or statically in {@code META-INF/spring/aot.factories} by using the fully-qualified
* interface as the key. A standard no-arg constructor is required for implementations. * class name of this interface as the key. A standard no-arg constructor is required
* for implementations.
* *
* @author Brian Clozel * @author Brian Clozel
* @author Stephane Nicoll * @author Stephane Nicoll
@ -38,7 +39,7 @@ public interface RuntimeHintsRegistrar {
/** /**
* Contribute hints to the given {@link RuntimeHints} instance. * Contribute hints to the given {@link RuntimeHints} instance.
* @param hints the hints contributed so far for the deployment unit * @param hints the hints contributed so far for the deployment unit
* @param classLoader the classloader, or {@code null} if even the system ClassLoader isn't accessible * @param classLoader the ClassLoader to use, or {@code null} for the default
*/ */
void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader); void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader);

28
spring-core/src/main/java/org/springframework/aot/hint/support/FilePatternResourceHintsRegistrar.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2023 the original author or authors. * Copyright 2002-2025 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.
@ -23,6 +23,7 @@ import java.util.List;
import org.springframework.aot.hint.ResourceHints; import org.springframework.aot.hint.ResourceHints;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils; import org.springframework.util.ResourceUtils;
/** /**
@ -66,19 +67,21 @@ public class FilePatternResourceHintsRegistrar {
@Deprecated(since = "6.0.12", forRemoval = true) @Deprecated(since = "6.0.12", forRemoval = true)
public void registerHints(ResourceHints hints, @Nullable ClassLoader classLoader) { public void registerHints(ResourceHints hints, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = (classLoader != null ? classLoader : getClass().getClassLoader()); ClassLoader classLoaderToUse = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
List<String> includes = new ArrayList<>(); if (classLoaderToUse != null) {
for (String location : this.classpathLocations) { List<String> includes = new ArrayList<>();
if (classLoaderToUse.getResource(location) != null) { for (String location : this.classpathLocations) {
for (String filePrefix : this.filePrefixes) { if (classLoaderToUse.getResource(location) != null) {
for (String fileExtension : this.fileExtensions) { for (String filePrefix : this.filePrefixes) {
includes.add(location + filePrefix + "*" + fileExtension); for (String fileExtension : this.fileExtensions) {
includes.add(location + filePrefix + "*" + fileExtension);
}
} }
} }
} }
} if (!includes.isEmpty()) {
if (!includes.isEmpty()) { hints.registerPattern(hint -> hint.includes(includes.toArray(String[]::new)));
hints.registerPattern(hint -> hint.includes(includes.toArray(String[]::new))); }
} }
} }
@ -246,8 +249,7 @@ public class FilePatternResourceHintsRegistrar {
* classpath location that resolves against the {@code ClassLoader}, files * classpath location that resolves against the {@code ClassLoader}, files
* with the configured file prefixes and extensions are registered. * with the configured file prefixes and extensions are registered.
* @param hints the hints contributed so far for the deployment unit * @param hints the hints contributed so far for the deployment unit
* @param classLoader the classloader, or {@code null} if even the system * @param classLoader the ClassLoader to use, or {@code null} for the default
* ClassLoader isn't accessible
*/ */
public void registerHints(ResourceHints hints, @Nullable ClassLoader classLoader) { public void registerHints(ResourceHints hints, @Nullable ClassLoader classLoader) {
build().registerHints(hints, classLoader); build().registerHints(hints, classLoader);

11
spring-core/src/main/java/org/springframework/aot/hint/support/SpringFactoriesLoaderRuntimeHints.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2024 the original author or authors. * Copyright 2002-2025 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.
@ -48,10 +48,11 @@ class SpringFactoriesLoaderRuntimeHints implements RuntimeHintsRegistrar {
@Override @Override
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) { public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = (classLoader != null ? classLoader : ClassLoader classLoaderToUse = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
SpringFactoriesLoaderRuntimeHints.class.getClassLoader()); if (classLoaderToUse != null) {
for (String resourceLocation : RESOURCE_LOCATIONS) { for (String resourceLocation : RESOURCE_LOCATIONS) {
registerHints(hints, classLoaderToUse, resourceLocation); registerHints(hints, classLoaderToUse, resourceLocation);
}
} }
} }

Loading…
Cancel
Save