From f5be18587c5bc8177a3e34c3bc2fda3f2ae7ef12 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Mon, 18 Aug 2025 14:36:10 +0200 Subject: [PATCH] Improve null-safety of loader/spring-boot-jarmode-tools See gh-46926 --- .../boot/jarmode/tools/Command.java | 4 +- .../boot/jarmode/tools/ExtractCommand.java | 40 ++++++++++--------- .../jarmode/tools/ExtractLayersCommand.java | 4 +- .../boot/jarmode/tools/HelpCommand.java | 2 +- .../boot/jarmode/tools/ListCommand.java | 4 +- .../boot/jarmode/tools/ListLayersCommand.java | 4 +- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/Command.java b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/Command.java index b2239546c6d..f43be0db89b 100644 --- a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/Command.java +++ b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/Command.java @@ -100,7 +100,7 @@ abstract class Command { */ final void run(PrintStream out, Deque args) { List parameters = new ArrayList<>(); - Map options = new HashMap<>(); + Map options = new HashMap<>(); while (!args.isEmpty()) { String arg = args.removeFirst(); Option option = this.options.find(arg); @@ -120,7 +120,7 @@ abstract class Command { * @param options any options extracted from the arguments * @param parameters any parameters extracted from the arguments */ - abstract void run(PrintStream out, Map options, List parameters); + abstract void run(PrintStream out, Map options, List parameters); /** * Whether the command is deprecated. diff --git a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java index 667527752a1..13be219157a 100644 --- a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java +++ b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java @@ -101,7 +101,7 @@ class ExtractCommand extends Command { } @Override - void run(PrintStream out, Map options, List parameters) { + void run(PrintStream out, Map options, List parameters) { try { checkJarCompatibility(); File destination = getDestination(options); @@ -122,7 +122,7 @@ class ExtractCommand extends Command { } } - private static void checkDirectoryIsEmpty(Map options, File destination) { + private static void checkDirectoryIsEmpty(Map options, File destination) { if (options.containsKey(FORCE_OPTION)) { return; } @@ -150,8 +150,8 @@ class ExtractCommand extends Command { } } - private void extractLibraries(FileResolver fileResolver, JarStructure jarStructure, Map options) - throws IOException { + private void extractLibraries(FileResolver fileResolver, JarStructure jarStructure, + Map options) throws IOException { String librariesDirectory = getLibrariesDirectory(options); extractArchive(fileResolver, (jarEntry) -> { Entry entry = jarStructure.resolve(jarEntry); @@ -162,18 +162,18 @@ class ExtractCommand extends Command { }); } - private static String getLibrariesDirectory(Map options) { - if (options.containsKey(LIBRARIES_DIRECTORY_OPTION)) { - String value = options.get(LIBRARIES_DIRECTORY_OPTION); - if (value.endsWith("/")) { - return value; + private static String getLibrariesDirectory(Map options) { + String libraryDirectory = options.get(LIBRARIES_DIRECTORY_OPTION); + if (libraryDirectory != null) { + if (libraryDirectory.endsWith("/")) { + return libraryDirectory; } - return value + "/"; + return libraryDirectory + "/"; } return "lib/"; } - private FileResolver getFileResolver(File destination, Map options) { + private FileResolver getFileResolver(File destination, Map options) { String applicationFilename = getApplicationFilename(options); if (!options.containsKey(LAYERS_OPTION)) { return new NoLayersFileResolver(destination, applicationFilename); @@ -183,9 +183,10 @@ class ExtractCommand extends Command { return new LayersFileResolver(destination, layers, layersToExtract, applicationFilename); } - private File getDestination(Map options) { - if (options.containsKey(DESTINATION_OPTION)) { - File destination = new File(options.get(DESTINATION_OPTION)); + private File getDestination(Map options) { + String value = options.get(DESTINATION_OPTION); + if (value != null) { + File destination = new File(value); if (destination.isAbsolute()) { return destination; } @@ -232,8 +233,8 @@ class ExtractCommand extends Command { return (this.layers != null) ? this.layers : Layers.get(this.context); } - private void createApplication(JarStructure jarStructure, FileResolver fileResolver, Map options) - throws IOException { + private void createApplication(JarStructure jarStructure, FileResolver fileResolver, + Map options) throws IOException { File file = fileResolver.resolveApplication(); if (file == null) { return; @@ -264,9 +265,10 @@ class ExtractCommand extends Command { } } - private String getApplicationFilename(Map options) { - if (options.containsKey(APPLICATION_FILENAME_OPTION)) { - return options.get(APPLICATION_FILENAME_OPTION); + private String getApplicationFilename(Map options) { + String value = options.get(APPLICATION_FILENAME_OPTION); + if (value != null) { + return value; } return this.context.getArchiveFile().getName(); } diff --git a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractLayersCommand.java b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractLayersCommand.java index eca850c61be..d598f1561b8 100644 --- a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractLayersCommand.java +++ b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractLayersCommand.java @@ -58,8 +58,8 @@ class ExtractLayersCommand extends Command { } @Override - void run(PrintStream out, Map options, List parameters) { - Map rewrittenOptions = new HashMap<>(); + void run(PrintStream out, Map options, List parameters) { + Map rewrittenOptions = new HashMap<>(); rewrittenOptions.put(ExtractCommand.DESTINATION_OPTION, options.getOrDefault(DESTINATION_OPTION, ".")); rewrittenOptions.put(ExtractCommand.LAYERS_OPTION, StringUtils.collectionToCommaDelimitedString(parameters)); rewrittenOptions.put(ExtractCommand.LAUNCHER_OPTION, null); diff --git a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/HelpCommand.java b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/HelpCommand.java index f4a5b4947d7..07f7224e04d 100644 --- a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/HelpCommand.java +++ b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/HelpCommand.java @@ -49,7 +49,7 @@ class HelpCommand extends Command { } @Override - void run(PrintStream out, Map options, List parameters) { + void run(PrintStream out, Map options, List parameters) { run(out, parameters); } diff --git a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListCommand.java b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListCommand.java index 60d26edcbce..366bb62ea06 100644 --- a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListCommand.java +++ b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListCommand.java @@ -20,6 +20,8 @@ import java.io.PrintStream; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; + /** * The {@code 'list'} tools command. * @@ -48,7 +50,7 @@ class ListCommand extends Command { } @Override - void run(PrintStream out, Map options, List parameters) { + void run(PrintStream out, Map options, List parameters) { this.delegate.run(out, options, parameters); } diff --git a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListLayersCommand.java b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListLayersCommand.java index 17ca1eea2e0..9c57d57010c 100644 --- a/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListLayersCommand.java +++ b/loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ListLayersCommand.java @@ -20,6 +20,8 @@ import java.io.PrintStream; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; + /** * The {@code 'list-layers'} tools command. * @@ -35,7 +37,7 @@ class ListLayersCommand extends Command { } @Override - void run(PrintStream out, Map options, List parameters) { + void run(PrintStream out, Map options, List parameters) { Layers layers = Layers.get(this.context); printLayers(out, layers); }