Skip to content

Conversation

@zakkak
Copy link
Collaborator

@zakkak zakkak commented Nov 13, 2023

Since #7670 it is no longer possible to build projects that include resources from paths with spaces.

How to reproduce:

  1. Build graal master from source
  2. export GRAALVM_HOME=/path/to/graal/master/build
  3. git clone https://github.com/quarkusio/quarkus
  4. cd quarkus
  5. ./mvnw -Dquickly
  6. ./mvnw -Dnative -pl integration-tests/simple\ with\ space -Dnative.surefire.skip -Dformat.skip -Dno-descriptor-tests clean verify -Dquarkus.native.container-build=false

This PR resolves this issue and adds a set of tests for resource names with spaces (which don't catch the issue at hand, but are still good to test against).

Closes quarkusio/quarkus#36998

@zakkak zakkak force-pushed the 2023-11-13-resources-with-space-fix branch from c39af7b to 7a31d81 Compare November 14, 2023 07:33
Copy link
Collaborator

@jerboaa jerboaa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should change this to ((JarURLConnection) url.openConnection()).getJarFileURL().toURI().getPath(); instead. See below.

Comment on lines 346 to 356
private JarFile urlToJarFile(URL url) {
try {
return ((JarURLConnection) url.openConnection()).getJarFileURL().getFile();
return ((JarURLConnection) url.openConnection()).getJarFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private boolean resourceIsDirectory(URL url, boolean fromJar, String resourcePath) throws IOException, URISyntaxException {
if (fromJar) {
try (JarFile jf = new JarFile(urlToJarPath(url))) {
try (JarFile jf = urlToJarFile(url)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the gist of it. Let url be new URL("jar:file:///home/sgehwolf/Documents/mandrel/bugs/quarkus/itest-with-space/test%20with%20space/byteman.jar!/META-INF/MANIFEST.MF")

Then we have this for the old code:

jshell> var x = ((JarURLConnection) url.openConnection()).getJarFileURL().getFile();
x ==> "/home/sgehwolf/Documents/mandrel/bugs/quarkus/it ... 0with%20space/byteman.jar"

jshell> JarFile f = new JarFile(x);
|  Exception java.nio.file.NoSuchFileException: /home/sgehwolf/Documents/mandrel/bugs/quarkus/itest-with-space/test%20with%20space/byteman.jar
|        at UnixException.translateToIOException (UnixException.java:92)
|        at UnixException.rethrowAsIOException (UnixException.java:106)
|        at UnixException.rethrowAsIOException (UnixException.java:111)
|        at UnixFileAttributeViews$Basic.readAttributes (UnixFileAttributeViews.java:55)
|        at UnixFileSystemProvider.readAttributes (UnixFileSystemProvider.java:148)
|        at LinuxFileSystemProvider.readAttributes (LinuxFileSystemProvider.java:99)
|        at Files.readAttributes (Files.java:1851)
|        at ZipFile$Source.get (ZipFile.java:1394)
|        at ZipFile$CleanableResource.<init> (ZipFile.java:716)
|        at ZipFile.<init> (ZipFile.java:250)
|        at ZipFile.<init> (ZipFile.java:179)
|        at JarFile.<init> (JarFile.java:346)
|        at JarFile.<init> (JarFile.java:317)
|        at JarFile.<init> (JarFile.java:256)
|        at (#29:1)

jshell> System.out.println(x);
/home/sgehwolf/Documents/mandrel/bugs/quarkus/itest-with-space/test%20with%20space/byteman.jar

And the new code:

jshell> URL url = new URL("jar:file:///home/sgehwolf/Documents/mandrel/bugs/quarkus/itest-with-space/test%20with%20space/byteman.jar!/META-INF/MANIFEST.MF")
url ==> jar:file:///home/sgehwolf/Documents/mandrel/bugs/ ... .jar!/META-INF/MANIFEST.MF

jshell> var x = ((JarURLConnection) url.openConnection()).getJarFile();
x ==> sun.net.www.protocol.jar.URLJarFile@4aa8f0b4

I.e. JarFile created from a String, expects URL decoded paths. OK. But looking at the implementation of getJarFile() I see that it creates a copy of the file, which is probably not what we want.

So I suggest to use:

private String urlToJarFile(URL url) {
            try {
                return ((JarURLConnection) url.openConnection()).getJarFileURL().toURI().getPath();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

... which should properly decode %20 to :

jshell> URL url = new URL("jar:file:///home/sgehwolf/Documents/mandrel/bugs/quarkus/itest-with-space/test%20with%20space/byteman.jar!/META-INF/MANIFEST.MF")
url ==> jar:file:///home/sgehwolf/Documents/mandrel/bugs/ ... .jar!/META-INF/MANIFEST.MF

jshell> var x = ((JarURLConnection) url.openConnection()).getJarFileURL().toURI().getPath();
x ==> "/home/sgehwolf/Documents/mandrel/bugs/quarkus/it ... st with space/byteman.jar"

jshell> JarFile f = new JarFile(x);
f ==> java.util.jar.JarFile@2a3046da

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that it creates a copy of the file, which is probably not what we want.

Good catch @jerboaa

So I suggest to use...

Done. Thanks!

@zakkak zakkak force-pushed the 2023-11-13-resources-with-space-fix branch from 7a31d81 to 3eedd42 Compare November 16, 2023 11:02
@zakkak zakkak requested review from dnestoro and jerboaa November 16, 2023 11:03
Copy link
Collaborator

@jerboaa jerboaa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to actually catch this in a test, but this seems fine to me and should be a safe change. Thanks!

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 16, 2023

Would be nice to actually catch this in a test

One option would be to build graal in a folder containing a space, but unfortunately that's not supported (there are some ninja related failures if you try to do it).

Another option would be to add a space in the jar file itself, the name is derived from

"SVM_TESTS" : {
so the following patch does the trick:

diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py
index 7c9555bccb5..713abcb06f4 100644
--- a/substratevm/mx.substratevm/suite.py
+++ b/substratevm/mx.substratevm/suite.py
@@ -1975,7 +1975,7 @@ suite = {
             "testDistribution" : True,
         },
 
-        "SVM_TESTS" : {
+        "SVM TESTS" : {
           "subDir": "src",
           "relpath" : True,
           "dependencies" : [

However, it will apply to all tests, i.e. we won't have a separate jar with spaces in the filename only for this test case. Which means that without this PR it results in:

com.oracle.svm.configure.test.config.OmitPreviousConfigTests started (4 of 65)
  testConfigDifference: Fatal error: Unexpected error while locating the configuration files.: java.lang.RuntimeException: java.nio.file.NoSuchFileException: /home/zakkak/code/graal/substratevm/mxbuild/jdk22/dists/jdk21/svm%20tests.jar
    at com.oracle.svm.core.jdk.Resources.get(Resources.java:317)
    at com.oracle.svm.core.jdk.Resources.createURLs(Resources.java:434)
    at com.oracle.svm.core.jdk.Resources.createURL(Resources.java:366)
    at com.oracle.svm.core.jdk.Resources.createURL(Resources.java:358)
    at com.oracle.svm.core.jdk.ResourcesHelper.nameToResourceURL(ResourcesHelper.java:102)
    at jdk.internal.loader.BootLoader.findResource(BootLoader.java:609)
    at java.lang.ClassLoader.getResource(ClassLoader.java:1409)
    at java.lang.ClassLoader.getResource(ClassLoader.java:1407)
    at java.lang.Class.getResource(DynamicHub.java:3160)
    at com.oracle.svm.configure.test.config.OmitPreviousConfigTests.lambda$loadTraceProcessorFromResourceDirectory$0(OmitPreviousConfigTests.java:68)
    at com.oracle.svm.configure.config.ConfigurationFileCollection.addDirectory(ConfigurationFileCollection.java:73)
    at com.oracle.svm.configure.test.config.OmitPreviousConfigTests.loadTraceProcessorFromResourceDirectory(OmitPreviousConfigTests.java:65)
    at com.oracle.svm.configure.test.config.OmitPreviousConfigTests.testConfigDifference(OmitPreviousConfigTests.java:107)
    at java.lang.reflect.Method.invoke(Method.java:580)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at com.oracle.mxtool.junit.MxJUnitWrapper.runRequest(MxJUnitWrapper.java:376)
    at com.oracle.svm.junit.SVMJUnitRunner.run(SVMJUnitRunner.java:164)
    at com.oracle.svm.junit.SVMJUnitRunner.main(SVMJUnitRunner.java:184)

I will try to create a new jar file (mx distribution) and add it as a dependency to SVM_TESTS to make this test-specific.

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 16, 2023

I will try to create a new jar file (mx distribution) and add it as a dependency to SVM_TESTS to make this test-specific.

Done in 8e03be8

@zakkak zakkak force-pushed the 2023-11-13-resources-with-space-fix branch 2 times, most recently from 436f857 to 8e03be8 Compare November 16, 2023 13:47
Copy link
Collaborator

@jerboaa jerboaa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. @fniephaus Could you help us get this pushed/reviewed? Thanks!

"testDistribution" : True,
},

"SVM_TESTS WITH SPACE" : {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might warrant a comment that there is intentionally a space in the name. Hard to spot ;-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed. @zakkak please add a comment in suite.py why we need exactly that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 17, 2023

@olpaw @dnestoro Could you help us getting this reviewed/integrated, please? It's a regression caused by #7670. Thanks!

@dnestoro
Copy link
Member

@olpaw @dnestoro Could you help us getting this reviewed/integrated, please? It's a regression caused by #7670. Thanks!

Sure, I will take a look on the PR next week (today I have some other priorities). Is that okay (or it is urgent to be done today)?

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 17, 2023

@olpaw @dnestoro Could you help us getting this reviewed/integrated, please? It's a regression caused by #7670. Thanks!

Sure, I will take a look on the PR next week (today I have some other priorities). Is that okay (or it is urgent to be done today)?

Next week is fine. We just don't want such issues hanging in the air without knowing if you guys are aware (as it's causing test failures for us). Thanks for the reply!

@dnestoro
Copy link
Member

Looks good to me! @olpaw can you also take a look on it before it gets merged?

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 20, 2023

Thanks for the review!

@olpaw olpaw self-requested a review November 20, 2023 14:15
return ((JarURLConnection) url.openConnection()).getJarFileURL().getFile();
} catch (IOException e) {
return ((JarURLConnection) url.openConnection()).getJarFileURL().toURI().getPath();
} catch (IOException | URISyntaxException e) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the small cleanups as well 😁

@olpaw olpaw changed the title Allow resources inclusion from jar files in paths containing spaces [GR-50220] Allow resources inclusion from jar files in paths containing spaces Nov 20, 2023
@zakkak zakkak force-pushed the 2023-11-13-resources-with-space-fix branch from 8e03be8 to 2d4c719 Compare November 20, 2023 18:14
@zakkak
Copy link
Collaborator Author

zakkak commented Nov 20, 2023

@jerboaa @dnestoro @olpaw Thank you for the review

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 21, 2023

Am I correct in thinking that this is in the merge queue?

@olpaw
Copy link
Member

olpaw commented Nov 21, 2023

Running in internal CI. Should be in merge queue soon.

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 21, 2023

Thanks!

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 24, 2023

@olpaw Any update on the merge queue status of this? Did it fail?

@zapster
Copy link
Member

zapster commented Nov 24, 2023

@jerboaa it is still in the merge queue. There is a lot going on currently, but I'm having an eye on it and make sure that it will go in.

@jerboaa
Copy link
Collaborator

jerboaa commented Nov 24, 2023

@zapster Thank you! Appreciate that.

@graalvmbot graalvmbot merged commit 50218dc into oracle:master Nov 25, 2023
@zakkak zakkak deleted the 2023-11-13-resources-with-space-fix branch November 27, 2023 07:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement. quarkus quarkus related issue redhat-interest

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GraalVM 24.0] quarkus-integration-test-simple-with-space fails to run with a recent JDK 22-based GraalVM master build

6 participants