Browse Source

Add nullability annotations to loader/spring-boot-loader-tools

See gh-46587
pull/46780/head
Moritz Halbritter 9 months ago
parent
commit
8d853fae86
  1. 8
      documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/buildtoolplugins/otherbuildsystems/examplerepackageimplementation/MyBuildTool.kt
  2. 31
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java
  3. 34
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java
  4. 8
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/DefaultLaunchScript.java
  5. 9
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/FileUtils.java
  6. 13
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ImagePackager.java
  7. 4
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JarModeLibrary.java
  8. 9
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JarWriter.java
  9. 4
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layer.java
  10. 10
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layout.java
  11. 16
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layouts.java
  12. 28
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Library.java
  13. 4
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/LibraryCoordinates.java
  14. 44
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/MainClassFinder.java
  15. 44
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java
  16. 13
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java
  17. 10
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java
  18. 11
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/SizeCalculatingEntryWriter.java
  19. 4
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ZipHeaderPeekInputStream.java
  20. 4
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/layer/IncludeExcludeContentSelector.java
  21. 4
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/layer/package-info.java
  22. 3
      loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/package-info.java

8
documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/buildtoolplugins/otherbuildsystems/examplerepackageimplementation/MyBuildTool.kt

@ -27,7 +27,7 @@ class MyBuildTool { @@ -27,7 +27,7 @@ class MyBuildTool {
@Throws(IOException::class)
fun build() {
val sourceJarFile: File? = /**/null
val sourceJarFile: File = /**/File(".")
val repackager = Repackager(sourceJarFile)
repackager.setBackupSource(false)
repackager.repackage { callback: LibraryCallback -> getLibraries(callback) }
@ -36,14 +36,14 @@ class MyBuildTool { @@ -36,14 +36,14 @@ class MyBuildTool {
@Throws(IOException::class)
private fun getLibraries(callback: LibraryCallback) {
// Build system specific implementation, callback for each dependency
for (nestedJar in getCompileScopeJars()!!) {
for (nestedJar in getCompileScopeJars()) {
callback.library(Library(nestedJar, LibraryScope.COMPILE))
}
// ...
}
private fun getCompileScopeJars(): List<File?>? {
return /**/ null
private fun getCompileScopeJars(): List<File> {
return /**/ listOf()
}
}

31
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/AbstractJarWriter.java

@ -42,6 +42,9 @@ import java.util.zip.ZipEntry; @@ -42,6 +42,9 @@ import java.util.zip.ZipEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.zip.UnixStat;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
* Abstract base class for JAR writers.
@ -61,16 +64,16 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -61,16 +64,16 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
private final Set<String> writtenEntries = new HashSet<>();
private Layers layers;
private @Nullable Layers layers;
private LayersIndex layersIndex;
private @Nullable LayersIndex layersIndex;
/**
* Update this writer to use specific layers.
* @param layers the layers to use
* @param layersIndex the layers index to update
*/
void useLayers(Layers layers, LayersIndex layersIndex) {
void useLayers(@Nullable Layers layers, @Nullable LayersIndex layersIndex) {
this.layers = layers;
this.layersIndex = layersIndex;
}
@ -86,7 +89,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -86,7 +89,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
}
final void writeEntries(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler,
Function<JarEntry, Library> libraryLookup) throws IOException {
Function<JarEntry, @Nullable Library> libraryLookup) throws IOException {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
@ -98,7 +101,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -98,7 +101,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
}
private void writeEntry(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler,
JarArchiveEntry entry, Library library) throws IOException {
JarArchiveEntry entry, @Nullable Library library) throws IOException {
setUpEntry(jarFile, entry, unpackHandler);
try (ZipHeaderPeekInputStream inputStream = new ZipHeaderPeekInputStream(jarFile.getInputStream(entry))) {
EntryWriter entryWriter = new InputStreamEntryWriter(inputStream);
@ -168,7 +171,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -168,7 +171,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
* @throws IOException if the write fails
* @since 2.3.0
*/
public void writeIndexFile(String location, Collection<String> lines) throws IOException {
public void writeIndexFile(@Nullable String location, Collection<String> lines) throws IOException {
if (location != null) {
JarArchiveEntry entry = new JarArchiveEntry(location);
writeEntry(entry, (outputStream) -> {
@ -207,7 +210,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -207,7 +210,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
}
@Override
public void writeLoaderClasses(LoaderImplementation loaderImplementation) throws IOException {
public void writeLoaderClasses(@Nullable LoaderImplementation loaderImplementation) throws IOException {
writeLoaderClasses((loaderImplementation != null) ? loaderImplementation.getJarResourceName()
: LoaderImplementation.DEFAULT.getJarResourceName());
}
@ -255,7 +258,8 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -255,7 +258,8 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
* @param entryWriter the entry writer or {@code null} if there is no content
* @throws IOException in case of I/O errors
*/
private void writeEntry(JarArchiveEntry entry, Library library, EntryWriter entryWriter) throws IOException {
private void writeEntry(JarArchiveEntry entry, @Nullable Library library, @Nullable EntryWriter entryWriter)
throws IOException {
String name = entry.getName();
if (this.writtenEntries.add(name)) {
writeParentDirectoryEntries(name);
@ -263,6 +267,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -263,6 +267,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
entry.getGeneralPurposeBit().useUTF8ForNames(true);
if (!entry.isDirectory() && entry.getSize() == -1) {
entryWriter = SizeCalculatingEntryWriter.get(entryWriter);
Assert.state(entryWriter != null, "'entryWriter' must not be null");
entry.setSize(entryWriter.size());
}
updateLayerIndex(entry, library);
@ -270,14 +275,14 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -270,14 +275,14 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
}
}
private void updateLayerIndex(JarArchiveEntry entry, Library library) {
if (this.layers != null && !entry.getName().endsWith("/")) {
private void updateLayerIndex(JarArchiveEntry entry, @Nullable Library library) {
if (this.layers != null && this.layersIndex != null && !entry.getName().endsWith("/")) {
Layer layer = (library != null) ? this.layers.getLayer(library) : this.layers.getLayer(entry.getName());
this.layersIndex.add(layer, entry.getName());
}
}
protected abstract void writeToArchive(ZipEntry entry, EntryWriter entryWriter) throws IOException;
protected abstract void writeToArchive(ZipEntry entry, @Nullable EntryWriter entryWriter) throws IOException;
private void writeParentDirectoryEntries(String name) throws IOException {
String parent = name.endsWith("/") ? name.substring(0, name.length() - 1) : name;
@ -320,7 +325,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -320,7 +325,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
private static final int BUFFER_SIZE = 32 * 1024;
private final MessageDigest messageDigest;
private final @Nullable MessageDigest messageDigest;
private final CRC32 crc = new CRC32();
@ -378,7 +383,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { @@ -378,7 +383,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
*/
EntryTransformer NONE = (jarEntry) -> jarEntry;
JarArchiveEntry transform(JarArchiveEntry jarEntry);
@Nullable JarArchiveEntry transform(JarArchiveEntry jarEntry);
}

34
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/BuildPropertiesWriter.java

@ -24,6 +24,8 @@ import java.time.format.DateTimeFormatter; @@ -24,6 +24,8 @@ import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Properties;
import org.jspecify.annotations.Nullable;
import org.springframework.core.CollectionFactory;
import org.springframework.util.StringUtils;
@ -86,7 +88,7 @@ public final class BuildPropertiesWriter { @@ -86,7 +88,7 @@ public final class BuildPropertiesWriter {
return properties;
}
private void addIfHasValue(Properties properties, String name, String value) {
private void addIfHasValue(Properties properties, String name, @Nullable String value) {
if (StringUtils.hasText(value)) {
properties.put(name, value);
}
@ -97,20 +99,20 @@ public final class BuildPropertiesWriter { @@ -97,20 +99,20 @@ public final class BuildPropertiesWriter {
*/
public static final class ProjectDetails {
private final String group;
private final @Nullable String group;
private final String artifact;
private final @Nullable String artifact;
private final String name;
private final @Nullable String name;
private final String version;
private final @Nullable String version;
private final Instant time;
private final @Nullable Instant time;
private final Map<String, String> additionalProperties;
private final @Nullable Map<String, String> additionalProperties;
public ProjectDetails(String group, String artifact, String version, String name, Instant time,
Map<String, String> additionalProperties) {
public ProjectDetails(@Nullable String group, @Nullable String artifact, @Nullable String version,
@Nullable String name, @Nullable Instant time, @Nullable Map<String, String> additionalProperties) {
this.group = group;
this.artifact = artifact;
this.name = name;
@ -120,7 +122,7 @@ public final class BuildPropertiesWriter { @@ -120,7 +122,7 @@ public final class BuildPropertiesWriter {
this.additionalProperties = additionalProperties;
}
private static void validateAdditionalProperties(Map<String, String> additionalProperties) {
private static void validateAdditionalProperties(@Nullable Map<String, String> additionalProperties) {
if (additionalProperties != null) {
additionalProperties.forEach((name, value) -> {
if (value == null) {
@ -130,27 +132,27 @@ public final class BuildPropertiesWriter { @@ -130,27 +132,27 @@ public final class BuildPropertiesWriter {
}
}
public String getGroup() {
public @Nullable String getGroup() {
return this.group;
}
public String getArtifact() {
public @Nullable String getArtifact() {
return this.artifact;
}
public String getName() {
public @Nullable String getName() {
return this.name;
}
public String getVersion() {
public @Nullable String getVersion() {
return this.version;
}
public Instant getTime() {
public @Nullable Instant getTime() {
return this.time;
}
public Map<String, String> getAdditionalProperties() {
public @Nullable Map<String, String> getAdditionalProperties() {
return this.additionalProperties;
}

8
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/DefaultLaunchScript.java

@ -29,6 +29,8 @@ import java.util.Set; @@ -29,6 +29,8 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jspecify.annotations.Nullable;
/**
* Default implementation of {@link LaunchScript}. Provides the default Spring Boot launch
* script or can load a specific script File. Also support mustache style template
@ -54,12 +56,12 @@ public class DefaultLaunchScript implements LaunchScript { @@ -54,12 +56,12 @@ public class DefaultLaunchScript implements LaunchScript {
* @param properties an optional set of script properties used for variable expansion
* @throws IOException if the script cannot be loaded
*/
public DefaultLaunchScript(File file, Map<?, ?> properties) throws IOException {
public DefaultLaunchScript(@Nullable File file, Map<?, ?> properties) throws IOException {
String content = loadContent(file);
this.content = expandPlaceholders(content, properties);
}
private String loadContent(File file) throws IOException {
private String loadContent(@Nullable File file) throws IOException {
if (file == null) {
return loadContent(getClass().getResourceAsStream("launch.script"));
}
@ -83,7 +85,7 @@ public class DefaultLaunchScript implements LaunchScript { @@ -83,7 +85,7 @@ public class DefaultLaunchScript implements LaunchScript {
outputStream.flush();
}
private String expandPlaceholders(String content, Map<?, ?> properties) throws IOException {
private String expandPlaceholders(@Nullable String content, Map<?, ?> properties) throws IOException {
StringBuilder expanded = new StringBuilder();
Matcher matcher = PLACEHOLDER_PATTERN.matcher(content);
while (matcher.find()) {

9
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/FileUtils.java

@ -23,6 +23,8 @@ import java.util.jar.Attributes; @@ -23,6 +23,8 @@ import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.jspecify.annotations.Nullable;
/**
* Utilities for manipulating files and directories in Spring Boot tooling.
*
@ -61,7 +63,10 @@ public abstract class FileUtils { @@ -61,7 +63,10 @@ public abstract class FileUtils {
* @return if the file has been signed
* @throws IOException on IO error
*/
public static boolean isSignedJarFile(File file) throws IOException {
public static boolean isSignedJarFile(@Nullable File file) throws IOException {
if (file == null) {
return false;
}
try (JarFile jarFile = new JarFile(file)) {
if (hasDigestEntry(jarFile.getManifest())) {
return true;
@ -70,7 +75,7 @@ public abstract class FileUtils { @@ -70,7 +75,7 @@ public abstract class FileUtils {
return false;
}
private static boolean hasDigestEntry(Manifest manifest) {
private static boolean hasDigestEntry(@Nullable Manifest manifest) {
return (manifest != null) && manifest.getEntries().values().stream().anyMatch(FileUtils::hasDigestName);
}

13
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ImagePackager.java

@ -22,6 +22,8 @@ import java.util.function.BiConsumer; @@ -22,6 +22,8 @@ import java.util.function.BiConsumer;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -38,7 +40,7 @@ public class ImagePackager extends Packager { @@ -38,7 +40,7 @@ public class ImagePackager extends Packager {
* @param source the source file to package
* @param backupFile the backup of the source file to package
*/
public ImagePackager(File source, File backupFile) {
public ImagePackager(File source, @Nullable File backupFile) {
super(source);
setBackupFile(backupFile);
if (isAlreadyPackaged()) {
@ -55,7 +57,8 @@ public class ImagePackager extends Packager { @@ -55,7 +57,8 @@ public class ImagePackager extends Packager {
* @param exporter the exporter used to write the image
* @throws IOException on IO error
*/
public void packageImage(Libraries libraries, BiConsumer<ZipEntry, EntryWriter> exporter) throws IOException {
public void packageImage(Libraries libraries, BiConsumer<ZipEntry, @Nullable EntryWriter> exporter)
throws IOException {
packageImage(libraries, new DelegatingJarWriter(exporter));
}
@ -71,14 +74,14 @@ public class ImagePackager extends Packager { @@ -71,14 +74,14 @@ public class ImagePackager extends Packager {
*/
private static class DelegatingJarWriter extends AbstractJarWriter {
private final BiConsumer<ZipEntry, EntryWriter> exporter;
private final BiConsumer<ZipEntry, @Nullable EntryWriter> exporter;
DelegatingJarWriter(BiConsumer<ZipEntry, EntryWriter> exporter) {
DelegatingJarWriter(BiConsumer<ZipEntry, @Nullable EntryWriter> exporter) {
this.exporter = exporter;
}
@Override
protected void writeToArchive(ZipEntry entry, EntryWriter entryWriter) throws IOException {
protected void writeToArchive(ZipEntry entry, @Nullable EntryWriter entryWriter) throws IOException {
this.exporter.accept(entry, entryWriter);
}

4
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JarModeLibrary.java

@ -63,7 +63,9 @@ public class JarModeLibrary extends Library { @@ -63,7 +63,9 @@ public class JarModeLibrary extends Library {
@Override
public InputStream openStream() throws IOException {
String path = "META-INF/jarmode/" + getCoordinates().getArtifactId() + ".jar";
LibraryCoordinates coordinates = getCoordinates();
Assert.state(coordinates != null, "'coordinates' must not be null");
String path = "META-INF/jarmode/" + coordinates.getArtifactId() + ".jar";
URL resource = getClass().getClassLoader().getResource(path);
Assert.state(resource != null, () -> "Unable to find resource " + path);
return resource.openStream();

9
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/JarWriter.java

@ -26,6 +26,7 @@ import java.util.zip.ZipException; @@ -26,6 +26,7 @@ import java.util.zip.ZipException;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;
import org.jspecify.annotations.Nullable;
/**
* Writes JAR content, ensuring valid directory entries are always created and duplicate
@ -41,7 +42,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable { @@ -41,7 +42,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable {
private final JarArchiveOutputStream jarOutputStream;
private final FileTime lastModifiedTime;
private final @Nullable FileTime lastModifiedTime;
/**
* Create a new {@link JarWriter} instance.
@ -60,7 +61,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable { @@ -60,7 +61,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable {
* @throws IOException if the file cannot be opened
* @throws FileNotFoundException if the file cannot be found
*/
public JarWriter(File file, LaunchScript launchScript) throws FileNotFoundException, IOException {
public JarWriter(File file, @Nullable LaunchScript launchScript) throws FileNotFoundException, IOException {
this(file, launchScript, null);
}
@ -74,7 +75,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable { @@ -74,7 +75,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable {
* @throws FileNotFoundException if the file cannot be found
* @since 2.3.0
*/
public JarWriter(File file, LaunchScript launchScript, FileTime lastModifiedTime)
public JarWriter(File file, @Nullable LaunchScript launchScript, @Nullable FileTime lastModifiedTime)
throws FileNotFoundException, IOException {
this.jarOutputStream = new JarArchiveOutputStream(new FileOutputStream(file));
if (launchScript != null) {
@ -86,7 +87,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable { @@ -86,7 +87,7 @@ public class JarWriter extends AbstractJarWriter implements AutoCloseable {
}
@Override
protected void writeToArchive(ZipEntry entry, EntryWriter entryWriter) throws IOException {
protected void writeToArchive(ZipEntry entry, @Nullable EntryWriter entryWriter) throws IOException {
JarArchiveEntry jarEntry = asJarArchiveEntry(entry);
if (this.lastModifiedTime != null) {
jarEntry.setTime(DefaultTimeZoneOffset.INSTANCE.removeFrom(this.lastModifiedTime).toMillis());

4
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layer.java

@ -19,6 +19,8 @@ package org.springframework.boot.loader.tools; @@ -19,6 +19,8 @@ package org.springframework.boot.loader.tools;
import java.util.Locale;
import java.util.regex.Pattern;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -48,7 +50,7 @@ public class Layer { @@ -48,7 +50,7 @@ public class Layer {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}

10
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layout.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.loader.tools;
import org.jspecify.annotations.Nullable;
/**
* Strategy interface used to determine the layout for a particular type of archive.
* Layouts may additionally implement {@link CustomLoaderLayout} if they wish to write
@ -33,7 +35,7 @@ public interface Layout { @@ -33,7 +35,7 @@ public interface Layout {
* Returns the launcher class name for this layout.
* @return the launcher class name
*/
String getLauncherClassName();
@Nullable String getLauncherClassName();
/**
* Returns the destination path for a given library.
@ -42,7 +44,7 @@ public interface Layout { @@ -42,7 +44,7 @@ public interface Layout {
* @return the location of the library relative to the root of the archive (should end
* with '/') or {@code null} if the library should not be included.
*/
String getLibraryLocation(String libraryName, LibraryScope scope);
@Nullable String getLibraryLocation(String libraryName, @Nullable LibraryScope scope);
/**
* Returns the location of classes within the archive.
@ -57,7 +59,7 @@ public interface Layout { @@ -57,7 +59,7 @@ public interface Layout {
* @return the classpath index file location
* @since 2.5.0
*/
default String getClasspathIndexFileLocation() {
default @Nullable String getClasspathIndexFileLocation() {
return null;
}
@ -68,7 +70,7 @@ public interface Layout { @@ -68,7 +70,7 @@ public interface Layout {
* @return the layer index file location
* @since 2.5.0
*/
default String getLayersIndexFileLocation() {
default @Nullable String getLayersIndexFileLocation() {
return null;
}

16
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Layouts.java

@ -22,6 +22,10 @@ import java.util.HashMap; @@ -22,6 +22,10 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
* Common {@link Layout layouts}.
*
@ -43,9 +47,7 @@ public final class Layouts { @@ -43,9 +47,7 @@ public final class Layouts {
* @return a {@link Layout}
*/
public static Layout forFile(File file) {
if (file == null) {
throw new IllegalArgumentException("File must not be null");
}
Assert.notNull(file, "'file' must not be null");
String lowerCaseFileName = file.getName().toLowerCase(Locale.ENGLISH);
if (lowerCaseFileName.endsWith(".jar")) {
return new Jar();
@ -65,12 +67,12 @@ public final class Layouts { @@ -65,12 +67,12 @@ public final class Layouts {
public static class Jar implements RepackagingLayout {
@Override
public String getLauncherClassName() {
public @Nullable String getLauncherClassName() {
return "org.springframework.boot.loader.launch.JarLauncher";
}
@Override
public String getLibraryLocation(String libraryName, LibraryScope scope) {
public String getLibraryLocation(String libraryName, @Nullable LibraryScope scope) {
return "BOOT-INF/lib/";
}
@ -119,7 +121,7 @@ public final class Layouts { @@ -119,7 +121,7 @@ public final class Layouts {
public static class None extends Jar {
@Override
public String getLauncherClassName() {
public @Nullable String getLauncherClassName() {
return null;
}
@ -152,7 +154,7 @@ public final class Layouts { @@ -152,7 +154,7 @@ public final class Layouts {
}
@Override
public String getLibraryLocation(String libraryName, LibraryScope scope) {
public @Nullable String getLibraryLocation(String libraryName, @Nullable LibraryScope scope) {
return SCOPE_LOCATION.get(scope);
}

28
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Library.java

@ -21,6 +21,10 @@ import java.io.FileInputStream; @@ -21,6 +21,10 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
* Encapsulates information about a single library that may be packed into the archive.
*
@ -33,11 +37,11 @@ public class Library { @@ -33,11 +37,11 @@ public class Library {
private final String name;
private final File file;
private final @Nullable File file;
private final LibraryScope scope;
private final @Nullable LibraryScope scope;
private final LibraryCoordinates coordinates;
private final @Nullable LibraryCoordinates coordinates;
private final boolean unpackRequired;
@ -67,9 +71,9 @@ public class Library { @@ -67,9 +71,9 @@ public class Library {
* @param included if the library is included in the uber jar
* @since 2.4.8
*/
public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates, boolean unpackRequired,
boolean local, boolean included) {
this.name = (name != null) ? name : file.getName();
public Library(@Nullable String name, @Nullable File file, @Nullable LibraryScope scope,
@Nullable LibraryCoordinates coordinates, boolean unpackRequired, boolean local, boolean included) {
this.name = (name != null) ? name : getFileName(file);
this.file = file;
this.scope = scope;
this.coordinates = coordinates;
@ -78,6 +82,11 @@ public class Library { @@ -78,6 +82,11 @@ public class Library {
this.included = included;
}
private static String getFileName(@Nullable File file) {
Assert.state(file != null, "'file' must not be null");
return file.getName();
}
/**
* Return the name of file as it should be written.
* @return the name
@ -90,7 +99,7 @@ public class Library { @@ -90,7 +99,7 @@ public class Library {
* Return the library file.
* @return the file
*/
public File getFile() {
public @Nullable File getFile() {
return this.file;
}
@ -107,7 +116,7 @@ public class Library { @@ -107,7 +116,7 @@ public class Library {
* Return the scope of the library.
* @return the scope
*/
public LibraryScope getScope() {
public @Nullable LibraryScope getScope() {
return this.scope;
}
@ -115,7 +124,7 @@ public class Library { @@ -115,7 +124,7 @@ public class Library {
* Return the {@linkplain LibraryCoordinates coordinates} of the library.
* @return the coordinates
*/
public LibraryCoordinates getCoordinates() {
public @Nullable LibraryCoordinates getCoordinates() {
return this.coordinates;
}
@ -129,6 +138,7 @@ public class Library { @@ -129,6 +138,7 @@ public class Library {
}
long getLastModified() {
Assert.state(this.file != null, "'file' must not be null");
return this.file.lastModified();
}

4
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/LibraryCoordinates.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.boot.loader.tools;
import org.jspecify.annotations.Nullable;
/**
* Encapsulates information about the artifact coordinates of a library.
*
@ -60,7 +62,7 @@ public interface LibraryCoordinates { @@ -60,7 +62,7 @@ public interface LibraryCoordinates {
* @param coordinates the coordinates to convert (may be {@code null})
* @return the standard notation form or {@code "::"} when the coordinates are null
*/
static String toStandardNotationString(LibraryCoordinates coordinates) {
static String toStandardNotationString(@Nullable LibraryCoordinates coordinates) {
if (coordinates == null) {
return "::";
}

44
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/MainClassFinder.java

@ -36,6 +36,8 @@ import java.util.Set; @@ -36,6 +36,8 @@ import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.jspecify.annotations.Nullable;
import org.springframework.asm.AnnotationVisitor;
import org.springframework.asm.ClassReader;
import org.springframework.asm.ClassVisitor;
@ -80,7 +82,7 @@ public abstract class MainClassFinder { @@ -80,7 +82,7 @@ public abstract class MainClassFinder {
* @return the main class or {@code null}
* @throws IOException if the directory cannot be read
*/
public static String findMainClass(File rootDirectory) throws IOException {
public static @Nullable String findMainClass(File rootDirectory) throws IOException {
return doWithMainClasses(rootDirectory, MainClass::getName);
}
@ -90,7 +92,7 @@ public abstract class MainClassFinder { @@ -90,7 +92,7 @@ public abstract class MainClassFinder {
* @return the main class or {@code null}
* @throws IOException if the directory cannot be read
*/
public static String findSingleMainClass(File rootDirectory) throws IOException {
public static @Nullable String findSingleMainClass(File rootDirectory) throws IOException {
return findSingleMainClass(rootDirectory, null);
}
@ -104,7 +106,8 @@ public abstract class MainClassFinder { @@ -104,7 +106,8 @@ public abstract class MainClassFinder {
* @return the main class or {@code null}
* @throws IOException if the directory cannot be read
*/
public static String findSingleMainClass(File rootDirectory, String annotationName) throws IOException {
public static @Nullable String findSingleMainClass(File rootDirectory, @Nullable String annotationName)
throws IOException {
SingleMainClassCallback callback = new SingleMainClassCallback(annotationName);
MainClassFinder.doWithMainClasses(rootDirectory, callback);
return callback.getMainClassName();
@ -119,7 +122,7 @@ public abstract class MainClassFinder { @@ -119,7 +122,7 @@ public abstract class MainClassFinder {
* @return the first callback result or {@code null}
* @throws IOException in case of I/O errors
*/
static <T> T doWithMainClasses(File rootDirectory, MainClassCallback<T> callback) throws IOException {
static <T> @Nullable T doWithMainClasses(File rootDirectory, MainClassCallback<T> callback) throws IOException {
if (!rootDirectory.exists()) {
return null; // nothing to do
}
@ -165,7 +168,7 @@ public abstract class MainClassFinder { @@ -165,7 +168,7 @@ public abstract class MainClassFinder {
* @return the main class or {@code null}
* @throws IOException if the jar file cannot be read
*/
public static String findMainClass(JarFile jarFile, String classesLocation) throws IOException {
public static @Nullable String findMainClass(JarFile jarFile, String classesLocation) throws IOException {
return doWithMainClasses(jarFile, classesLocation, MainClass::getName);
}
@ -176,7 +179,7 @@ public abstract class MainClassFinder { @@ -176,7 +179,7 @@ public abstract class MainClassFinder {
* @return the main class or {@code null}
* @throws IOException if the jar file cannot be read
*/
public static String findSingleMainClass(JarFile jarFile, String classesLocation) throws IOException {
public static @Nullable String findSingleMainClass(JarFile jarFile, String classesLocation) throws IOException {
return findSingleMainClass(jarFile, classesLocation, null);
}
@ -191,8 +194,8 @@ public abstract class MainClassFinder { @@ -191,8 +194,8 @@ public abstract class MainClassFinder {
* @return the main class or {@code null}
* @throws IOException if the jar file cannot be read
*/
public static String findSingleMainClass(JarFile jarFile, String classesLocation, String annotationName)
throws IOException {
public static @Nullable String findSingleMainClass(JarFile jarFile, String classesLocation,
@Nullable String annotationName) throws IOException {
SingleMainClassCallback callback = new SingleMainClassCallback(annotationName);
MainClassFinder.doWithMainClasses(jarFile, classesLocation, callback);
return callback.getMainClassName();
@ -207,7 +210,7 @@ public abstract class MainClassFinder { @@ -207,7 +210,7 @@ public abstract class MainClassFinder {
* @return the first callback result or {@code null}
* @throws IOException in case of I/O errors
*/
static <T> T doWithMainClasses(JarFile jarFile, String classesLocation, MainClassCallback<T> callback)
static <T> @Nullable T doWithMainClasses(JarFile jarFile, String classesLocation, MainClassCallback<T> callback)
throws IOException {
List<JarEntry> classEntries = getClassEntries(jarFile, classesLocation);
classEntries.sort(new ClassEntryComparator());
@ -226,7 +229,7 @@ public abstract class MainClassFinder { @@ -226,7 +229,7 @@ public abstract class MainClassFinder {
return null;
}
private static String convertToClassName(String name, String prefix) {
private static String convertToClassName(String name, @Nullable String prefix) {
name = name.replace('/', '.');
name = name.replace('\\', '.');
name = name.substring(0, name.length() - DOT_CLASS.length());
@ -236,7 +239,7 @@ public abstract class MainClassFinder { @@ -236,7 +239,7 @@ public abstract class MainClassFinder {
return name;
}
private static List<JarEntry> getClassEntries(JarFile source, String classesLocation) {
private static List<JarEntry> getClassEntries(JarFile source, @Nullable String classesLocation) {
classesLocation = (classesLocation != null) ? classesLocation : "";
Enumeration<JarEntry> sourceEntries = source.entries();
List<JarEntry> classEntries = new ArrayList<>();
@ -249,7 +252,7 @@ public abstract class MainClassFinder { @@ -249,7 +252,7 @@ public abstract class MainClassFinder {
return classEntries;
}
private static ClassDescriptor createClassDescriptor(InputStream inputStream) {
private static @Nullable ClassDescriptor createClassDescriptor(InputStream inputStream) {
try {
ClassReader classReader = new ClassReader(inputStream);
ClassDescriptor classDescriptor = new ClassDescriptor();
@ -291,13 +294,14 @@ public abstract class MainClassFinder { @@ -291,13 +294,14 @@ public abstract class MainClassFinder {
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
public @Nullable AnnotationVisitor visitAnnotation(String desc, boolean visible) {
this.annotationNames.add(Type.getType(desc).getClassName());
return null;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
public @Nullable MethodVisitor visitMethod(int access, String name, String desc, String signature,
String[] exceptions) {
if (isAccess(access, Opcodes.ACC_PUBLIC, Opcodes.ACC_STATIC) && MAIN_METHOD_NAME.equals(name)
&& MAIN_METHOD_TYPE.getDescriptor().equals(desc)) {
this.mainMethodFound = true;
@ -336,7 +340,7 @@ public abstract class MainClassFinder { @@ -336,7 +340,7 @@ public abstract class MainClassFinder {
* @param mainClass the main class
* @return a non-null value if processing should end or {@code null} to continue
*/
T doWith(MainClass mainClass);
@Nullable T doWith(MainClass mainClass);
}
@ -370,7 +374,7 @@ public abstract class MainClassFinder { @@ -370,7 +374,7 @@ public abstract class MainClassFinder {
}
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
@ -404,19 +408,19 @@ public abstract class MainClassFinder { @@ -404,19 +408,19 @@ public abstract class MainClassFinder {
private final Set<MainClass> mainClasses = new LinkedHashSet<>();
private final String annotationName;
private final @Nullable String annotationName;
private SingleMainClassCallback(String annotationName) {
private SingleMainClassCallback(@Nullable String annotationName) {
this.annotationName = annotationName;
}
@Override
public Object doWith(MainClass mainClass) {
public @Nullable Object doWith(MainClass mainClass) {
this.mainClasses.add(mainClass);
return null;
}
private String getMainClassName() {
private @Nullable String getMainClassName() {
Set<MainClass> matchingMainClasses = new LinkedHashSet<>();
if (this.annotationName != null) {
for (MainClass mainClass : this.mainClasses) {

44
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Packager.java

@ -39,6 +39,7 @@ import java.util.jar.Manifest; @@ -39,6 +39,7 @@ import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.loader.tools.AbstractJarWriter.EntryTransformer;
import org.springframework.boot.loader.tools.AbstractJarWriter.UnpackHandler;
@ -84,21 +85,21 @@ public abstract class Packager { @@ -84,21 +85,21 @@ public abstract class Packager {
private final List<MainClassTimeoutWarningListener> mainClassTimeoutListeners = new ArrayList<>();
private String mainClass;
private @Nullable String mainClass;
private final File source;
private File backupFile;
private @Nullable File backupFile;
private Layout layout;
private @Nullable Layout layout;
private LoaderImplementation loaderImplementation;
private @Nullable LoaderImplementation loaderImplementation;
private LayoutFactory layoutFactory;
private @Nullable LayoutFactory layoutFactory;
private Layers layers;
private @Nullable Layers layers;
private LayersIndex layersIndex;
private @Nullable LayersIndex layersIndex;
private boolean includeRelevantJarModeJars = true;
@ -128,7 +129,7 @@ public abstract class Packager { @@ -128,7 +129,7 @@ public abstract class Packager {
* searched for a suitable class.
* @param mainClass the main class name
*/
public void setMainClass(String mainClass) {
public void setMainClass(@Nullable String mainClass) {
this.mainClass = mainClass;
}
@ -145,7 +146,7 @@ public abstract class Packager { @@ -145,7 +146,7 @@ public abstract class Packager {
* Sets the loader implementation to use.
* @param loaderImplementation the loaderImplementation to set
*/
public void setLoaderImplementation(LoaderImplementation loaderImplementation) {
public void setLoaderImplementation(@Nullable LoaderImplementation loaderImplementation) {
this.loaderImplementation = loaderImplementation;
}
@ -154,7 +155,7 @@ public abstract class Packager { @@ -154,7 +155,7 @@ public abstract class Packager {
* layout is specified.
* @param layoutFactory the layout factory to set
*/
public void setLayoutFactory(LayoutFactory layoutFactory) {
public void setLayoutFactory(@Nullable LayoutFactory layoutFactory) {
this.layoutFactory = layoutFactory;
}
@ -172,7 +173,7 @@ public abstract class Packager { @@ -172,7 +173,7 @@ public abstract class Packager {
* Sets the {@link File} to use to back up the original source.
* @param backupFile the file to use to back up the original source
*/
protected void setBackupFile(File backupFile) {
protected void setBackupFile(@Nullable File backupFile) {
this.backupFile = backupFile;
}
@ -260,8 +261,11 @@ public abstract class Packager { @@ -260,8 +261,11 @@ public abstract class Packager {
}
private void writeLayerIndex(AbstractJarWriter writer) throws IOException {
Assert.state(this.layout != null, "'layout' must not be null");
String name = this.layout.getLayersIndexFileLocation();
if (StringUtils.hasLength(name)) {
Assert.state(this.layers != null, "'layers' must not be null");
Assert.state(this.layersIndex != null, "'layersIndex' must not be null");
Layer layer = this.layers.getLayer(name);
this.layersIndex.add(layer, name);
writer.writeEntry(name, this.layersIndex::writeTo);
@ -335,7 +339,7 @@ public abstract class Packager { @@ -335,7 +339,7 @@ public abstract class Packager {
}
}
private String getMainClass(JarFile source, Manifest manifest) throws IOException {
private @Nullable String getMainClass(JarFile source, Manifest manifest) throws IOException {
if (this.mainClass != null) {
return this.mainClass;
}
@ -346,7 +350,7 @@ public abstract class Packager { @@ -346,7 +350,7 @@ public abstract class Packager {
return findMainMethodWithTimeoutWarning(source);
}
private String findMainMethodWithTimeoutWarning(JarFile source) throws IOException {
private @Nullable String findMainMethodWithTimeoutWarning(JarFile source) throws IOException {
long startTime = System.currentTimeMillis();
String mainMethod = findMainMethod(source);
long duration = System.currentTimeMillis() - startTime;
@ -358,7 +362,7 @@ public abstract class Packager { @@ -358,7 +362,7 @@ public abstract class Packager {
return mainMethod;
}
protected String findMainMethod(JarFile source) throws IOException {
protected @Nullable String findMainMethod(JarFile source) throws IOException {
return MainClassFinder.findSingleMainClass(source, getLayout().getClassesLocation(),
SPRING_BOOT_APPLICATION_CLASS_NAME);
}
@ -434,7 +438,7 @@ public abstract class Packager { @@ -434,7 +438,7 @@ public abstract class Packager {
return entry.getName().endsWith(".cdx.json") || entry.getName().endsWith("/bom.json");
}
private void putIfHasLength(Attributes attributes, String name, String value) {
private void putIfHasLength(Attributes attributes, String name, @Nullable String value) {
if (StringUtils.hasLength(value)) {
attributes.putValue(name, value);
}
@ -456,7 +460,7 @@ public abstract class Packager { @@ -456,7 +460,7 @@ public abstract class Packager {
* @param duration the amount of time it took to find the main method
* @param mainMethod the main method that was actually found
*/
void handleTimeoutWarning(long duration, String mainMethod);
void handleTimeoutWarning(long duration, @Nullable String mainMethod);
}
@ -472,7 +476,7 @@ public abstract class Packager { @@ -472,7 +476,7 @@ public abstract class Packager {
}
@Override
public JarArchiveEntry transform(JarArchiveEntry entry) {
public @Nullable JarArchiveEntry transform(JarArchiveEntry entry) {
if (entry.getName().equals("META-INF/INDEX.LIST")) {
return null;
}
@ -528,7 +532,7 @@ public abstract class Packager { @@ -528,7 +532,7 @@ public abstract class Packager {
private final UnpackHandler unpackHandler;
private final Function<JarEntry, Library> libraryLookup;
private final Function<JarEntry, @Nullable Library> libraryLookup;
PackagedLibraries(Libraries libraries, boolean ensureReproducibleBuild) throws IOException {
this.libraries = (ensureReproducibleBuild) ? new TreeMap<>() : new LinkedHashMap<>();
@ -553,7 +557,7 @@ public abstract class Packager { @@ -553,7 +557,7 @@ public abstract class Packager {
}
}
private Library lookup(JarEntry entry) {
private @Nullable Library lookup(JarEntry entry) {
return this.libraries.get(entry.getName());
}
@ -561,7 +565,7 @@ public abstract class Packager { @@ -561,7 +565,7 @@ public abstract class Packager {
return this.unpackHandler;
}
Function<JarEntry, Library> getLibraryLookup() {
Function<JarEntry, @Nullable Library> getLibraryLookup() {
return this.libraryLookup;
}

13
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java

@ -23,6 +23,8 @@ import java.util.Locale; @@ -23,6 +23,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.jar.JarFile;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@ -103,7 +105,8 @@ public class Repackager extends Packager { @@ -103,7 +105,8 @@ public class Repackager extends Packager {
* @throws IOException if the file cannot be repackaged
* @since 1.3.0
*/
public void repackage(File destination, Libraries libraries, LaunchScript launchScript) throws IOException {
public void repackage(File destination, Libraries libraries, @Nullable LaunchScript launchScript)
throws IOException {
repackage(destination, libraries, launchScript, null);
}
@ -118,8 +121,8 @@ public class Repackager extends Packager { @@ -118,8 +121,8 @@ public class Repackager extends Packager {
* @throws IOException if the file cannot be repackaged
* @since 2.3.0
*/
public void repackage(File destination, Libraries libraries, LaunchScript launchScript, FileTime lastModifiedTime)
throws IOException {
public void repackage(File destination, Libraries libraries, @Nullable LaunchScript launchScript,
@Nullable FileTime lastModifiedTime) throws IOException {
Assert.isTrue(destination != null && !destination.isDirectory(), "Invalid destination");
getLayout(); // get layout early
destination = destination.getAbsoluteFile();
@ -146,8 +149,8 @@ public class Repackager extends Packager { @@ -146,8 +149,8 @@ public class Repackager extends Packager {
}
}
private void repackage(JarFile sourceJar, File destination, Libraries libraries, LaunchScript launchScript,
FileTime lastModifiedTime) throws IOException {
private void repackage(JarFile sourceJar, File destination, Libraries libraries,
@Nullable LaunchScript launchScript, @Nullable FileTime lastModifiedTime) throws IOException {
try (JarWriter writer = new JarWriter(destination, launchScript, lastModifiedTime)) {
write(sourceJar, libraries, writer, lastModifiedTime != null);
}

10
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/RunProcess.java

@ -23,6 +23,8 @@ import java.util.Collection; @@ -23,6 +23,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.jspecify.annotations.Nullable;
/**
* Utility used to run a process.
*
@ -37,11 +39,11 @@ public class RunProcess { @@ -37,11 +39,11 @@ public class RunProcess {
private static final long JUST_ENDED_LIMIT = 500;
private final File workingDirectory;
private final @Nullable File workingDirectory;
private final String[] command;
private volatile Process process;
private volatile @Nullable Process process;
private volatile long endTime;
@ -60,7 +62,7 @@ public class RunProcess { @@ -60,7 +62,7 @@ public class RunProcess {
* to run in the working directory of the current Java process
* @param command the program to execute and its arguments
*/
public RunProcess(File workingDirectory, String... command) {
public RunProcess(@Nullable File workingDirectory, String... command) {
this.workingDirectory = workingDirectory;
this.command = command;
}
@ -104,7 +106,7 @@ public class RunProcess { @@ -104,7 +106,7 @@ public class RunProcess {
* Return the running process.
* @return the process or {@code null}
*/
public Process getRunningProcess() {
public @Nullable Process getRunningProcess() {
return this.process;
}

11
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/SizeCalculatingEntryWriter.java

@ -26,6 +26,9 @@ import java.io.IOException; @@ -26,6 +26,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
/**
@ -74,7 +77,7 @@ final class SizeCalculatingEntryWriter implements EntryWriter { @@ -74,7 +77,7 @@ final class SizeCalculatingEntryWriter implements EntryWriter {
return this.size;
}
static EntryWriter get(EntryWriter entryWriter) throws IOException {
static @Nullable EntryWriter get(@Nullable EntryWriter entryWriter) throws IOException {
if (entryWriter == null || entryWriter.size() != -1) {
return entryWriter;
}
@ -88,7 +91,7 @@ final class SizeCalculatingEntryWriter implements EntryWriter { @@ -88,7 +91,7 @@ final class SizeCalculatingEntryWriter implements EntryWriter {
private int size = 0;
private File tempFile;
private @Nullable File tempFile;
private OutputStream outputStream;
@ -131,8 +134,10 @@ final class SizeCalculatingEntryWriter implements EntryWriter { @@ -131,8 +134,10 @@ final class SizeCalculatingEntryWriter implements EntryWriter {
}
Object getContent() {
return (this.outputStream instanceof ByteArrayOutputStream byteArrayOutputStream)
Object result = (this.outputStream instanceof ByteArrayOutputStream byteArrayOutputStream)
? byteArrayOutputStream.toByteArray() : this.tempFile;
Assert.state(result != null, "'result' must not be null");
return result;
}
int getSize() {

4
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/ZipHeaderPeekInputStream.java

@ -22,6 +22,8 @@ import java.io.IOException; @@ -22,6 +22,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.jspecify.annotations.Nullable;
/**
* {@link InputStream} that can peek ahead at zip header bytes.
*
@ -37,7 +39,7 @@ class ZipHeaderPeekInputStream extends FilterInputStream { @@ -37,7 +39,7 @@ class ZipHeaderPeekInputStream extends FilterInputStream {
private int position;
private ByteArrayInputStream headerStream;
private @Nullable ByteArrayInputStream headerStream;
protected ZipHeaderPeekInputStream(InputStream in) throws IOException {
super(in);

4
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/layer/IncludeExcludeContentSelector.java

@ -20,6 +20,8 @@ import java.util.Collections; @@ -20,6 +20,8 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import org.jspecify.annotations.Nullable;
import org.springframework.boot.loader.tools.Layer;
import org.springframework.util.Assert;
@ -45,7 +47,7 @@ public class IncludeExcludeContentSelector<T> implements ContentSelector<T> { @@ -45,7 +47,7 @@ public class IncludeExcludeContentSelector<T> implements ContentSelector<T> {
this(layer, includes, excludes, Function.identity());
}
public <S> IncludeExcludeContentSelector(Layer layer, List<S> includes, List<S> excludes,
public <S> IncludeExcludeContentSelector(Layer layer, @Nullable List<S> includes, @Nullable List<S> excludes,
Function<S, ContentFilter<T>> filterFactory) {
Assert.notNull(layer, "'layer' must not be null");
Assert.notNull(filterFactory, "'filterFactory' must not be null");

4
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/layer/package-info.java

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
/**
* Classes used to support layer customization.
*
*/
@NullMarked
package org.springframework.boot.loader.tools.layer;
import org.jspecify.annotations.NullMarked;

3
loader/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/package-info.java

@ -17,4 +17,7 @@ @@ -17,4 +17,7 @@
/**
* Tools for generating executable JAR/WAR files.
*/
@NullMarked
package org.springframework.boot.loader.tools;
import org.jspecify.annotations.NullMarked;

Loading…
Cancel
Save