diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/BannerProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/BannerProcessor.java index c30633dccaed2..7fcc656f85508 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/BannerProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/BannerProcessor.java @@ -2,16 +2,14 @@ import java.io.IOException; import java.io.UncheckedIOException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.AbstractMap; import java.util.Enumeration; import java.util.Map; import java.util.Scanner; -import java.util.jar.JarFile; import org.jboss.logging.Logger; @@ -103,20 +101,22 @@ private Map.Entry getBanner(BannerConfig config) throws IOExceptio } } - private boolean isQuarkusCoreBanner(URL url) throws IOException { + protected boolean isQuarkusCoreBanner(URL url) { if (!"jar".equals(url.getProtocol())) { return false; } String thisClassName = this.getClass().getName(); - String jarPath = url.getPath().substring(0, url.getPath().lastIndexOf('!')); - // We determine whether the banner is the default by checking to see if the jar that contains it also - // contains this class. This way although somewhat complicated guarantees that any rename of artifacts - // won't affect the check - try (JarFile jarFile = new JarFile(Paths.get(new URI(jarPath)).toFile())) { - return jarFile.getJarEntry(thisClassName.replace('.', '/') + ".class") != null; - } catch (URISyntaxException e) { + try { + return ClassPathUtils.processAsPath(url, p -> { + // We determine whether the banner is the default by checking to see if the jar that contains it also + // contains this class. This way although somewhat complicated guarantees that any rename of artifacts + // won't affect the check + Path resolved = p.resolve("/" + thisClassName.replace('.', '/') + ".class"); + return Files.exists(resolved); + }); + } catch (UncheckedIOException ex) { return false; } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/BannerProcessorTest.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/BannerProcessorTest.java new file mode 100644 index 0000000000000..40f0902f86eb8 --- /dev/null +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/BannerProcessorTest.java @@ -0,0 +1,55 @@ +package io.quarkus.deployment.pkg.steps; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.junit.jupiter.api.Test; + +import io.quarkus.deployment.steps.BannerProcessor; +import io.quarkus.fs.util.ZipUtils; + +public class BannerProcessorTest { + + class MyBannerProcessor extends BannerProcessor { + public boolean test(Path path) throws Exception { + return this.isQuarkusCoreBanner(path.toUri().toURL()); + } + } + + @Test + public void checkQuarkusCoreBannerOnFilesystemWithSpecialCharacters() throws Exception { + MyBannerProcessor processor = new MyBannerProcessor(); + + assertFalse(processor.test(Paths.get("tmp", "Descărcări", "test", "something!"))); + + final Path tmpDir = Files.createTempDirectory("Descărcări"); + final Path zipPath = tmpDir.resolve("BannerProcessorTest.jar"); + + try { + try (FileSystem ignored = ZipUtils.newZip(zipPath)) { + } + + try (FileSystem fs = ZipUtils.newFileSystem(zipPath)) { + assertFalse(processor.test(fs.getPath("/"))); + } + + try (final FileSystem fs = ZipUtils.newFileSystem(zipPath)) { + Path classFile = fs.getPath(MyBannerProcessor.class.getName().replace('.', '/') + ".class"); + Files.createDirectories(classFile.getParent()); + Files.write(classFile, "".getBytes(StandardCharsets.UTF_8)); + } + + try (FileSystem fs = ZipUtils.newFileSystem(zipPath)) { + assertTrue(processor.test(fs.getPath("/"))); + } + } finally { + Files.deleteIfExists(zipPath); + } + } +}