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:
@@ -1,6 +1,8 @@
|
||||
plugins {
|
||||
id "java"
|
||||
id "org.springframework.boot"
|
||||
// id 'org.springframework.boot' version '3.1.4'
|
||||
// id 'io.spring.dependency-management' version '1.1.3'
|
||||
}
|
||||
|
||||
apply plugin: "io.spring.dependency-management"
|
||||
|
||||
@@ -17,8 +17,13 @@
|
||||
package org.springframework.boot.loaderapp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
@@ -27,6 +32,8 @@ import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
@SpringBootApplication
|
||||
@@ -49,9 +56,20 @@ public class LoaderTestApplication {
|
||||
String message = (!Arrays.equals(resourceContent, directContent)) ? "NO MATCH"
|
||||
: directContent.length + " BYTES";
|
||||
System.out.println(">>>>> " + message + " from " + resourceUrl);
|
||||
testGh7161();
|
||||
};
|
||||
}
|
||||
|
||||
private void testGh7161() {
|
||||
try {
|
||||
Resource resource = new ClassPathResource("gh-7161");
|
||||
Path path = Paths.get(resource.getURI());
|
||||
System.out.println(">>>>> gh-7161 " + Files.list(path).toList());
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(LoaderTestApplication.class, args).close();
|
||||
}
|
||||
|
||||
@@ -51,11 +51,12 @@ class LoaderIntegrationTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("javaRuntimes")
|
||||
void readUrlsWithoutWarning(JavaRuntime javaRuntime) {
|
||||
void runJar(JavaRuntime javaRuntime) {
|
||||
try (GenericContainer<?> container = createContainer(javaRuntime, "spring-boot-loader-tests-app", null)) {
|
||||
container.start();
|
||||
System.out.println(this.output.toUtf8String());
|
||||
assertThat(this.output.toUtf8String()).contains(">>>>> 287649 BYTES from")
|
||||
.contains(">>>>> gh-7161 [/gh-7161/example.txt]")
|
||||
.doesNotContain("WARNING:")
|
||||
.doesNotContain("illegal")
|
||||
.doesNotContain("jar written to temp");
|
||||
|
||||
Reference in New Issue
Block a user