diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java index 91d2fef5a6..2b2c249614 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -243,7 +243,7 @@ class BootZipCopyAction implements CopyAction { details.copyTo(this.out); this.out.closeArchiveEntry(); if (BootZipCopyAction.this.librarySpec.isSatisfiedBy(details)) { - this.writtenLibraries.add(name.substring(name.lastIndexOf('/') + 1)); + this.writtenLibraries.add(name); } if (BootZipCopyAction.this.layerResolver != null) { Layer layer = BootZipCopyAction.this.layerResolver.getLayer(details); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootjar/classpath/BootJarClasspathApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootjar/classpath/BootJarClasspathApplication.java new file mode 100644 index 0000000000..fa70335dad --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootjar/classpath/BootJarClasspathApplication.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bootjar.classpath; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * Application used for testing classpath handling with BootJar. + * + * @author Andy Wilkinson + */ +public class BootJarClasspathApplication { + + protected BootJarClasspathApplication() { + + } + + public static void main(String[] args) { + int i = 1; + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + for (URL url : ((URLClassLoader) classLoader).getURLs()) { + System.out.println(i++ + ". " + url.getFile()); + } + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/main/CustomMainClass.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootjar/main/CustomMainClass.java similarity index 96% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/main/CustomMainClass.java rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootjar/main/CustomMainClass.java index dfa5c64af0..c1b044c95a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/main/CustomMainClass.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootjar/main/CustomMainClass.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.main; +package com.example.bootjar.main; /** * Application used for testing {@code BootRun}'s main class configuration. diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/classpath/BootRunClasspathApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/classpath/BootRunClasspathApplication.java similarity index 96% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/classpath/BootRunClasspathApplication.java rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/classpath/BootRunClasspathApplication.java index 44f579e99e..308cbddb81 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/classpath/BootRunClasspathApplication.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/classpath/BootRunClasspathApplication.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.classpath; +package com.example.bootrun.classpath; import java.io.File; import java.lang.management.ManagementFactory; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/jvmargs/BootRunJvmArgsApplication.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/jvmargs/BootRunJvmArgsApplication.java similarity index 96% rename from spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/jvmargs/BootRunJvmArgsApplication.java rename to spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/jvmargs/BootRunJvmArgsApplication.java index f3b111f716..cfb8c83377 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/jvmargs/BootRunJvmArgsApplication.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/jvmargs/BootRunJvmArgsApplication.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.example.jvmargs; +package com.example.bootrun.jvmargs; import java.lang.management.ManagementFactory; diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/main/CustomMainClass.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/main/CustomMainClass.java new file mode 100644 index 0000000000..ccb847c99d --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootrun/main/CustomMainClass.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bootrun.main; + +/** + * Application used for testing {@code BootRun}'s main class configuration. + * + * @author Andy Wilkinson + */ +public class CustomMainClass { + + protected CustomMainClass() { + + } + + public static void main(String[] args) { + System.out.println(CustomMainClass.class.getName()); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootwar/main/CustomMainClass.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootwar/main/CustomMainClass.java new file mode 100644 index 0000000000..be96fb18e7 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/com/example/bootwar/main/CustomMainClass.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.bootwar.main; + +/** + * Application used for testing {@code BootRun}'s main class configuration. + * + * @author Andy Wilkinson + */ +public class CustomMainClass { + + protected CustomMainClass() { + + } + + public static void main(String[] args) { + System.out.println(CustomMainClass.class.getName()); + } + +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java index 21fb15d1b3..37ff902e93 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java @@ -19,6 +19,7 @@ package org.springframework.boot.gradle.tasks.bundling; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Locale; import java.util.function.Consumer; import java.util.jar.Attributes; import java.util.jar.JarEntry; @@ -196,7 +197,8 @@ abstract class AbstractBootArchiveIntegrationTests { .isEqualTo(TaskOutcome.SUCCESS); try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) { Attributes mainAttributes = jarFile.getManifest().getMainAttributes(); - assertThat(mainAttributes.getValue("Start-Class")).isEqualTo("com.example.main.CustomMainClass"); + assertThat(mainAttributes.getValue("Start-Class")) + .isEqualTo("com.example." + this.taskName.toLowerCase(Locale.ENGLISH) + ".main.CustomMainClass"); } assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome()) .isEqualTo(TaskOutcome.UP_TO_DATE); @@ -206,10 +208,13 @@ abstract class AbstractBootArchiveIntegrationTests { copyApplication("main"); } - private void copyApplication(String name) throws IOException { - File output = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example/" + name); + protected void copyApplication(String name) throws IOException { + File output = new File(this.gradleBuild.getProjectDir(), + "src/main/java/com/example/" + this.taskName.toLowerCase() + "/" + name); output.mkdirs(); - FileSystemUtils.copyRecursively(new File("src/test/java/com/example/" + name), output); + FileSystemUtils.copyRecursively( + new File("src/test/java/com/example/" + this.taskName.toLowerCase(Locale.ENGLISH) + "/" + name), + output); } private void createStandardJar(File location) throws IOException { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java index 7f7998a8b3..f488f107d8 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java @@ -296,6 +296,30 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { .isEqualTo(TaskOutcome.SUCCESS); } + @TestTemplate + void packagedApplicationClasspath() throws IOException { + copyClasspathApplication(); + BuildResult result = this.gradleBuild.build("launch"); + String output = result.getOutput(); + assertThat(output).containsPattern("1\\. .*classes"); + assertThat(output).containsPattern("2\\. .*library-1.0-SNAPSHOT.jar"); + assertThat(output).containsPattern("3\\. .*commons-lang3-3.9.jar"); + assertThat(output).containsPattern("4\\. .*spring-boot-jarmode-layertools-.*.jar"); + assertThat(output).doesNotContain("5. "); + } + + @TestTemplate + void explodedApplicationClasspath() throws IOException { + copyClasspathApplication(); + BuildResult result = this.gradleBuild.build("launch"); + String output = result.getOutput(); + assertThat(output).containsPattern("1\\. .*classes"); + assertThat(output).containsPattern("2\\. .*spring-boot-jarmode-layertools-.*.jar"); + assertThat(output).containsPattern("3\\. .*library-1.0-SNAPSHOT.jar"); + assertThat(output).containsPattern("4\\. .*commons-lang3-3.9.jar"); + assertThat(output).doesNotContain("5. "); + } + private void assertExtractedLayers(List layerNames, Map> indexedLayers) throws IOException { Map> extractedLayers = readExtractedLayers(this.gradleBuild.getProjectDir(), layerNames); @@ -395,4 +419,8 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests { return extractedLayers; } + private void copyClasspathApplication() throws IOException { + copyApplication("classpath"); + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java index 9496b5b780..795c16e3e6 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -230,9 +230,10 @@ class BootJarTests extends AbstractBootArchiveTests { @Test void whenJarIsLayeredClasspathIndexPointsToLayeredLibs() throws IOException { try (JarFile jarFile = new JarFile(createLayeredJar())) { - assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly("- \"first-library.jar\"", - "- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\"", "- \"first-project-library.jar\"", - "- \"second-project-library-SNAPSHOT.jar\""); + assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly( + "- \"BOOT-INF/lib/first-library.jar\"", "- \"BOOT-INF/lib/second-library.jar\"", + "- \"BOOT-INF/lib/third-library-SNAPSHOT.jar\"", "- \"BOOT-INF/lib/first-project-library.jar\"", + "- \"BOOT-INF/lib/second-project-library-SNAPSHOT.jar\""); } } @@ -254,9 +255,10 @@ class BootJarTests extends AbstractBootArchiveTests { try (JarFile jarFile = new JarFile(createPopulatedJar())) { assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index")) .isEqualTo("BOOT-INF/classpath.idx"); - assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly("- \"first-library.jar\"", - "- \"second-library.jar\"", "- \"third-library-SNAPSHOT.jar\"", "- \"first-project-library.jar\"", - "- \"second-project-library-SNAPSHOT.jar\""); + assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly( + "- \"BOOT-INF/lib/first-library.jar\"", "- \"BOOT-INF/lib/second-library.jar\"", + "- \"BOOT-INF/lib/third-library-SNAPSHOT.jar\"", "- \"BOOT-INF/lib/first-project-library.jar\"", + "- \"BOOT-INF/lib/second-project-library-SNAPSHOT.jar\""); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests.java index 066131ea53..a35f515e54 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests.java @@ -71,7 +71,7 @@ class BootRunIntegrationTests { copyMainClassApplication(); BuildResult result = this.gradleBuild.build("bootRun"); assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); - assertThat(result.getOutput()).contains("com.example.main.CustomMainClass"); + assertThat(result.getOutput()).contains("com.example.bootrun.main.CustomMainClass"); } @TestTemplate @@ -79,7 +79,7 @@ class BootRunIntegrationTests { copyMainClassApplication(); BuildResult result = this.gradleBuild.build("bootRun"); assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); - assertThat(result.getOutput()).contains("com.example.main.CustomMainClass"); + assertThat(result.getOutput()).contains("com.example.bootrun.main.CustomMainClass"); } @TestTemplate @@ -87,7 +87,8 @@ class BootRunIntegrationTests { copyClasspathApplication(); BuildResult result = this.gradleBuild.build("bootRun"); assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); - assertThat(result.getOutput()).contains("Main class name = com.example.classpath.BootRunClasspathApplication"); + assertThat(result.getOutput()) + .contains("Main class name = com.example.bootrun.classpath.BootRunClasspathApplication"); } @TestTemplate @@ -150,9 +151,9 @@ class BootRunIntegrationTests { } private void copyApplication(String name) throws IOException { - File output = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example/" + name); + File output = new File(this.gradleBuild.getProjectDir(), "src/main/java/com/example/bootrun/" + name); output.mkdirs(); - FileSystemUtils.copyRecursively(new File("src/test/java/com/example/" + name), output); + FileSystemUtils.copyRecursively(new File("src/test/java/com/example/bootrun/" + name), output); } private String canonicalPathOf(String path) throws IOException { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-explodedApplicationClasspath.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-explodedApplicationClasspath.gradle new file mode 100644 index 0000000000..e0774d64ba --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-explodedApplicationClasspath.gradle @@ -0,0 +1,25 @@ +plugins { + id 'java' + id 'org.springframework.boot' version '{version}' +} + +repositories { + mavenCentral() + maven { url "file:repository" } +} + +dependencies { + implementation("com.example:library:1.0-SNAPSHOT") + implementation("org.apache.commons:commons-lang3:3.9") +} + +task explode(type: Sync) { + dependsOn(bootJar) + destinationDir = file("$buildDir/exploded") + from zipTree(files(bootJar).singleFile) +} + +task launch(type: JavaExec) { + classpath = files(explode) + main = 'org.springframework.boot.loader.JarLauncher' +} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-packagedApplicationClasspath.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-packagedApplicationClasspath.gradle new file mode 100644 index 0000000000..72b2787a43 --- /dev/null +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-packagedApplicationClasspath.gradle @@ -0,0 +1,19 @@ + +plugins { + id 'java' + id 'org.springframework.boot' version '{version}' +} + +task launch(type: JavaExec) { + classpath = files(bootJar) +} + +repositories { + mavenCentral() + maven { url "file:repository" } +} + +dependencies { + implementation("com.example:library:1.0-SNAPSHOT") + implementation("org.apache.commons:commons-lang3:3.9") +} diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-applicationPluginMainClassNameIsUsed.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-applicationPluginMainClassNameIsUsed.gradle index 3e72e7582d..60588fdb37 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-applicationPluginMainClassNameIsUsed.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-applicationPluginMainClassNameIsUsed.gradle @@ -3,4 +3,4 @@ plugins { id 'org.springframework.boot' version '{version}' } -mainClassName = 'com.example.main.CustomMainClass' +mainClassName = 'com.example.bootrun.main.CustomMainClass' diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-springBootExtensionMainClassNameIsUsed.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-springBootExtensionMainClassNameIsUsed.gradle index 36730c1c29..082de3eb00 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-springBootExtensionMainClassNameIsUsed.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/run/BootRunIntegrationTests-springBootExtensionMainClassNameIsUsed.gradle @@ -4,5 +4,5 @@ plugins { } springBoot { - mainClass = 'com.example.main.CustomMainClass' + mainClass = 'com.example.bootrun.main.CustomMainClass' } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java index 0dbae37407..e0c1dd22ff 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -479,15 +479,11 @@ public abstract class Packager { } private void writeClasspathIndex(RepackagingLayout layout, AbstractJarWriter writer) throws IOException { - List names = this.libraries.keySet().stream().map(this::getJarName) - .map((name) -> "- \"" + name + "\"").collect(Collectors.toList()); + List names = this.libraries.keySet().stream().map((path) -> "- \"" + path + "\"") + .collect(Collectors.toList()); writer.writeIndexFile(layout.getClasspathIndexFileLocation(), names); } - private String getJarName(String path) { - return path.substring(path.lastIndexOf('/') + 1); - } - } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java index afeacd673d..8bcfc93826 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/AbstractPackagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -234,7 +234,7 @@ abstract class AbstractPackagerTests

{ String index = getPackagedEntryContent("BOOT-INF/classpath.idx"); String[] libraries = index.split("\\r?\\n"); List expected = Stream.of(libJarFile1, libJarFile2, libJarFile3) - .map((jar) -> "- \"" + jar.getName() + "\"").collect(Collectors.toList()); + .map((jar) -> "- \"BOOT-INF/lib/" + jar.getName() + "\"").collect(Collectors.toList()); assertThat(Arrays.asList(libraries)).containsExactlyElementsOf(expected); } @@ -265,7 +265,7 @@ abstract class AbstractPackagerTests

{ assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue(); String classpathIndex = getPackagedEntryContent("BOOT-INF/classpath.idx"); List expectedClasspathIndex = Stream.of(libJarFile1, libJarFile2, libJarFile3) - .map((file) -> "- \"" + file.getName() + "\"").collect(Collectors.toList()); + .map((file) -> "- \"BOOT-INF/lib/" + file.getName() + "\"").collect(Collectors.toList()); assertThat(Arrays.asList(classpathIndex.split("\\n"))).containsExactlyElementsOf(expectedClasspathIndex); assertThat(hasPackagedEntry("BOOT-INF/layers.idx")).isTrue(); String layersIndex = getPackagedEntryContent("BOOT-INF/layers.idx"); @@ -296,7 +296,7 @@ abstract class AbstractPackagerTests

{ assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue(); String classpathIndex = getPackagedEntryContent("BOOT-INF/classpath.idx"); assertThat(Arrays.asList(classpathIndex.split("\\n"))) - .containsExactly("- \"spring-boot-jarmode-layertools.jar\""); + .containsExactly("- \"BOOT-INF/lib/spring-boot-jarmode-layertools.jar\""); assertThat(hasPackagedEntry("BOOT-INF/layers.idx")).isTrue(); String layersIndex = getPackagedEntryContent("BOOT-INF/layers.idx"); List expectedLayers = new ArrayList<>(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/ClassPathIndexFileTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/ClassPathIndexFileTests.java index f8bba406d6..889b045ed9 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/ClassPathIndexFileTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/ClassPathIndexFileTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,11 +78,11 @@ class ClassPathIndexFileTests { ClassPathIndexFile indexFile = copyAndLoadTestIndexFile(); List urls = indexFile.getUrls(); List expected = new ArrayList<>(); - expected.add(new File(this.temp, "a.jar")); - expected.add(new File(this.temp, "b.jar")); - expected.add(new File(this.temp, "c.jar")); - expected.add(new File(this.temp, "d.jar")); - expected.add(new File(this.temp, "e.jar")); + expected.add(new File(this.temp, "BOOT-INF/layers/one/lib/a.jar")); + expected.add(new File(this.temp, "BOOT-INF/layers/one/lib/b.jar")); + expected.add(new File(this.temp, "BOOT-INF/layers/one/lib/c.jar")); + expected.add(new File(this.temp, "BOOT-INF/layers/two/lib/d.jar")); + expected.add(new File(this.temp, "BOOT-INF/layers/two/lib/e.jar")); assertThat(urls).containsExactly(expected.stream().map(this::toUrl).toArray(URL[]::new)); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/resources/org/springframework/boot/loader/classpath-index-file.idx b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/resources/org/springframework/boot/loader/classpath-index-file.idx index a08268d5ac..b84b99a6b4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/resources/org/springframework/boot/loader/classpath-index-file.idx +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/resources/org/springframework/boot/loader/classpath-index-file.idx @@ -1,5 +1,5 @@ -- "a.jar" -- "b.jar" -- "c.jar" -- "d.jar" -- "e.jar" +- "BOOT-INF/layers/one/lib/a.jar" +- "BOOT-INF/layers/one/lib/b.jar" +- "BOOT-INF/layers/one/lib/c.jar" +- "BOOT-INF/layers/two/lib/d.jar" +- "BOOT-INF/layers/two/lib/e.jar"