Support java.nio.file Paths and FileSystems with nested jars

Add a `NestedFileSystemProvider` implementation so that the JDK's
`ZipFileSystem` can load content from nested jars and nested
directory entries.

Creating a `ZipFileSystem` may be a relatively expensive operation as
zip structures need to be parsed and in the case of directory entries
a virtual datablock nees to be generated on the fly. As such, we
install the `ZipFileSystem` as late as possible since in a typical
application it may never be needed.

This commit also tweaks Gradle and Maven plugins to ensure that the
service loader file is written to repackaged jars.

Closes gh-7161
This commit is contained in:
Phillip Webb
2023-10-18 14:57:05 -07:00
parent 4b495ca2a9
commit 3c62defb9d
21 changed files with 2115 additions and 5 deletions

View File

@@ -220,7 +220,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
try (JarInputStream inputStream = new JarInputStream(new BufferedInputStream(loaderJar.openStream()))) {
JarEntry entry;
while ((entry = inputStream.getNextJarEntry()) != null) {
if (isDirectoryEntry(entry) || isClassEntry(entry)) {
if (isDirectoryEntry(entry) || isClassEntry(entry) || isServicesEntry(entry)) {
writeEntry(new JarArchiveEntry(entry), new InputStreamEntryWriter(inputStream));
}
}
@@ -235,6 +235,10 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
return entry.getName().endsWith(".class");
}
private boolean isServicesEntry(JarEntry entry) {
return !entry.isDirectory() && entry.getName().startsWith("META-INF/services/");
}
private void writeEntry(JarArchiveEntry entry, EntryWriter entryWriter) throws IOException {
writeEntry(entry, null, entryWriter, UnpackHandler.NEVER);
}