Skip to content

Commit

Permalink
Mimic directories as jars in IOUtils.loadNestedJarUri (#7705)
Browse files Browse the repository at this point in the history
Spring boot's LaunchedURLClassLoader creates weird urls that have directories that look like jars. This patch makes IOUtils handle such URLs.
Fixes grails/grails-core#12625
  • Loading branch information
yawkat authored Jul 20, 2022
1 parent 1f79bd1 commit e14d8ec
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
5 changes: 5 additions & 0 deletions core/src/main/java/io/micronaut/core/io/IOUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ private static Path loadNestedJarUri(List<Closeable> 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
Expand Down
27 changes: 27 additions & 0 deletions core/src/test/groovy/io/micronaut/core/io/IOUtilsSpec.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.micronaut.core.io

import spock.lang.Issue
import spock.lang.Specification

import java.nio.charset.StandardCharsets
Expand Down Expand Up @@ -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)
}
}

0 comments on commit e14d8ec

Please sign in to comment.