diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/TarLayoutWriter.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/TarLayoutWriter.java index 3eddff38b2..66856ad034 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/TarLayoutWriter.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/TarLayoutWriter.java @@ -39,6 +39,7 @@ class TarLayoutWriter implements Layout, Closeable { TarLayoutWriter(OutputStream outputStream) { this.outputStream = new TarArchiveOutputStream(outputStream); + this.outputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/ZipFileTarArchive.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/ZipFileTarArchive.java index 525aa632d0..c6aea6c24c 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/ZipFileTarArchive.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/io/ZipFileTarArchive.java @@ -61,6 +61,7 @@ public class ZipFileTarArchive implements TarArchive { @Override public void writeTo(OutputStream outputStream) throws IOException { TarArchiveOutputStream tar = new TarArchiveOutputStream(outputStream); + tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); try (ZipFile zipFile = new ZipFile(this.zip)) { Enumeration entries = zipFile.getEntries(); while (entries.hasMoreElements()) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java index b904d0384a..59c445e5e5 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java @@ -20,6 +20,10 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Random; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.TaskOutcome; @@ -51,6 +55,7 @@ class BootBuildImageIntegrationTests { @TestTemplate void bootBuildImageBuildsImage() throws IOException { writeMainClass(); + writeLongNameResource(); BuildResult result = this.gradleBuild.build("bootBuildImage"); assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); ImageReference imageReference = ImageReference.of(ImageName.of(this.gradleBuild.getProjectDir().getName())); @@ -87,4 +92,18 @@ class BootBuildImageIntegrationTests { } } + private void writeLongNameResource() { + StringBuilder name = new StringBuilder(); + new Random().ints('a', 'z' + 1).limit(128).forEach((i) -> name.append((char) i)); + try { + Path path = this.gradleBuild.getProjectDir().toPath() + .resolve(Paths.get("src", "main", "resources", name.toString())); + Files.createDirectories(path.getParent()); + Files.createFile(path); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java index aa898f6b81..889bcda38f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/BuildImageTests.java @@ -18,6 +18,10 @@ package org.springframework.boot.maven; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Random; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; @@ -42,7 +46,7 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests { @TestTemplate void whenBuildImageIsInvokedWithoutRepackageTheArchiveIsRepackagedOnTheFly(MavenBuild mavenBuild) { - mavenBuild.project("build-image").goals("package").execute((project) -> { + mavenBuild.project("build-image").goals("package").prepare(this::writeLongNameResource).execute((project) -> { File jar = new File(project, "target/build-image-0.0.1.BUILD-SNAPSHOT.jar"); assertThat(jar).isFile(); File original = new File(project, "target/build-image-0.0.1.BUILD-SNAPSHOT.jar.original"); @@ -79,6 +83,19 @@ public class BuildImageTests extends AbstractArchiveIntegrationTests { }); } + private void writeLongNameResource(File project) { + StringBuilder name = new StringBuilder(); + new Random().ints('a', 'z' + 1).limit(128).forEach((i) -> name.append((char) i)); + try { + Path path = project.toPath().resolve(Paths.get("src", "main", "resources", name.toString())); + Files.createDirectories(path.getParent()); + Files.createFile(path); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + private void removeImage(ImageReference imageReference) { try { new DockerApi().image().remove(imageReference, false); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuild.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuild.java index 7c1609b34e..145c5a1354 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuild.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/MavenBuild.java @@ -70,6 +70,8 @@ class MavenBuild { private final Properties properties = new Properties(); + private Consumer preparation; + private File projectDir; MavenBuild(File home) { @@ -109,6 +111,11 @@ class MavenBuild { return this; } + MavenBuild prepare(Consumer callback) { + this.preparation = callback; + return this; + } + void execute(Consumer callback) { Invoker invoker = new DefaultInvoker(); invoker.setMavenHome(this.home); @@ -158,6 +165,9 @@ class MavenBuild { request.setBatchMode(true); File target = new File(this.temp, "target"); target.mkdirs(); + if (this.preparation != null) { + this.preparation.accept(this.temp); + } File buildLogFile = new File(target, "build.log"); try (PrintWriter buildLog = new PrintWriter(new FileWriter(buildLogFile))) { request.setOutputHandler(new InvocationOutputHandler() { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java index 0c88aaa2b8..795af32b97 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java @@ -215,6 +215,7 @@ public class BuildImageMojo extends AbstractPackagerMojo { @Override public void writeTo(OutputStream outputStream) throws IOException { TarArchiveOutputStream tar = new TarArchiveOutputStream(outputStream); + tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); this.packager.packageImage(this.libraries, (entry, entryWriter) -> write(entry, entryWriter, tar)); }