Open sbrannen opened 1 year ago
A related topic came up during a meeting with the GraalVM team. Right now the resource configuration format in GraalVM accepts regexps, but they will restrict that in the future to only accept a subset - something like "org/springframework/test/context/aot/samples/basic/*"
and "*.yaml"
. The actual behavior is not defined yet.
This will need to happen because the runtime will start enforcing missing reflection and resource entries as exceptions. If you didn't register for it, you will get an exception at runtime if check for that resource. Doing that with extensive regexps is not a good fit at runtime.
they will restrict that in the future to only accept a subset
Thanks for the heads-up, @bclozel. That could certainly influence our decision.
The GraalVM team has merged support to "restrict the Expressivity of Patterns in resource-config.json" in PR https://github.com/oracle/graal/pull/8715 for inclusion in GraalVM for JDK 23 (September 17, 2024).
Overview
Prior to 6.1 M4 we did not have a need for registering resource hints for GraalVM native image for classpath location patterns (i.e., locations containing wildcards (
**
,*
, or?
) or using theclasspath*:
prefix). Rather, we only had a concrete need to support static classpath locations.However, since the introduction of support for location patterns in
@PropertySource
and@TestPropertySource
, we now need to be able to register resource hints for patterns such asclasspath*:my/config/**/file?.properties
.The Challenge
Class-path and module-path scanning uses
PathMatchingResourcePatternResolver
behind the scenes. To resolve the actual resources for a location pattern, we have to use thatResourcePatternResolver
which returns resource types such asFileSystemResource
andUrlResource
instead ofClassPathResource
, and it is not possible to easily infer the "path within the classpath" for aResource
type other thanClassPathResource
.For example, if we supply
classpath*:**/aot/samples/basic/test?.yaml
as the location pattern to@TestPropertySource
and usePathMatchingResourcePatternResolver
to resolve the actual locations, we end up with filesystem-based paths such as the following./Users/example/spring-framework/spring-test/bin/test/org/springframework/test/context/aot/samples/basic/test1.yaml
/Users/example/spring-framework/spring-test/bin/test/org/springframework/test/context/aot/samples/basic/test2.yaml
Whereas, what we actually need (in order to register resource hints) are the following paths within the classpath.
org/springframework/test/context/aot/samples/basic/test1.yaml
org/springframework/test/context/aot/samples/basic/test2.yaml
Brainstorming
One option is to use
PathMatchingResourcePatternResolver
to resolve the actual locations and then infer the "path within the classpath" by implementing logic specific to each resource type (e.g.,FileSystemResource
andUrlResource
). I spiked an implementation that supportsFileSystemResource
by iterating over all classpath roots for the current JVM to find a given classpath root that is the base directory for the givenFileSystemResource
and then extracting the "path within the classpath" by removing the base directory.That approach could work (and does work in my local tests); however, it does not take into account JARs in the classpath,
URLClassLoader
inspection, JAR manifests, etc. -- features thatPathMatchingResourcePatternResolver
supports while resolving the resources. In addition, it requires duplication of much of the logic inPathMatchingResourcePatternResolver
.Another option would be to introduce first-class support for registering an Ant-style classpath pattern in
org.springframework.aot.hint.ResourceHints
that transparently converts Ant-style wildcards into an analogous regular expression.If we don't implement first-class support for Ant-style patterns and don't want to go with the
PathMatchingResourcePatternResolver
option (which I am currently not in favor of due to the aforementioned drawbacks), we could introduce a utility that converts from Ant-style patterns to our simplistic "Spring resource hint patterns" (i.e., only supports*
) as follows.Passing the result of that function to
ResourceHints#registerPattern
works in my local test. However, that results in a lossy conversion from an Ant-style pattern TO a "Spring resource hint pattern" TO a regular expression (which is what is actually used in the JSON resource configuration file for GraalVM native image). Consequently, I am not in favor of introducing this utility: I've only included it here for the sake of completeness.Related Issues
21325
31055
31340
31429
⚠️ The following issues are currently blocked by this issue.
31161
31088
Deliverables