Add support for creating layered war files with Maven
See gh-22821
This commit is contained in:
@@ -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.
|
||||
@@ -50,20 +50,12 @@ class ContextTests {
|
||||
.withMessage("Unable to find source JAR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenSourceIsNotJarThrowsException() throws Exception {
|
||||
File zip = new File(this.temp, "test.zip");
|
||||
Files.createFile(zip.toPath());
|
||||
assertThatIllegalStateException().isThrownBy(() -> new Context(zip, this.temp))
|
||||
.withMessage("Unable to find source JAR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getJarFileReturnsJar() throws Exception {
|
||||
File jar = new File(this.temp, "test.jar");
|
||||
Files.createFile(jar.toPath());
|
||||
Context context = new Context(jar, this.temp);
|
||||
assertThat(context.getJarFile()).isEqualTo(jar);
|
||||
assertThat(context.getArchiveFile()).isEqualTo(jar);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -82,7 +74,7 @@ class ContextTests {
|
||||
File jar = new File(target, "test.jar");
|
||||
Files.createFile(jar.toPath());
|
||||
Context context = new Context(jar, this.temp);
|
||||
assertThat(context.getRelativeJarDir()).isEqualTo("target");
|
||||
assertThat(context.getRelativeArchiveDir()).isEqualTo("target");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,7 +82,7 @@ class ContextTests {
|
||||
File jar = new File(this.temp, "test.jar");
|
||||
Files.createFile(jar.toPath());
|
||||
Context context = new Context(jar, this.temp);
|
||||
assertThat(context.getRelativeJarDir()).isNull();
|
||||
assertThat(context.getRelativeArchiveDir()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,7 +94,7 @@ class ContextTests {
|
||||
File jar = new File(directory1, "test.jar");
|
||||
Files.createFile(jar.toPath());
|
||||
Context context = new Context(jar, directory2);
|
||||
assertThat(context.getRelativeJarDir()).isNull();
|
||||
assertThat(context.getRelativeArchiveDir()).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -69,7 +69,7 @@ class ExtractCommandTests {
|
||||
|
||||
@Test
|
||||
void runExtractsLayers() throws Exception {
|
||||
given(this.context.getJarFile()).willReturn(this.jarFile);
|
||||
given(this.context.getArchiveFile()).willReturn(this.jarFile);
|
||||
given(this.context.getWorkingDir()).willReturn(this.extract);
|
||||
this.command.run(Collections.emptyMap(), Collections.emptyList());
|
||||
assertThat(this.extract.list()).containsOnly("a", "b", "c", "d");
|
||||
@@ -81,7 +81,7 @@ class ExtractCommandTests {
|
||||
|
||||
@Test
|
||||
void runWhenHasDestinationOptionExtractsLayers() {
|
||||
given(this.context.getJarFile()).willReturn(this.jarFile);
|
||||
given(this.context.getArchiveFile()).willReturn(this.jarFile);
|
||||
File out = new File(this.extract, "out");
|
||||
this.command.run(Collections.singletonMap(ExtractCommand.DESTINATION_OPTION, out.getAbsolutePath()),
|
||||
Collections.emptyList());
|
||||
@@ -93,7 +93,7 @@ class ExtractCommandTests {
|
||||
|
||||
@Test
|
||||
void runWhenHasLayerParamsExtractsLimitedLayers() {
|
||||
given(this.context.getJarFile()).willReturn(this.jarFile);
|
||||
given(this.context.getArchiveFile()).willReturn(this.jarFile);
|
||||
given(this.context.getWorkingDir()).willReturn(this.extract);
|
||||
this.command.run(Collections.emptyMap(), Arrays.asList("a", "c"));
|
||||
assertThat(this.extract.list()).containsOnly("a", "c");
|
||||
@@ -107,7 +107,7 @@ class ExtractCommandTests {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
writer.write("text");
|
||||
}
|
||||
given(this.context.getJarFile()).willReturn(file);
|
||||
given(this.context.getArchiveFile()).willReturn(file);
|
||||
given(this.context.getWorkingDir()).willReturn(this.extract);
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.command.run(Collections.emptyMap(), Collections.emptyList()))
|
||||
|
||||
@@ -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.
|
||||
@@ -52,7 +52,7 @@ class HelpCommandTests {
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
Context context = mock(Context.class);
|
||||
given(context.getJarFile()).willReturn(createJarFile("test.jar"));
|
||||
given(context.getArchiveFile()).willReturn(createJarFile("test.jar"));
|
||||
this.command = new HelpCommand(context, LayerToolsJarMode.Runner.getCommands(context));
|
||||
this.out = new TestPrintStream(this);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.springframework.boot.jarmode.layertools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
@@ -37,6 +41,9 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
class IndexedLayersTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
@Test
|
||||
void createWhenIndexFileIsEmptyThrowsException() {
|
||||
assertThatIllegalStateException().isThrownBy(() -> new IndexedLayers(" \n "))
|
||||
@@ -82,8 +89,20 @@ class IndexedLayersTests {
|
||||
assertThat(layers.getLayer(mockEntry("a b/c d"))).isEqualTo("application");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getShouldReturnIndexedLayersFromContext() throws Exception {
|
||||
Context context = mock(Context.class);
|
||||
given(context.getArchiveFile()).willReturn(createWarFile("test.war"));
|
||||
IndexedLayers layers = IndexedLayers.get(context);
|
||||
assertThat(layers.getLayer(mockEntry("WEB-INF/lib/a.jar"))).isEqualTo("test");
|
||||
}
|
||||
|
||||
private String getIndex() throws Exception {
|
||||
ClassPathResource resource = new ClassPathResource("test-layers.idx", getClass());
|
||||
return getIndex("test-layers.idx");
|
||||
}
|
||||
|
||||
private String getIndex(String fileName) throws Exception {
|
||||
ClassPathResource resource = new ClassPathResource(fileName, getClass());
|
||||
InputStreamReader reader = new InputStreamReader(resource.getInputStream());
|
||||
return FileCopyUtils.copyToString(reader);
|
||||
}
|
||||
@@ -94,4 +113,23 @@ class IndexedLayersTests {
|
||||
return entry;
|
||||
}
|
||||
|
||||
private File createWarFile(String name) throws Exception {
|
||||
File file = new File(this.temp, name);
|
||||
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file))) {
|
||||
out.putNextEntry(new ZipEntry("WEB-INF/lib/a/"));
|
||||
out.closeEntry();
|
||||
out.putNextEntry(new ZipEntry("WEB-INF/lib/a/a.jar"));
|
||||
out.closeEntry();
|
||||
out.putNextEntry(new ZipEntry("WEB-INF/classes/Demo.class"));
|
||||
out.closeEntry();
|
||||
out.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
|
||||
out.write(getIndex("test-manifest.MF").getBytes());
|
||||
out.closeEntry();
|
||||
out.putNextEntry(new ZipEntry("WEB-INF/layers.idx"));
|
||||
out.write(getIndex("test-war-layers.idx").getBytes());
|
||||
out.closeEntry();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -55,7 +55,7 @@ class LayerToolsJarModeTests {
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
Context context = mock(Context.class);
|
||||
given(context.getJarFile()).willReturn(createJarFile("test.jar"));
|
||||
given(context.getArchiveFile()).willReturn(createJarFile("test.jar"));
|
||||
this.out = new TestPrintStream(this);
|
||||
this.systemOut = System.out;
|
||||
System.setOut(this.out);
|
||||
|
||||
@@ -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.
|
||||
@@ -60,7 +60,7 @@ class ListCommandTests {
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.jarFile = createJarFile("test.jar");
|
||||
given(this.context.getJarFile()).willReturn(this.jarFile);
|
||||
given(this.context.getArchiveFile()).willReturn(this.jarFile);
|
||||
this.command = new ListCommand(this.context);
|
||||
this.out = new TestPrintStream(this);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Manifest-Version: 1.0
|
||||
Created-By: Maven WAR Plugin 3.3.1
|
||||
Build-Jdk-Spec: 11
|
||||
Implementation-Title: demo
|
||||
Implementation-Version: 0.0.1-SNAPSHOT
|
||||
Main-Class: org.springframework.boot.loader.WarLauncher
|
||||
Start-Class: com.example.DemoApplication
|
||||
Spring-Boot-Version: 2.5.0-SNAPSHOT
|
||||
Spring-Boot-Classes: WEB-INF/classes/
|
||||
Spring-Boot-Lib: WEB-INF/lib/
|
||||
Spring-Boot-Classpath-Index: WEB-INF/classpath.idx
|
||||
Spring-Boot-Layers-Index: WEB-INF/layers.idx
|
||||
@@ -0,0 +1,6 @@
|
||||
- "test":
|
||||
- "WEB-INF/lib/a.jar"
|
||||
- "WEB-INF/lib/b.jar"
|
||||
- "empty":
|
||||
- "application":
|
||||
- "WEB-INF/classes/Demo.class"
|
||||
Reference in New Issue
Block a user