From b946766483f1d4185b6a08c426962408f6cea8d0 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Fri, 1 May 2020 09:41:43 +0300 Subject: [PATCH] Fix broken directory with space handling Fixes: #8977 --- .github/workflows/ci-actions.yml | 7 +- .../quarkus/runtime/util/ClassPathUtils.java | 32 +++++-- integration-tests/pom.xml | 1 + integration-tests/simple with space/pom.xml | 92 +++++++++++++++++++ .../quarkus/it/spaces/GreetingResource.java | 21 +++++ .../it/spaces/GreetingResourceTest.java | 22 +++++ .../it/spaces/NativeGreetingResourceIT.java | 9 ++ 7 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 integration-tests/simple with space/pom.xml create mode 100644 integration-tests/simple with space/src/main/java/io/quarkus/it/spaces/GreetingResource.java create mode 100644 integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/GreetingResourceTest.java create mode 100644 integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/NativeGreetingResourceIT.java diff --git a/.github/workflows/ci-actions.yml b/.github/workflows/ci-actions.yml index 3ee3a99f80bf13..124b7b6c35ff7f 100644 --- a/.github/workflows/ci-actions.yml +++ b/.github/workflows/ci-actions.yml @@ -422,7 +422,7 @@ jobs: virtual-http rest-client - category: Misc1 - timeout: 40 + timeout: 45 test-modules: > maven jackson @@ -526,11 +526,16 @@ jobs: - name: Build with Maven env: TEST_MODULES: ${{matrix.test-modules}} + CATEGORY: ${{matrix.category}} run: | for i in $TEST_MODULES do modules+=("integration-tests/$i"); done IFS=, eval mvn -pl "${modules[*]}" $NATIVE_TEST_MAVEN_OPTS + # add the 'simple with spaces' project to the run of 'Misc1' by cd-ing into the directory since Maven doesn't like having names with spaces on the command line + if [ "$CATEGORY" == "Misc1" ]; then + mvn -Dnative -Dquarkus.native.container-build=true -B --settings .github/mvn-settings.xml -f 'integration-tests/simple with space/' verify + fi - name: Prepare failure archive (if maven failed) if: failure() shell: bash diff --git a/core/runtime/src/main/java/io/quarkus/runtime/util/ClassPathUtils.java b/core/runtime/src/main/java/io/quarkus/runtime/util/ClassPathUtils.java index 8cd07afc5cd535..24c0bd98f648bd 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/util/ClassPathUtils.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/util/ClassPathUtils.java @@ -175,17 +175,21 @@ public static void consumeStream(URL url, Consumer consumer) throws */ public static R readStream(URL url, Function function) throws IOException { if (JAR.equals(url.getProtocol())) { - final URI uri; - try { - uri = new URI(url.toString()); - } catch (URISyntaxException e) { - throw new IOException(e); - } + final URI uri = toURI(url); final String file = uri.getSchemeSpecificPart(); - final int exclam = file.lastIndexOf('!'); - final Path jar = toLocalPath(exclam >= 0 ? new URL(file.substring(0, exclam)) : url); + final int fileExclam = file.lastIndexOf('!'); + final URL jarURL; + if (fileExclam > 0) { + // we need to use the original url instead of the scheme specific part because it contains the properly encoded path + String urlFile = url.getFile(); + int urlExclam = urlFile.lastIndexOf('!'); + jarURL = new URL(urlFile.substring(0, urlExclam)); + } else { + jarURL = url; + } + final Path jar = toLocalPath(jarURL); try (FileSystem jarFs = FileSystems.newFileSystem(jar, (ClassLoader) null)) { - try (InputStream is = Files.newInputStream(jarFs.getPath(file.substring(exclam + 1)))) { + try (InputStream is = Files.newInputStream(jarFs.getPath(file.substring(fileExclam + 1)))) { return function.apply(is); } } @@ -200,6 +204,16 @@ public static R readStream(URL url, Function function) throw } } + private static URI toURI(URL url) throws IOException { + final URI uri; + try { + uri = new URI(url.toString()); + } catch (URISyntaxException e) { + throw new IOException(e); + } + return uri; + } + /** * Translates a URL to local file system path. * In case the the URL couldn't be translated to a file system path, diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index a1dabb1d672d08..7fd8ee2208da13 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -106,6 +106,7 @@ reactive-messaging-amqp rest-client packaging + simple with space diff --git a/integration-tests/simple with space/pom.xml b/integration-tests/simple with space/pom.xml new file mode 100644 index 00000000000000..14d35f533eeafa --- /dev/null +++ b/integration-tests/simple with space/pom.xml @@ -0,0 +1,92 @@ + + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + ../ + + 4.0.0 + + quarkus-integration-test-simple-with-space + Quarkus - Integration Tests - Simple with space + + A very basic integration test that contains a space in the directory and also resources files that contain spaces + + + + io.quarkus + quarkus-resteasy + + + + org.primefaces + primefaces + 8.0 + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + + + + + native + + + native + + + + + + maven-failsafe-plugin + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + + + + + + + + + native + + + + + diff --git a/integration-tests/simple with space/src/main/java/io/quarkus/it/spaces/GreetingResource.java b/integration-tests/simple with space/src/main/java/io/quarkus/it/spaces/GreetingResource.java new file mode 100644 index 00000000000000..ad59740540dd34 --- /dev/null +++ b/integration-tests/simple with space/src/main/java/io/quarkus/it/spaces/GreetingResource.java @@ -0,0 +1,21 @@ +package io.quarkus.it.spaces; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.primefaces.util.Constants; + +@Path("/hello") +public class GreetingResource { + + // make sure we reference something from Primefaces so GraalVM doesn't throw out the entire jar + private static final String PRIMEFACES_DOWNLOAD_COOKIE = Constants.DOWNLOAD_COOKIE; + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String hello() { + return "hello"; + } +} diff --git a/integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/GreetingResourceTest.java b/integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/GreetingResourceTest.java new file mode 100644 index 00000000000000..642ba0cb745de9 --- /dev/null +++ b/integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/GreetingResourceTest.java @@ -0,0 +1,22 @@ +package io.quarkus.it.spaces; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.CoreMatchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class GreetingResourceTest { + + @Test + public void testHelloEndpoint() { + given() + .when().get("/hello") + .then() + .statusCode(200) + .body(is("hello")); + } + +} diff --git a/integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/NativeGreetingResourceIT.java b/integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/NativeGreetingResourceIT.java new file mode 100644 index 00000000000000..c4a6f3d6d3d0ce --- /dev/null +++ b/integration-tests/simple with space/src/test/java/io/quarkus/it/spaces/NativeGreetingResourceIT.java @@ -0,0 +1,9 @@ +package io.quarkus.it.spaces; + +import io.quarkus.test.junit.NativeImageTest; + +@NativeImageTest +public class NativeGreetingResourceIT extends GreetingResourceTest { + + // Execute the same tests but in native mode. +}