Skip to content

Commit 13f7db2

Browse files
committed
Write classpath index file from Gradle plugin
Closes gh-19847
1 parent 2198614 commit 13f7db2

File tree

2 files changed

+57
-2
lines changed
  • spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src

2 files changed

+57
-2
lines changed

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootJar.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import java.io.File;
2121
import java.io.IOException;
2222
import java.io.StringWriter;
23+
import java.util.ArrayList;
2324
import java.util.Collections;
25+
import java.util.List;
2426
import java.util.concurrent.Callable;
2527

2628
import org.gradle.api.Action;
@@ -59,7 +61,9 @@ public class BootJar extends Jar implements BootArchive {
5961

6062
private Layers layers;
6163

62-
private static final String BOOT_INF_LAYERS = "BOOT-INF/layers/";
64+
private static final String BOOT_INF_LAYERS = "BOOT-INF/layers";
65+
66+
private List<String> dependencies = new ArrayList<>();
6367

6468
/**
6569
* Creates a new {@code BootJar} task.
@@ -68,7 +72,10 @@ public BootJar() {
6872
this.bootInf = getProject().copySpec().into("BOOT-INF");
6973
getMainSpec().with(this.bootInf);
7074
this.bootInf.into("classes", classpathFiles(File::isDirectory));
71-
this.bootInf.into("lib", classpathFiles(File::isFile));
75+
this.bootInf.into("lib", classpathFiles(File::isFile))
76+
.eachFile((details) -> BootJar.this.dependencies.add(details.getPath()));
77+
this.bootInf.into("",
78+
(spec) -> spec.from((Callable<File>) () -> createClasspathIndex(BootJar.this.dependencies)));
7279
this.bootInf.filesMatching("module-info.class",
7380
(details) -> details.setRelativePath(details.getRelativeSourcePath()));
7481
getRootSpec().eachFile((details) -> {
@@ -93,9 +100,29 @@ public void copy() {
93100
attributes.remove("Spring-Boot-Lib");
94101
attributes.putIfAbsent("Spring-Boot-Layers-Index", "BOOT-INF/layers.idx");
95102
}
103+
attributes.putIfAbsent("Spring-Boot-Classpath-Index", "BOOT-INF/classpath.idx");
96104
super.copy();
97105
}
98106

107+
private File createClasspathIndex(List<String> dependencies) {
108+
try {
109+
StringWriter content = new StringWriter();
110+
BufferedWriter writer = new BufferedWriter(content);
111+
for (String dependency : dependencies) {
112+
writer.write(dependency);
113+
writer.write("\n");
114+
}
115+
writer.flush();
116+
File source = getProject().getResources().getText().fromString(content.toString()).asFile();
117+
File indexFile = new File(source.getParentFile(), "classpath.idx");
118+
source.renameTo(indexFile);
119+
return indexFile;
120+
}
121+
catch (IOException ex) {
122+
throw new RuntimeException("Failed to create classpath.idx", ex);
123+
}
124+
}
125+
99126
@Override
100127
protected CopyAction createCopyAction() {
101128
return this.support.createCopyAction(this);

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,37 @@ void layers() throws IOException {
9696
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(null);
9797
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Layers-Index"))
9898
.isEqualTo("BOOT-INF/layers.idx");
99+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
100+
.isEqualTo("BOOT-INF/classpath.idx");
99101
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/layers.idx"))) {
100102
assertThat(input).hasContent("dependencies\nsnapshot-dependencies\nresources\napplication\n");
101103
}
104+
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/classpath.idx"))) {
105+
assertThat(input).hasContent(
106+
"BOOT-INF/layers/dependencies/lib/first-library.jar\nBOOT-INF/layers/dependencies/lib/second-library.jar\nBOOT-INF/layers/snapshot-dependencies/lib/third-library-SNAPSHOT.jar\n");
107+
}
108+
}
109+
}
110+
111+
@Test
112+
void classpathIndex() throws IOException {
113+
BootJar bootJar = getTask();
114+
bootJar.setMainClassName("com.example.Main");
115+
File classesJavaMain = new File(this.temp, "classes/java/main");
116+
File applicationClass = new File(classesJavaMain, "com/example/Application.class");
117+
applicationClass.getParentFile().mkdirs();
118+
applicationClass.createNewFile();
119+
bootJar.classpath(classesJavaMain, jarFile("first-library.jar"), jarFile("second-library.jar"),
120+
jarFile("third-library-SNAPSHOT.jar"));
121+
bootJar.requiresUnpack("second-library.jar");
122+
executeTask();
123+
try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) {
124+
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
125+
.isEqualTo("BOOT-INF/classpath.idx");
126+
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/classpath.idx"))) {
127+
assertThat(input).hasContent(
128+
"BOOT-INF/lib/first-library.jar\nBOOT-INF/lib/second-library.jar\nBOOT-INF/lib/third-library-SNAPSHOT.jar\n");
129+
}
102130
}
103131
}
104132

0 commit comments

Comments
 (0)