This commit is contained in:
Phillip Webb
2024-04-04 21:31:48 -07:00
parent f7397b9557
commit 3ed77ae5f3
33 changed files with 108 additions and 246 deletions

View File

@@ -156,10 +156,8 @@ public abstract class BootJar extends Jar implements BootArchive {
@SuppressWarnings("removal")
private boolean isIncludeJarmodeTools() {
if (!this.getIncludeTools().get()) {
return false;
}
return this.layered.getIncludeLayerTools().get();
return Boolean.TRUE.equals(this.getIncludeTools().get())
&& Boolean.TRUE.equals(this.layered.getIncludeLayerTools().get());
}
@Override

View File

@@ -130,10 +130,8 @@ public abstract class BootWar extends War implements BootArchive {
@SuppressWarnings("removal")
private boolean isIncludeJarmodeTools() {
if (!this.getIncludeTools().get()) {
return false;
}
return this.layered.getIncludeLayerTools().get();
return Boolean.TRUE.equals(this.getIncludeTools().get())
&& Boolean.TRUE.equals(this.layered.getIncludeLayerTools().get());
}
@Override

View File

@@ -316,18 +316,13 @@ abstract class Command {
}
if (this.optionalValue) {
String nextArg = args.peek();
if (nextArg == null || nextArg.startsWith("--")) {
return null;
}
return (nextArg != null && !nextArg.startsWith("--")) ? args.removeFirst() : null;
}
try {
return args.removeFirst();
}
else {
try {
return args.removeFirst();
}
catch (NoSuchElementException ex) {
throw new MissingValueException(this.name);
}
catch (NoSuchElementException ex) {
throw new MissingValueException(this.name);
}
}

View File

@@ -236,10 +236,7 @@ class ExtractCommand extends Command {
}
private Layers getLayers() {
if (this.layers != null) {
return this.layers;
}
return Layers.get(this.context);
return (this.layers != null) ? this.layers : Layers.get(this.context);
}
private void createApplication(JarStructure jarStructure, FileResolver fileResolver, Map<Option, String> options)
@@ -250,7 +247,7 @@ class ExtractCommand extends Command {
}
String librariesDirectory = getLibrariesDirectory(options);
Manifest manifest = jarStructure.createLauncherManifest((library) -> librariesDirectory + library);
mkDirs(file.getParentFile());
mkdirs(file.getParentFile());
try (JarOutputStream output = new JarOutputStream(new FileOutputStream(file), manifest)) {
withJarEntries(this.context.getArchiveFile(), ((stream, jarEntry) -> {
Entry entry = jarStructure.resolve(jarEntry);
@@ -272,14 +269,11 @@ class ExtractCommand extends Command {
}
private static boolean isType(Entry entry, Type type) {
if (entry == null) {
return false;
}
return entry.type() == type;
return (entry != null) && entry.type() == type;
}
private static void extractEntry(InputStream stream, JarEntry entry, File file) throws IOException {
mkDirs(file.getParentFile());
mkdirs(file.getParentFile());
try (OutputStream out = new FileOutputStream(file)) {
StreamUtils.copy(stream, out);
}
@@ -293,27 +287,18 @@ class ExtractCommand extends Command {
}
private static FileTime getCreationTime(JarEntry entry) {
if (entry.getCreationTime() != null) {
return entry.getCreationTime();
}
return entry.getLastModifiedTime();
return (entry.getCreationTime() != null) ? entry.getCreationTime() : entry.getLastModifiedTime();
}
private static FileTime getLastAccessTime(JarEntry entry) {
if (entry.getLastAccessTime() != null) {
return entry.getLastAccessTime();
}
return getLastModifiedTime(entry);
return (entry.getLastAccessTime() != null) ? entry.getLastAccessTime() : getLastModifiedTime(entry);
}
private static FileTime getLastModifiedTime(JarEntry entry) {
if (entry.getLastModifiedTime() != null) {
return entry.getLastModifiedTime();
}
return entry.getCreationTime();
return (entry.getLastModifiedTime() != null) ? entry.getLastModifiedTime() : entry.getCreationTime();
}
private static void mkDirs(File file) throws IOException {
private static void mkdirs(File file) throws IOException {
if (!file.exists() && !file.mkdirs()) {
throw new IOException("Unable to create directory " + file);
}
@@ -461,7 +446,7 @@ class ExtractCommand extends Command {
public void createDirectories() throws IOException {
for (String layer : this.layers) {
if (shouldExtractLayer(layer)) {
mkDirs(getLayerDirectory(layer));
mkdirs(getLayerDirectory(layer));
}
}
}
@@ -492,10 +477,7 @@ class ExtractCommand extends Command {
}
private boolean shouldExtractLayer(String layer) {
if (this.layersToExtract.isEmpty()) {
return true;
}
return this.layersToExtract.contains(layer);
return this.layersToExtract.isEmpty() || this.layersToExtract.contains(layer);
}
}

View File

@@ -65,10 +65,7 @@ class IndexedJarStructure implements JarStructure {
private static String getLocation(Manifest manifest, String attribute) {
String location = getMandatoryAttribute(manifest, attribute);
if (!location.endsWith("/")) {
location = location + "/";
}
return location;
return (!location.endsWith("/")) ? location + "/" : location;
}
private static List<String> readIndexFile(String indexFile) {
@@ -78,12 +75,8 @@ class IndexedJarStructure implements JarStructure {
.toArray(String[]::new);
List<String> classpathEntries = new ArrayList<>();
for (String line : lines) {
if (line.startsWith("- ")) {
classpathEntries.add(line.substring(3, line.length() - 1));
}
else {
throw new IllegalStateException("Classpath index file is malformed");
}
Assert.state(line.startsWith("- "), "Classpath index file is malformed");
classpathEntries.add(line.substring(3, line.length() - 1));
}
Assert.state(!classpathEntries.isEmpty(), "Empty classpath index file loaded");
return classpathEntries;
@@ -99,10 +92,10 @@ class IndexedJarStructure implements JarStructure {
if (this.classpathEntries.contains(name)) {
return new Entry(name, toStructureDependency(name), Type.LIBRARY);
}
else if (name.startsWith(this.classesLocation)) {
if (name.startsWith(this.classesLocation)) {
return new Entry(name, name.substring(this.classesLocation.length()), Type.APPLICATION_CLASS_OR_RESOURCE);
}
else if (name.startsWith("org/springframework/boot/loader")) {
if (name.startsWith("org/springframework/boot/loader")) {
return new Entry(name, name, Type.LOADER);
}
return null;

View File

@@ -68,11 +68,13 @@ interface JarStructure {
* @param type of the entry
*/
record Entry(String originalLocation, String location, Type type) {
enum Type {
LIBRARY, APPLICATION_CLASS_OR_RESOURCE, LOADER
}
}
}

View File

@@ -44,9 +44,11 @@ import org.springframework.util.StringUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Base class for jar mode tests.
*
* @author Moritz Halbritter
*/
abstract class AbstractTests {
abstract class AbstractJarModeTests {
@TempDir
File tempDir;

View File

@@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*
* @author Moritz Halbritter
*/
class ExtractCommandTests extends AbstractTests {
class ExtractCommandTests extends AbstractJarModeTests {
private static final Instant CREATION_TIME = Instant.parse("2020-01-01T00:00:00Z");

View File

@@ -29,7 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Moritz Halbritter
*/
class ListLayersCommandTests extends AbstractTests {
class ListLayersCommandTests extends AbstractJarModeTests {
@Test
void shouldListLayers() throws IOException {

View File

@@ -28,7 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Moritz Halbritter
*/
class ToolsJarModeTests extends AbstractTests {
class ToolsJarModeTests extends AbstractJarModeTests {
private ToolsJarMode mode;

View File

@@ -22,7 +22,6 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -362,7 +361,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
args.add("-cp");
if (needsClasspathArgFile()) {
args.add("@" + writeClasspathArgFile(classpath.toString()));
args.add("@" + ArgFile.create(classpath).path());
}
else {
args.add(classpath.toString());
@@ -389,12 +388,6 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
return os.toLowerCase(Locale.ROOT).contains("win");
}
private Path writeClasspathArgFile(String classpath) throws IOException {
ArgFile argFile = ArgFile.create();
argFile.write(classpath);
return argFile.getPath();
}
protected URL[] getClassPathUrls() throws MojoExecutionException {
try {
List<URL> urls = new ArrayList<>();
@@ -473,30 +466,20 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
static class ArgFile {
record ArgFile(Path path) {
private final Path path;
ArgFile(Path path) {
this.path = path;
private void write(CharSequence content) throws IOException {
Files.writeString(this.path, "\"" + escape(content) + "\"");
}
void write(String content) throws IOException {
String escaped = escape(content);
Files.writeString(this.path, "\"" + escaped + "\"", StandardOpenOption.APPEND);
private String escape(CharSequence content) {
return content.toString().replace("\\", "\\\\");
}
Path getPath() {
return this.path;
}
private String escape(String content) {
return content.replace("\\", "\\\\");
}
static ArgFile create() throws IOException {
Path file = Files.createTempFile("spring-boot-", ".argfile");
return new ArgFile(file);
static ArgFile create(CharSequence content) throws IOException {
ArgFile argFile = new ArgFile(Files.createTempFile("spring-boot-", ".argfile"));
argFile.write(content);
return argFile;
}
}

View File

@@ -34,11 +34,8 @@ class AbstractRunMojoTests {
@Test
void argfileEscapesContent() throws IOException {
ArgFile file = ArgFile.create();
file.write("some \\ content");
file.write("And even more content");
assertThat(file.getPath()).content(StandardCharsets.UTF_8)
.isEqualTo("\"some \\\\ content\"\"And even more content\"");
ArgFile file = ArgFile.create("some \\ content");
assertThat(file.path()).content(StandardCharsets.UTF_8).isEqualTo("\"some \\\\ content\"");
}
}