diff --git a/core/src/main/java/io/micronaut/core/io/IOUtils.java b/core/src/main/java/io/micronaut/core/io/IOUtils.java index 32e2d443512..8255f9667e4 100644 --- a/core/src/main/java/io/micronaut/core/io/IOUtils.java +++ b/core/src/main/java/io/micronaut/core/io/IOUtils.java @@ -136,6 +136,11 @@ private static Path loadNestedJarUri(List toClose, String jarUri) thr return Paths.get(URI.create(jarUri)); } Path jarPath = loadNestedJarUri(toClose, jarUri.substring(0, sep)); + if (Files.isDirectory(jarPath)) { + // spring boot creates weird jar URLs, like 'jar:file:/xyz.jar!/BOOT-INF/classes!/abc' + // This check makes our class loading resilient to that + return jarPath; + } FileSystem zipfs; try { // can't use newFileSystem(Path) here (without CL) because it doesn't exist on java 8 diff --git a/core/src/test/groovy/io/micronaut/core/io/IOUtilsSpec.groovy b/core/src/test/groovy/io/micronaut/core/io/IOUtilsSpec.groovy index 960868ca775..59327499228 100644 --- a/core/src/test/groovy/io/micronaut/core/io/IOUtilsSpec.groovy +++ b/core/src/test/groovy/io/micronaut/core/io/IOUtilsSpec.groovy @@ -1,5 +1,6 @@ package io.micronaut.core.io +import spock.lang.Issue import spock.lang.Specification import java.nio.charset.StandardCharsets @@ -66,4 +67,30 @@ class IOUtilsSpec extends Specification { cleanup: Files.deleteIfExists(zipPath) } + + @Issue('https://github.com/grails/grails-core/issues/12625/') + def 'dir inside jar'() { + given: + Path zipPath = Files.createTempFile("micronaut-ioutils-spec", ".zip") + try (ZipOutputStream outer = new ZipOutputStream(Files.newOutputStream(zipPath))) { + outer.putNextEntry(new ZipEntry("foo/bar/baz/test.txt")) + outer.write("bla".getBytes(StandardCharsets.UTF_8)) + outer.closeEntry() + } + + def visitedInner = [] + def textInner = [] + + when: + IOUtils.eachFile(URI.create('jar:' + zipPath.toUri() + '!/foo/bar!/xyz'), 'baz', entry -> { + visitedInner.add(entry.getFileName().toString()) + textInner = Files.readAllLines(entry) + }) + then: + visitedInner == ['test.txt'] + textInner == ['bla'] + + cleanup: + Files.deleteIfExists(zipPath) + } }