-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ClassLoader can't solve directories on Graal binary #1108
Comments
@olpaw Which version do we plan to release ? Thank you very much |
@guanchao-yang, @mageddo as of now (GraalVM 19.1.1) we only support adding resources that are real data files to native-images. A directory on its own is not seen as a resource because we cannot embed a directory into a native-image. If we'd add support for that, which kind of usage patterns would need to be supported on resources that represent directories to make spring work as expected? |
It's nothing really to do with Spring. The question above was about Flyway, where they sort the filenames in a directory and execute them as scripts in order. Webjars also likes to traverse "directories" in classpath resources (so it can resolve the "best" available resource matching the request). It's just a common pattern, to search for stuff in packages and subpackages. Here's a library dedicated to scanning classpath directories: https://github.com/classgraph/classgraph. It's used by the most recent versions of webjars, and naturally doesn't work in substratevm because of the above. |
Any progress here? Are there any workarounds we can do to list all files in a directory or in the classpath in general? |
Also running in troubles because of this... |
Me too. Are there any update nor workaround on it ? Thanks! |
We're currently working on implementing Flyway support on native-image and it turns out quite harder than we initially thought it would be. Any chances that this issue here will be implemented in the foreseeable future? Right now, we have to come up with workarounds for the classpath enumeration. It would be great if an application running in a native image could just use the classpath enumeration libraries like Reflections / Classgraph / Springs |
Interestingly, one can list resources at runtime: try (FileSystem fileSystem = FileSystems.newFileSystem(URI.create("resource:/"), Map.of(), classLoader)) {
Path path = fileSystem.getPath("folder");
try (Stream<Path> files = Files.walk(path)) {
files.forEach(file -> {
System.out.print(file.toString());
if (Files.isDirectory(file)) {
System.out.println(" (D)");
} else if (Files.isRegularFile(file)) {
System.out.println(" (F)");
} else {
System.out.println(" (?)");
}
});
}
} with one caveat: you can't list starting from the root folder, you have to know the name of the first directory where to start. With {
"resources": {
"includes": [
{
"pattern": "folder.*"
}
]
}
} and a directory tree under
this prints
This works because there is a filesystem named But this doesn't matter, because now we have to convince maintainers of Flyway, Reflections, etc. to add specific support for GraalVM. It would be nice if this would work in a JVM compatible way. |
I see that the discussion is a bit old, but maybe I could help here.
|
I couldn't build the original sample either. If you could post your changes it might be useful. How do you mean "it worked"? What did you run and what was the output? Instead I tried the Flyway sample at https://github.com/spring-projects/spring-aot-smoke-tests with a manual {
"resources": {
"includes": [
{
"pattern": "\\Qdb\/migration\/\\E.*"
}
]
}
} If you run |
Regarding the original sample (using the latest labsjdk11 and native image):
The output was as expected:
I'm not sure what is the problem with the original sample Gradle setup, so I will need to take a better look to see why it's not building using Regarding the spring aot smoke test, I'm running it right now. |
So the problem is that
I think @mhalbritter already alluded to this, but I wasn't following. It looks to me as if Flyway (and Spring etc.) could use the |
Right. Existing libraries have been working for over a decade scanning the classpath using Requiring all applications and libraries to add special support for The only reasonable solution I see is for GraalVM to provide the support already available in |
I tend to agree with @sbrannen take above. |
But |
Good point. Are you proposing that libraries like Spring Framework attempt to use If so, then I question GraalVM's choice of |
@mhalbritter's code above fails if the starting URI is a String rootPath = rootDirResource.getURI().getRawPath();
if (!("file").equals(rootDirResource.getURI().getScheme()) && rootPath.startsWith("/")) {
rootPath = rootPath.substring(1);
if (rootPath.length()==0) {
return result;
}
if (rootPath.endsWith("/")) {
rootPath = rootPath.substring(0, rootPath.length()-1);
}
if (rootPath.length()==0) {
return result;
}
} It would be good to not have to do that. |
@jovanstevanovic I've raised #5020, could you have a look? I'll try extracting feedback from here into separate issues so that we can close this one. |
@bclozel thanks for extracting the issue from this discussion, that is actually something that I've planned to do. Sure, we can close this one now. 💯 |
Context
I'm using embedded flyway to automatically migrate my database scripts and it solves directories on classpath to load sql files
What is expected
java.lang.ClassLoader#getResources(String)
returns the URL for the specified directoryWhat is happening
java.lang.ClassLoader#getResources(String)
returns an empty EnumerationSteps to reproduce
Here an example project reproducing the issue
App.java
The text was updated successfully, but these errors were encountered: