Skip to content

Commit d1d35d0

Browse files
committed
Add nullability annotations to loader/spring-boot-jarmode-tools
See gh-46587
1 parent f00dc97 commit d1d35d0

File tree

11 files changed

+57
-38
lines changed

11 files changed

+57
-38
lines changed

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/Command.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import java.util.NoSuchElementException;
2929
import java.util.stream.Stream;
3030

31+
import org.jspecify.annotations.Nullable;
32+
3133
/**
3234
* A command that can be launched.
3335
*
@@ -132,7 +134,7 @@ boolean isDeprecated() {
132134
* Returns the deprecation message.
133135
* @return the deprecation message
134136
*/
135-
String getDeprecationMessage() {
137+
@Nullable String getDeprecationMessage() {
136138
return null;
137139
}
138140

@@ -142,7 +144,7 @@ String getDeprecationMessage() {
142144
* @param name the name of the command to find
143145
* @return a {@link Command} instance or {@code null}.
144146
*/
145-
static Command find(Collection<? extends Command> commands, String name) {
147+
static @Nullable Command find(Collection<? extends Command> commands, String name) {
146148
for (Command command : commands) {
147149
if (command.getName().equals(name)) {
148150
return command;
@@ -206,7 +208,7 @@ private Options(Option[] values) {
206208
this.values = values;
207209
}
208210

209-
private Option find(String arg) {
211+
private @Nullable Option find(String arg) {
210212
if (arg.startsWith("--")) {
211213
String name = arg.substring(2);
212214
for (Option candidate : this.values) {
@@ -264,13 +266,13 @@ static final class Option {
264266

265267
private final String name;
266268

267-
private final String valueDescription;
269+
private final @Nullable String valueDescription;
268270

269271
private final String description;
270272

271273
private final boolean optionalValue;
272274

273-
private Option(String name, String valueDescription, String description, boolean optionalValue) {
275+
private Option(String name, @Nullable String valueDescription, String description, boolean optionalValue) {
274276
this.name = name;
275277
this.description = description;
276278
this.valueDescription = valueDescription;
@@ -290,7 +292,7 @@ String getName() {
290292
* option is a flag/switch.
291293
* @return the option value description
292294
*/
293-
String getValueDescription() {
295+
@Nullable String getValueDescription() {
294296
return this.valueDescription;
295297
}
296298

@@ -310,7 +312,7 @@ String getDescription() {
310312
return this.description;
311313
}
312314

313-
private String claimArg(Deque<String> args) {
315+
private @Nullable String claimArg(Deque<String> args) {
314316
if (this.valueDescription == null) {
315317
return null;
316318
}

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/Context.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import java.util.Locale;
2929
import java.util.jar.JarFile;
3030

31+
import org.jspecify.annotations.Nullable;
32+
3133
import org.springframework.util.Assert;
3234

3335
/**
@@ -41,7 +43,7 @@ class Context {
4143

4244
private final File workingDir;
4345

44-
private final String relativeDir;
46+
private final @Nullable String relativeDir;
4547

4648
/**
4749
* Create a new {@link Context} instance.
@@ -63,7 +65,7 @@ class Context {
6365
this.relativeDir = deduceRelativeDir(archiveFile.getParentFile(), this.workingDir);
6466
}
6567

66-
private boolean isExistingFile(File archiveFile) {
68+
private boolean isExistingFile(@Nullable File archiveFile) {
6769
return archiveFile != null && archiveFile.isFile() && archiveFile.exists();
6870
}
6971

@@ -81,10 +83,10 @@ private static File getSourceArchiveFile() {
8183
if (source != null && source.exists()) {
8284
return source.getAbsoluteFile();
8385
}
84-
return null;
86+
throw new IllegalStateException("Unable to find source archive");
8587
}
8688
catch (Exception ex) {
87-
return null;
89+
throw new IllegalStateException("Unable to find source archive", ex);
8890
}
8991
}
9092

@@ -105,7 +107,7 @@ private static File getRootJarFile(JarFile jarFile) {
105107
return new File(name);
106108
}
107109

108-
private String deduceRelativeDir(File sourceDirectory, File workingDir) {
110+
private @Nullable String deduceRelativeDir(File sourceDirectory, File workingDir) {
109111
String sourcePath = sourceDirectory.getAbsolutePath();
110112
String workingPath = workingDir.getAbsolutePath();
111113
if (sourcePath.equals(workingPath) || !sourcePath.startsWith(workingPath)) {
@@ -136,7 +138,7 @@ File getWorkingDir() {
136138
* or {@code null} if none relative directory can be deduced.
137139
* @return the relative dir ending in {@code /} or {@code null}
138140
*/
139-
String getRelativeArchiveDir() {
141+
@Nullable String getRelativeArchiveDir() {
140142
return this.relativeDir;
141143
}
142144

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractCommand.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import java.util.zip.ZipEntry;
4242
import java.util.zip.ZipInputStream;
4343

44+
import org.jspecify.annotations.Nullable;
45+
4446
import org.springframework.boot.jarmode.tools.JarStructure.Entry;
4547
import org.springframework.boot.jarmode.tools.JarStructure.Entry.Type;
4648
import org.springframework.boot.loader.jarmode.JarModeErrorException;
@@ -84,13 +86,13 @@ class ExtractCommand extends Command {
8486

8587
private final Context context;
8688

87-
private final Layers layers;
89+
private final @Nullable Layers layers;
8890

8991
ExtractCommand(Context context) {
9092
this(context, null);
9193
}
9294

93-
ExtractCommand(Context context, Layers layers) {
95+
ExtractCommand(Context context, @Nullable Layers layers) {
9496
super("extract", "Extract the contents from the jar", Options.of(LAUNCHER_OPTION, LAYERS_OPTION,
9597
DESTINATION_OPTION, LIBRARIES_DIRECTORY_OPTION, APPLICATION_FILENAME_OPTION, FORCE_OPTION),
9698
Parameters.none());
@@ -153,7 +155,7 @@ private void extractLibraries(FileResolver fileResolver, JarStructure jarStructu
153155
String librariesDirectory = getLibrariesDirectory(options);
154156
extractArchive(fileResolver, (jarEntry) -> {
155157
Entry entry = jarStructure.resolve(jarEntry);
156-
if (isType(entry, Type.LIBRARY)) {
158+
if (entry != null && entry.type() == Type.LIBRARY) {
157159
return librariesDirectory + entry.location();
158160
}
159161
return null;
@@ -269,10 +271,6 @@ private String getApplicationFilename(Map<Option, String> options) {
269271
return this.context.getArchiveFile().getName();
270272
}
271273

272-
private static boolean isType(Entry entry, Type type) {
273-
return (entry != null) && entry.type() == type;
274-
}
275-
276274
private static void extractEntry(InputStream stream, JarEntry entry, File file) throws IOException {
277275
mkdirs(file.getParentFile());
278276
try (OutputStream out = new FileOutputStream(file)) {
@@ -287,15 +285,15 @@ private static void extractEntry(InputStream stream, JarEntry entry, File file)
287285
}
288286
}
289287

290-
private static FileTime getCreationTime(JarEntry entry) {
288+
private static @Nullable FileTime getCreationTime(JarEntry entry) {
291289
return (entry.getCreationTime() != null) ? entry.getCreationTime() : entry.getLastModifiedTime();
292290
}
293291

294-
private static FileTime getLastAccessTime(JarEntry entry) {
292+
private static @Nullable FileTime getLastAccessTime(JarEntry entry) {
295293
return (entry.getLastAccessTime() != null) ? entry.getLastAccessTime() : getLastModifiedTime(entry);
296294
}
297295

298-
private static FileTime getLastModifiedTime(JarEntry entry) {
296+
private static @Nullable FileTime getLastModifiedTime(JarEntry entry) {
299297
return (entry.getLastModifiedTime() != null) ? entry.getLastModifiedTime() : entry.getCreationTime();
300298
}
301299

@@ -348,7 +346,7 @@ private static File assertFileIsContainedInDirectory(File directory, File file,
348346
@FunctionalInterface
349347
private interface EntryNameTransformer {
350348

351-
String getName(JarEntry entry);
349+
@Nullable String getName(JarEntry entry);
352350

353351
}
354352

@@ -375,7 +373,7 @@ private interface FileResolver {
375373
* should be skipped
376374
* @throws IOException if something went wrong
377375
*/
378-
default File resolve(JarEntry entry, String newName) throws IOException {
376+
default @Nullable File resolve(JarEntry entry, String newName) throws IOException {
379377
return resolve(entry.getName(), newName);
380378
}
381379

@@ -387,15 +385,15 @@ default File resolve(JarEntry entry, String newName) throws IOException {
387385
* should be skipped
388386
* @throws IOException if something went wrong
389387
*/
390-
File resolve(String originalName, String newName) throws IOException;
388+
@Nullable File resolve(String originalName, String newName) throws IOException;
391389

392390
/**
393391
* Resolves the file for the application.
394392
* @return the file for the application or {@code null} if the application should
395393
* be skipped
396394
* @throws IOException if something went wrong
397395
*/
398-
File resolveApplication() throws IOException;
396+
@Nullable File resolveApplication() throws IOException;
399397

400398
}
401399

@@ -453,7 +451,7 @@ public void createDirectories() throws IOException {
453451
}
454452

455453
@Override
456-
public File resolve(String originalName, String newName) throws IOException {
454+
public @Nullable File resolve(String originalName, String newName) throws IOException {
457455
String layer = this.layers.getLayer(originalName);
458456
if (shouldExtractLayer(layer)) {
459457
File directory = getLayerDirectory(layer);
@@ -463,7 +461,7 @@ public File resolve(String originalName, String newName) throws IOException {
463461
}
464462

465463
@Override
466-
public File resolveApplication() throws IOException {
464+
public @Nullable File resolveApplication() throws IOException {
467465
String layer = this.layers.getApplicationLayerName();
468466
if (shouldExtractLayer(layer)) {
469467
File directory = getLayerDirectory(layer);

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ExtractLayersCommand.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.List;
2323
import java.util.Map;
2424

25+
import org.jspecify.annotations.Nullable;
26+
2527
import org.springframework.util.StringUtils;
2628

2729
/**
@@ -39,7 +41,7 @@ class ExtractLayersCommand extends Command {
3941
this(context, null);
4042
}
4143

42-
ExtractLayersCommand(Context context, Layers layers) {
44+
ExtractLayersCommand(Context context, @Nullable Layers layers) {
4345
super("extract", "Extracts layers from the jar for image creation", Options.of(DESTINATION_OPTION),
4446
Parameters.of("[<layer>...]"));
4547
this.delegate = new ExtractCommand(context, layers);

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/HelpCommand.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.Map;
2222
import java.util.stream.Stream;
2323

24+
import org.jspecify.annotations.Nullable;
25+
2426
/**
2527
* Implicit {@code 'help'} command.
2628
*
@@ -39,7 +41,7 @@ class HelpCommand extends Command {
3941
this(context, commands, System.getProperty("jarmode"));
4042
}
4143

42-
HelpCommand(Context context, List<Command> commands, String jarMode) {
44+
HelpCommand(Context context, List<Command> commands, @Nullable String jarMode) {
4345
super("help", "Help about any command", Options.none(), Parameters.of("[<command>]"));
4446
this.context = context;
4547
this.commands = commands;

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/IndexedJarStructure.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.util.stream.Collectors;
3434
import java.util.zip.ZipEntry;
3535

36+
import org.jspecify.annotations.Nullable;
37+
3638
import org.springframework.boot.jarmode.tools.JarStructure.Entry.Type;
3739
import org.springframework.util.Assert;
3840
import org.springframework.util.StreamUtils;
@@ -92,7 +94,7 @@ public String getClassesLocation() {
9294
}
9395

9496
@Override
95-
public Entry resolve(String name) {
97+
public @Nullable Entry resolve(String name) {
9698
if (ENTRY_IGNORE_LIST.contains(name)) {
9799
return null;
98100
}
@@ -138,7 +140,7 @@ private static String getMandatoryAttribute(Manifest manifest, String attribute)
138140
return value;
139141
}
140142

141-
static IndexedJarStructure get(File file) {
143+
static @Nullable IndexedJarStructure get(File file) {
142144
try {
143145
try (JarFile jarFile = new JarFile(file)) {
144146
Manifest manifest = jarFile.getManifest();

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/IndexedLayers.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.util.jar.Manifest;
3131
import java.util.zip.ZipEntry;
3232

33+
import org.jspecify.annotations.Nullable;
34+
3335
import org.springframework.util.Assert;
3436
import org.springframework.util.StreamUtils;
3537
import org.springframework.util.StringUtils;
@@ -98,7 +100,7 @@ public String getLayer(String name) {
98100
* @return an {@link IndexedLayers} instance or {@code null} if this not a layered
99101
* jar.
100102
*/
101-
static IndexedLayers get(Context context) {
103+
static @Nullable IndexedLayers get(Context context) {
102104
try (JarFile jarFile = new JarFile(context.getArchiveFile())) {
103105
Manifest manifest = jarFile.getManifest();
104106
if (manifest == null) {

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/JarStructure.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.util.jar.Manifest;
2121
import java.util.zip.ZipEntry;
2222

23+
import org.jspecify.annotations.Nullable;
24+
2325
/**
2426
* Provide information about a fat jar structure that is meant to be extracted.
2527
*
@@ -34,7 +36,7 @@ interface JarStructure {
3436
* @param entry the entry to handle
3537
* @return the resolved {@link Entry}
3638
*/
37-
default Entry resolve(ZipEntry entry) {
39+
default @Nullable Entry resolve(ZipEntry entry) {
3840
return resolve(entry.getName());
3941
}
4042

@@ -44,7 +46,7 @@ default Entry resolve(ZipEntry entry) {
4446
* @param name the name of the entry to handle
4547
* @return the resolved {@link Entry}
4648
*/
47-
Entry resolve(String name);
49+
@Nullable Entry resolve(String name);
4850

4951
/**
5052
* Create the {@link Manifest} for the launcher jar, applying the specified operator

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/LayerToolsJarMode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.List;
2020

21+
import org.jspecify.annotations.Nullable;
22+
2123
import org.springframework.boot.loader.jarmode.JarMode;
2224

2325
/**
@@ -29,7 +31,7 @@
2931
*/
3032
public class LayerToolsJarMode implements JarMode {
3133

32-
static Context contextOverride;
34+
static @Nullable Context contextOverride;
3335

3436
@Override
3537
public boolean accepts(String mode) {

loader/spring-boot-jarmode-tools/src/main/java/org/springframework/boot/jarmode/tools/ToolsJarMode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.io.PrintStream;
2020
import java.util.List;
2121

22+
import org.jspecify.annotations.Nullable;
23+
2224
import org.springframework.boot.loader.jarmode.JarMode;
2325

2426
/**
@@ -37,7 +39,7 @@ public ToolsJarMode() {
3739
this(null, null);
3840
}
3941

40-
public ToolsJarMode(Context context, PrintStream out) {
42+
public ToolsJarMode(@Nullable Context context, @Nullable PrintStream out) {
4143
this.context = (context != null) ? context : new Context();
4244
this.out = (out != null) ? out : System.out;
4345
}

0 commit comments

Comments
 (0)