Add support for layered jars in gradle plugin
Closes gh-19792 Co-authored-by: Andy Wilkinson <awilkinson@pivotal.io>
This commit is contained in:
@@ -178,6 +178,18 @@ class PackagingDocumentationTests {
|
||||
assertThat(bootJar).isFile();
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void bootJarLayered() throws IOException {
|
||||
this.gradleBuild.script("src/docs/gradle/packaging/boot-jar-layered").build("bootJar");
|
||||
File file = new File(this.gradleBuild.getProjectDir(),
|
||||
"build/libs/" + this.gradleBuild.getProjectDir().getName() + ".jar");
|
||||
assertThat(file).isFile();
|
||||
try (JarFile jar = new JarFile(file)) {
|
||||
JarEntry entry = jar.getJarEntry("BOOT-INF/layers.idx");
|
||||
assertThat(entry).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
protected void jarFile(File file) throws IOException {
|
||||
try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(file))) {
|
||||
jar.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* 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.
|
||||
@@ -16,6 +16,15 @@
|
||||
|
||||
package org.springframework.boot.gradle.tasks.bundling;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.gradle.testkit.runner.InvalidRunnerConfigurationException;
|
||||
import org.gradle.testkit.runner.TaskOutcome;
|
||||
import org.gradle.testkit.runner.UnexpectedBuildFailure;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link BootJar}.
|
||||
*
|
||||
@@ -27,4 +36,21 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
|
||||
super("bootJar");
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void upToDateWhenBuiltTwiceWithLayers()
|
||||
throws InvalidRunnerConfigurationException, UnexpectedBuildFailure, IOException {
|
||||
assertThat(this.gradleBuild.build("-Playered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-Playered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.UP_TO_DATE);
|
||||
}
|
||||
|
||||
@TestTemplate
|
||||
void notUpToDateWhenBuiltWithoutLayersAndThenWithLayers()
|
||||
throws InvalidRunnerConfigurationException, UnexpectedBuildFailure, IOException {
|
||||
assertThat(this.gradleBuild.build("bootJar").task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||
assertThat(this.gradleBuild.build("-Playered=true", "bootJar").task(":bootJar").getOutcome())
|
||||
.isEqualTo(TaskOutcome.SUCCESS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.boot.gradle.tasks.bundling;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -28,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link BootJar}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class BootJarTests extends AbstractBootArchiveTests<BootJar> {
|
||||
|
||||
@@ -57,6 +60,48 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void layers() throws IOException {
|
||||
BootJar bootJar = getTask();
|
||||
bootJar.setMainClassName("com.example.Main");
|
||||
bootJar.layered();
|
||||
File classesJavaMain = new File(this.temp, "classes/java/main");
|
||||
File applicationClass = new File(classesJavaMain, "com/example/Application.class");
|
||||
applicationClass.getParentFile().mkdirs();
|
||||
applicationClass.createNewFile();
|
||||
File resourcesMain = new File(this.temp, "resources/main");
|
||||
File applicationProperties = new File(resourcesMain, "application.properties");
|
||||
applicationProperties.getParentFile().mkdirs();
|
||||
applicationProperties.createNewFile();
|
||||
File staticResources = new File(resourcesMain, "static");
|
||||
staticResources.mkdir();
|
||||
File css = new File(staticResources, "test.css");
|
||||
css.createNewFile();
|
||||
bootJar.classpath(classesJavaMain, resourcesMain, jarFile("first-library.jar"), jarFile("second-library.jar"),
|
||||
jarFile("third-library-SNAPSHOT.jar"));
|
||||
bootJar.requiresUnpack("second-library.jar");
|
||||
executeTask();
|
||||
List<String> entryNames = getEntryNames(bootJar.getArchiveFile().get().getAsFile());
|
||||
assertThat(entryNames).containsSubsequence("org/springframework/boot/loader/",
|
||||
"BOOT-INF/layers/application/classes/com/example/Application.class",
|
||||
"BOOT-INF/layers/resources/classes/static/test.css",
|
||||
"BOOT-INF/layers/application/classes/application.properties",
|
||||
"BOOT-INF/layers/dependencies/lib/first-library.jar",
|
||||
"BOOT-INF/layers/dependencies/lib/second-library.jar",
|
||||
"BOOT-INF/layers/snapshot-dependencies/lib/third-library-SNAPSHOT.jar");
|
||||
assertThat(entryNames).doesNotContain("BOOT-INF/classes").doesNotContain("BOOT-INF/lib")
|
||||
.doesNotContain("BOOT-INF/com/");
|
||||
try (JarFile jarFile = new JarFile(bootJar.getArchiveFile().get().getAsFile())) {
|
||||
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classes")).isEqualTo(null);
|
||||
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(null);
|
||||
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Layers-Index"))
|
||||
.isEqualTo("BOOT-INF/layers.idx");
|
||||
try (InputStream input = jarFile.getInputStream(jarFile.getEntry("BOOT-INF/layers.idx"))) {
|
||||
assertThat(input).hasContent("dependencies\nsnapshot-dependencies\nresources\napplication\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeTask() {
|
||||
getTask().copy();
|
||||
|
||||
Reference in New Issue
Block a user