Write classpath index file from Gradle plugin

Closes gh-19847
pull/19864/head
Madhura Bhave 5 years ago
parent 2198614359
commit 13f7db2d8c

@ -20,7 +20,9 @@ import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import org.gradle.api.Action; import org.gradle.api.Action;
@ -59,7 +61,9 @@ public class BootJar extends Jar implements BootArchive {
private Layers layers; private Layers layers;
private static final String BOOT_INF_LAYERS = "BOOT-INF/layers/"; private static final String BOOT_INF_LAYERS = "BOOT-INF/layers";
private List<String> dependencies = new ArrayList<>();
/** /**
* Creates a new {@code BootJar} task. * Creates a new {@code BootJar} task.
@ -68,7 +72,10 @@ public class BootJar extends Jar implements BootArchive {
this.bootInf = getProject().copySpec().into("BOOT-INF"); this.bootInf = getProject().copySpec().into("BOOT-INF");
getMainSpec().with(this.bootInf); getMainSpec().with(this.bootInf);
this.bootInf.into("classes", classpathFiles(File::isDirectory)); this.bootInf.into("classes", classpathFiles(File::isDirectory));
this.bootInf.into("lib", classpathFiles(File::isFile)); this.bootInf.into("lib", classpathFiles(File::isFile))
.eachFile((details) -> BootJar.this.dependencies.add(details.getPath()));
this.bootInf.into("",
(spec) -> spec.from((Callable<File>) () -> createClasspathIndex(BootJar.this.dependencies)));
this.bootInf.filesMatching("module-info.class", this.bootInf.filesMatching("module-info.class",
(details) -> details.setRelativePath(details.getRelativeSourcePath())); (details) -> details.setRelativePath(details.getRelativeSourcePath()));
getRootSpec().eachFile((details) -> { getRootSpec().eachFile((details) -> {
@ -93,9 +100,29 @@ public class BootJar extends Jar implements BootArchive {
attributes.remove("Spring-Boot-Lib"); attributes.remove("Spring-Boot-Lib");
attributes.putIfAbsent("Spring-Boot-Layers-Index", "BOOT-INF/layers.idx"); attributes.putIfAbsent("Spring-Boot-Layers-Index", "BOOT-INF/layers.idx");
} }
attributes.putIfAbsent("Spring-Boot-Classpath-Index", "BOOT-INF/classpath.idx");
super.copy(); super.copy();
} }
private File createClasspathIndex(List<String> dependencies) {
try {
StringWriter content = new StringWriter();
BufferedWriter writer = new BufferedWriter(content);
for (String dependency : dependencies) {
writer.write(dependency);
writer.write("\n");
}
writer.flush();
File source = getProject().getResources().getText().fromString(content.toString()).asFile();
File indexFile = new File(source.getParentFile(), "classpath.idx");
source.renameTo(indexFile);
return indexFile;
}
catch (IOException ex) {
throw new RuntimeException("Failed to create classpath.idx", ex);
}
}
@Override @Override
protected CopyAction createCopyAction() { protected CopyAction createCopyAction() {
return this.support.createCopyAction(this); return this.support.createCopyAction(this);

@ -96,9 +96,37 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(null); assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(null);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Layers-Index")) assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Layers-Index"))
.isEqualTo("BOOT-INF/layers.idx"); .isEqualTo("BOOT-INF/layers.idx");
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
.isEqualTo("BOOT-INF/classpath.idx");
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/layers.idx"))) { try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/layers.idx"))) {
assertThat(input).hasContent("dependencies\nsnapshot-dependencies\nresources\napplication\n"); assertThat(input).hasContent("dependencies\nsnapshot-dependencies\nresources\napplication\n");
} }
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/classpath.idx"))) {
assertThat(input).hasContent(
"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");
}
}
}
@Test
void classpathIndex() throws IOException {
BootJar bootJar = getTask();
bootJar.setMainClassName("com.example.Main");
File classesJavaMain = new File(this.temp, "classes/java/main");
File applicationClass = new File(classesJavaMain, "com/example/Application.class");
applicationClass.getParentFile().mkdirs();
applicationClass.createNewFile();
bootJar.classpath(classesJavaMain, jarFile("first-library.jar"), jarFile("second-library.jar"),
jarFile("third-library-SNAPSHOT.jar"));
bootJar.requiresUnpack("second-library.jar");
executeTask();
try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
.isEqualTo("BOOT-INF/classpath.idx");
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/classpath.idx"))) {
assertThat(input).hasContent(
"BOOT-INF/lib/first-library.jar\nBOOT-INF/lib/second-library.jar\nBOOT-INF/lib/third-library-SNAPSHOT.jar\n");
}
} }
} }

Loading…
Cancel
Save