diff --git a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java index 8a4afb64447..3052f89ca39 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java @@ -27,6 +27,7 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributeView; import java.nio.file.attribute.FileTime; +import java.util.EnumSet; import java.util.Enumeration; import java.util.List; import java.util.Locale; @@ -249,9 +250,10 @@ class ExtractCommand extends Command { Manifest manifest = jarStructure.createLauncherManifest((library) -> librariesDirectory + library); mkdirs(file.getParentFile()); try (JarOutputStream output = new JarOutputStream(new FileOutputStream(file), manifest)) { + EnumSet allowedTypes = EnumSet.of(Type.APPLICATION_CLASS_OR_RESOURCE, Type.META_INF); withJarEntries(this.context.getArchiveFile(), ((stream, jarEntry) -> { Entry entry = jarStructure.resolve(jarEntry); - if (isType(entry, Type.APPLICATION_CLASS_OR_RESOURCE) && StringUtils.hasLength(entry.location())) { + if (entry != null && allowedTypes.contains(entry.type()) && StringUtils.hasLength(entry.location())) { JarEntry newJarEntry = createJarEntry(entry.location(), jarEntry); output.putNextEntry(newJarEntry); StreamUtils.copy(stream, output); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/IndexedJarStructure.java b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/IndexedJarStructure.java index 13184dd060f..855160ba1c6 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/IndexedJarStructure.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/IndexedJarStructure.java @@ -24,6 +24,7 @@ import java.nio.file.NoSuchFileException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.function.UnaryOperator; import java.util.jar.Attributes; import java.util.jar.Attributes.Name; @@ -48,6 +49,9 @@ class IndexedJarStructure implements JarStructure { private static final List MANIFEST_DENY_LIST = List.of("Start-Class", "Spring-Boot-Classes", "Spring-Boot-Lib", "Spring-Boot-Classpath-Index", "Spring-Boot-Layers-Index"); + private static final Set ENTRY_IGNORE_LIST = Set.of("META-INF/", "META-INF/MANIFEST.MF", + "META-INF/services/java.nio.file.spi.FileSystemProvider"); + private final Manifest originalManifest; private final String libLocation; @@ -89,6 +93,9 @@ class IndexedJarStructure implements JarStructure { @Override public Entry resolve(String name) { + if (ENTRY_IGNORE_LIST.contains(name)) { + return null; + } if (this.classpathEntries.contains(name)) { return new Entry(name, toStructureDependency(name), Type.LIBRARY); } @@ -98,6 +105,9 @@ class IndexedJarStructure implements JarStructure { if (name.startsWith("org/springframework/boot/loader")) { return new Entry(name, name, Type.LOADER); } + if (name.startsWith("META-INF/")) { + return new Entry(name, name, Type.META_INF); + } return null; } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/JarStructure.java b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/JarStructure.java index df0680a231f..c8c13dd27a9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/JarStructure.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/JarStructure.java @@ -71,7 +71,7 @@ interface JarStructure { enum Type { - LIBRARY, APPLICATION_CLASS_OR_RESOURCE, LOADER + LIBRARY, APPLICATION_CLASS_OR_RESOURCE, LOADER, META_INF } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/java/org/springframework/boot/jarmode/tools/ExtractCommandTests.java b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/java/org/springframework/boot/jarmode/tools/ExtractCommandTests.java index 7f6b2908444..dbf90066ff3 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/java/org/springframework/boot/jarmode/tools/ExtractCommandTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/java/org/springframework/boot/jarmode/tools/ExtractCommandTests.java @@ -62,7 +62,8 @@ class ExtractCommandTests extends AbstractJarModeTests { "BOOT-INF/lib/dependency-2.jar", "/jar-contents/dependency-2", "BOOT-INF/lib/dependency-3-SNAPSHOT.jar", "/jar-contents/dependency-3-SNAPSHOT", "org/springframework/boot/loader/launch/JarLauncher.class", "/jar-contents/JarLauncher", "BOOT-INF/classes/application.properties", - "/jar-contents/application.properties"); + "/jar-contents/application.properties", "META-INF/build-info.properties", + "/jar-contents/build-info.properties"); } private File file(String name) { @@ -207,6 +208,14 @@ class ExtractCommandTests extends AbstractJarModeTests { .contains("out/test.jar"); } + @Test + void shouldExtractFilesUnderMetaInf() throws IOException { + run(ExtractCommandTests.this.archive); + File application = file("test/test.jar"); + List entryNames = getJarEntryNames(application); + assertThat(entryNames).contains("META-INF/build-info.properties"); + } + } @Nested diff --git a/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/resources/jar-contents/build-info.properties b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/resources/jar-contents/build-info.properties new file mode 100644 index 00000000000..c98400888ec --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-jarmode-tools/src/test/resources/jar-contents/build-info.properties @@ -0,0 +1 @@ +build.artifact=test