diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java index 3adcd5c5361..74681400eb8 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractAotMojo.java @@ -44,6 +44,7 @@ import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; import org.apache.maven.toolchain.ToolchainManager; +import org.jspecify.annotations.Nullable; /** * Abstract base class for AOT processing MOJOs. @@ -59,6 +60,7 @@ public abstract class AbstractAotMojo extends AbstractDependencyFilterMojo { * The current Maven session. This is used for toolchain manager API calls. */ @Parameter(defaultValue = "${session}", readonly = true) + @SuppressWarnings("NullAway.Init") private MavenSession session; /** @@ -76,21 +78,21 @@ public abstract class AbstractAotMojo extends AbstractDependencyFilterMojo { * List of JVM system properties to pass to the AOT process. */ @Parameter - private Map systemPropertyVariables; + private @Nullable Map systemPropertyVariables; /** * JVM arguments that should be associated with the AOT process. On command line, make * sure to wrap multiple values between quotes. */ @Parameter(property = "spring-boot.aot.jvmArguments") - private String jvmArguments; + private @Nullable String jvmArguments; /** * Arguments that should be provided to the AOT compile process. On command line, make * sure to wrap multiple values between quotes. */ @Parameter(property = "spring-boot.aot.compilerArguments") - private String compilerArguments; + private @Nullable String compilerArguments; protected AbstractAotMojo(ToolchainManager toolchainManager) { this.toolchainManager = toolchainManager; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java index da70807079f..ce689c45023 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java @@ -36,6 +36,7 @@ import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactFeatur import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; +import org.jspecify.annotations.Nullable; /** * A base mojo filtering the dependencies of the project. @@ -67,6 +68,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { * @since 3.0.0 */ @Parameter(defaultValue = "${project}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") protected MavenProject project; /** @@ -78,7 +80,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { * @since 1.2.0 */ @Parameter(property = "spring-boot.includes") - private List includes; + private @Nullable List includes; /** * Collection of artifact definitions to exclude. The {@link Exclude} element defines @@ -89,20 +91,20 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { * @since 1.1.0 */ @Parameter(property = "spring-boot.excludes") - private List excludes; + private @Nullable List excludes; /** * Comma separated list of groupId names to exclude (exact match). * @since 1.1.0 */ @Parameter(property = "spring-boot.excludeGroupIds", defaultValue = "") - private String excludeGroupIds; + private @Nullable String excludeGroupIds; - protected void setExcludes(List excludes) { + protected void setExcludes(@Nullable List excludes) { this.excludes = excludes; } - protected void setIncludes(List includes) { + protected void setIncludes(@Nullable List includes) { this.includes = includes; } @@ -163,7 +165,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { return filters; } - private String cleanFilterConfig(String content) { + private String cleanFilterConfig(@Nullable String content) { if (content == null || content.trim().isEmpty()) { return ""; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java index 0b1bd80a47d..6de78382df3 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractPackagerMojo.java @@ -36,6 +36,7 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; import org.apache.maven.shared.artifact.filter.collection.ScopeFilter; +import org.jspecify.annotations.Nullable; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -67,6 +68,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @since 1.0.0 */ @Parameter(defaultValue = "${project}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") protected MavenProject project; /** @@ -74,6 +76,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @since 2.4.0 */ @Parameter(defaultValue = "${session}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") protected MavenSession session; /** @@ -88,7 +91,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @since 1.0.0 */ @Parameter - private String mainClass; + private @Nullable String mainClass; /** * Exclude Spring Boot devtools from the repackaged archive. @@ -135,7 +138,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @return {@code null}, indicating a layout type will be chosen based on the original * archive type */ - protected LayoutType getLayout() { + protected @Nullable LayoutType getLayout() { return null; } @@ -144,7 +147,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @return the loader implementation or {@code null} * @since 3.2.0 */ - protected LoaderImplementation getLoaderImplementation() { + protected @Nullable LoaderImplementation getLoaderImplementation() { return null; } @@ -153,7 +156,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * no explicit layout is set. * @return {@code null}, indicating a default layout factory will be chosen */ - protected LayoutFactory getLayoutFactory() { + protected @Nullable LayoutFactory getLayoutFactory() { return null; } @@ -211,7 +214,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @return the libraries to use * @throws MojoExecutionException on execution error */ - protected final Libraries getLibraries(Collection unpacks) throws MojoExecutionException { + protected final Libraries getLibraries(@Nullable Collection unpacks) throws MojoExecutionException { Set artifacts = this.project.getArtifacts(); Set includedArtifacts = filterDependencies(artifacts, getAdditionalFilters()); return new ArtifactsLibraries(artifacts, includedArtifacts, this.session.getProjects(), unpacks, getLog()); @@ -238,12 +241,12 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo * @param classifier the artifact classifier * @return the source artifact to repackage */ - protected Artifact getSourceArtifact(String classifier) { + protected Artifact getSourceArtifact(@Nullable String classifier) { Artifact sourceArtifact = getArtifact(classifier); return (sourceArtifact != null) ? sourceArtifact : this.project.getArtifact(); } - private Artifact getArtifact(String classifier) { + private @Nullable Artifact getArtifact(@Nullable String classifier) { if (classifier != null) { for (Artifact attachedArtifact : this.project.getAttachedArtifacts()) { if (classifier.equals(attachedArtifact.getClassifier()) && attachedArtifact.getFile() != null @@ -255,7 +258,7 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo return null; } - protected File getTargetFile(String finalName, String classifier, File targetDirectory) { + protected File getTargetFile(String finalName, @Nullable String classifier, File targetDirectory) { String classifierSuffix = (classifier != null) ? classifier.trim() : ""; if (!classifierSuffix.isEmpty() && !classifierSuffix.startsWith("-")) { classifierSuffix = "-" + classifierSuffix; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java index 64cdf3c8379..1d88d36e13d 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractRunMojo.java @@ -36,6 +36,7 @@ import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.toolchain.ToolchainManager; +import org.jspecify.annotations.Nullable; import org.springframework.boot.loader.tools.FileUtils; @@ -60,6 +61,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.0.0 */ @Parameter(defaultValue = "${project}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") private MavenProject project; /** @@ -68,6 +70,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 2.3.0 */ @Parameter(defaultValue = "${session}", readonly = true) + @SuppressWarnings("NullAway.Init") private MavenSession session; /** @@ -95,6 +98,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 2.2.0 */ @Parameter(property = "spring-boot.run.agents") + @SuppressWarnings("NullAway") // maven-maven-plugin can't handle annotated arrays private File[] agents; /** @@ -112,7 +116,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.5.0 */ @Parameter(property = "spring-boot.run.workingDirectory") - private File workingDirectory; + private @Nullable File workingDirectory; /** * JVM arguments that should be associated with the forked process used to run the @@ -121,7 +125,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.1.0 */ @Parameter(property = "spring-boot.run.jvmArguments") - private String jvmArguments; + private @Nullable String jvmArguments; /** * List of JVM system properties to pass to the process. @@ -129,7 +133,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 2.1.0 */ @Parameter - private Map systemPropertyVariables; + private @Nullable Map systemPropertyVariables; /** * List of Environment variables that should be associated with the forked process @@ -138,7 +142,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 2.1.0 */ @Parameter - private Map environmentVariables; + private @Nullable Map environmentVariables; /** * Arguments that should be passed to the application. @@ -146,6 +150,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.0.0 */ @Parameter + @SuppressWarnings("NullAway") // maven-maven-plugin can't handle annotated arrays private String[] arguments; /** @@ -156,7 +161,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 2.2.3 */ @Parameter(property = "spring-boot.run.arguments") - private String commandlineArguments; + private @Nullable String commandlineArguments; /** * The spring profiles to activate. Convenience shortcut of specifying the @@ -166,6 +171,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.3.0 */ @Parameter(property = "spring-boot.run.profiles") + @SuppressWarnings("NullAway") // maven-maven-plugin can't handle annotated arrays private String[] profiles; /** @@ -175,7 +181,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.0.0 */ @Parameter(property = "spring-boot.run.main-class") - private String mainClass; + private @Nullable String mainClass; /** * Additional classpath elements that should be added to the classpath. An element can @@ -184,6 +190,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 3.2.0 */ @Parameter(property = "spring-boot.run.additional-classpath-elements") + @SuppressWarnings("NullAway") // maven-maven-plugin can't handle annotated arrays private String[] additionalClasspathElements; /** @@ -193,6 +200,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { * @since 1.0.0 */ @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) + @SuppressWarnings("NullAway.Init") private File classesDirectory; /** @@ -336,7 +344,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { } private void addActiveProfileArgument(RunArguments arguments) { - if (this.profiles.length > 0) { + if (this.profiles != null && this.profiles.length > 0) { StringBuilder arg = new StringBuilder("--spring.profiles.active="); for (int i = 0; i < this.profiles.length; i++) { arg.append(this.profiles[i]); @@ -424,7 +432,7 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo { */ static class SystemPropertyFormatter { - static String format(String key, String value) { + static String format(@Nullable String key, @Nullable String value) { if (key == null) { return ""; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java index d7b50579d63..3db80473604 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java @@ -29,6 +29,7 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; +import org.jspecify.annotations.Nullable; import org.springframework.boot.loader.tools.Libraries; import org.springframework.boot.loader.tools.Library; @@ -64,7 +65,7 @@ public class ArtifactsLibraries implements Libraries { private final Collection localProjects; - private final Collection unpacks; + private final @Nullable Collection unpacks; private final Log log; @@ -93,7 +94,7 @@ public class ArtifactsLibraries implements Libraries { * @since 2.4.8 */ public ArtifactsLibraries(Set artifacts, Set includedArtifacts, - Collection localProjects, Collection unpacks, Log log) { + Collection localProjects, @Nullable Collection unpacks, Log log) { this.artifacts = artifacts; this.includedArtifacts = includedArtifacts; this.localProjects = localProjects; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java index 065db26b039..f545a77c65b 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildImageMojo.java @@ -34,6 +34,7 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProjectHelper; +import org.jspecify.annotations.Nullable; import org.springframework.boot.buildpack.platform.build.AbstractBuildLog; import org.springframework.boot.buildpack.platform.build.BuildLog; @@ -71,13 +72,15 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.0 */ @Parameter(defaultValue = "${project.build.directory}", required = true) + @SuppressWarnings("NullAway.Init") private File sourceDirectory; /** * Name of the source archive. * @since 2.3.0 */ - @Parameter(defaultValue = "${project.build.finalName}", readonly = true) + @Parameter(defaultValue = "${project.build.finalName}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") private String finalName; /** @@ -92,7 +95,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.0 */ @Parameter - private String classifier; + private @Nullable String classifier; /** * Image configuration, with {@code builder}, {@code runImage}, {@code name}, @@ -101,7 +104,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.0 */ @Parameter - private Image image; + private @Nullable Image image; /** * Alias for {@link Image#name} to support configuration through command-line @@ -109,7 +112,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.0 */ @Parameter(property = "spring-boot.build-image.imageName") - String imageName; + @Nullable String imageName; /** * Alias for {@link Image#builder} to support configuration through command-line @@ -117,14 +120,14 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.0 */ @Parameter(property = "spring-boot.build-image.builder") - String imageBuilder; + @Nullable String imageBuilder; /** * Alias for {@link Image#trustBuilder} to support configuration through command-line * property. */ @Parameter(property = "spring-boot.build-image.trustBuilder") - Boolean trustBuilder; + @Nullable Boolean trustBuilder; /** * Alias for {@link Image#runImage} to support configuration through command-line @@ -132,7 +135,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.1 */ @Parameter(property = "spring-boot.build-image.runImage") - String runImage; + @Nullable String runImage; /** * Alias for {@link Image#cleanCache} to support configuration through command-line @@ -140,21 +143,21 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.4.0 */ @Parameter(property = "spring-boot.build-image.cleanCache") - Boolean cleanCache; + @Nullable Boolean cleanCache; /** * Alias for {@link Image#pullPolicy} to support configuration through command-line * property. */ @Parameter(property = "spring-boot.build-image.pullPolicy") - PullPolicy pullPolicy; + @Nullable PullPolicy pullPolicy; /** * Alias for {@link Image#publish} to support configuration through command-line * property. */ @Parameter(property = "spring-boot.build-image.publish") - Boolean publish; + @Nullable Boolean publish; /** * Alias for {@link Image#network} to support configuration through command-line @@ -162,7 +165,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.6.0 */ @Parameter(property = "spring-boot.build-image.network") - String network; + @Nullable String network; /** * Alias for {@link Image#createdDate} to support configuration through command-line @@ -170,7 +173,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 3.1.0 */ @Parameter(property = "spring-boot.build-image.createdDate") - String createdDate; + @Nullable String createdDate; /** * Alias for {@link Image#applicationDirectory} to support configuration through @@ -178,7 +181,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 3.1.0 */ @Parameter(property = "spring-boot.build-image.applicationDirectory") - String applicationDirectory; + @Nullable String applicationDirectory; /** * Alias for {@link Image#imagePlatform} to support configuration through command-line @@ -186,14 +189,14 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 3.4.0 */ @Parameter(property = "spring-boot.build-image.imagePlatform") - String imagePlatform; + @Nullable String imagePlatform; /** * Docker configuration options. * @since 2.4.0 */ @Parameter - private Docker docker; + private @Nullable Docker docker; /** * The type of archive (which corresponds to how the dependencies are laid out inside @@ -202,14 +205,14 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.11 */ @Parameter - private LayoutType layout; + private @Nullable LayoutType layout; /** * The loader implementation that should be used. * @since 3.2.0 */ @Parameter - private LoaderImplementation loaderImplementation; + private @Nullable LoaderImplementation loaderImplementation; /** * The layout factory that will be used to create the executable archive if no @@ -218,7 +221,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * @since 2.3.11 */ @Parameter - private LayoutFactory layoutFactory; + private @Nullable LayoutFactory layoutFactory; protected BuildImageMojo(MavenProjectHelper projectHelper) { super(projectHelper); @@ -230,12 +233,12 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * is not provided */ @Override - protected LayoutType getLayout() { + protected @Nullable LayoutType getLayout() { return this.layout; } @Override - protected LoaderImplementation getLoaderImplementation() { + protected @Nullable LoaderImplementation getLoaderImplementation() { return this.loaderImplementation; } @@ -246,7 +249,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * parameter is not provided */ @Override - protected LayoutFactory getLayoutFactory() { + protected @Nullable LayoutFactory getLayoutFactory() { return this.layoutFactory; } @@ -340,7 +343,7 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo { * Return the {@link File} to use to back up the original source. * @return the file to use to back up the original source */ - private File getBackupFile() { + private @Nullable File getBackupFile() { // We can't use 'project.getAttachedArtifacts()' because package can be done in a // forked lifecycle and will be null if (this.classifier != null) { diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java index 3e52e888812..7877a60ad4e 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java @@ -33,6 +33,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; +import org.jspecify.annotations.Nullable; import org.sonatype.plexus.build.incremental.BuildContext; import org.springframework.boot.loader.tools.BuildPropertiesWriter; @@ -56,18 +57,21 @@ public class BuildInfoMojo extends AbstractMojo { * The Maven session. */ @Parameter(defaultValue = "${session}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") private MavenSession session; /** * The Maven project. */ @Parameter(defaultValue = "${project}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") private MavenProject project; /** * The location of the generated {@code build-info.properties} file. */ @Parameter(defaultValue = "${project.build.outputDirectory}/META-INF/build-info.properties") + @SuppressWarnings("NullAway.Init") private File outputFile; /** @@ -79,14 +83,14 @@ public class BuildInfoMojo extends AbstractMojo { * @since 2.2.0 */ @Parameter(defaultValue = "${project.build.outputTimestamp}") - private String time; + private @Nullable String time; /** * Additional properties to store in the {@code build-info.properties} file. Each * entry is prefixed by {@code build.} in the generated {@code build-info.properties}. */ @Parameter - private Map additionalProperties; + private @Nullable Map additionalProperties; /** * Properties that should be excluded {@code build-info.properties} file. Can be used @@ -95,7 +99,7 @@ public class BuildInfoMojo extends AbstractMojo { * {@code additionalProperties}. */ @Parameter - private List excludeInfoProperties; + private @Nullable List excludeInfoProperties; /** * Skip the execution. @@ -138,11 +142,11 @@ public class BuildInfoMojo extends AbstractMojo { return new ProjectDetails(group, artifact, version, name, time, additionalProperties); } - private T getIfNotExcluded(String name, T value) { + private @Nullable T getIfNotExcluded(String name, @Nullable T value) { return (this.excludeInfoProperties == null || !this.excludeInfoProperties.contains(name)) ? value : null; } - private Map applyExclusions(Map source) { + private @Nullable Map applyExclusions(@Nullable Map source) { if (source == null || this.excludeInfoProperties == null) { return source; } @@ -151,7 +155,7 @@ public class BuildInfoMojo extends AbstractMojo { return result; } - private Instant getBuildTime() { + private @Nullable Instant getBuildTime() { if (this.time == null || this.time.isEmpty()) { Date startTime = this.session.getRequest().getStartTime(); return (startTime != null) ? startTime.toInstant() : Instant.now(); diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CacheInfo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CacheInfo.java index a35903071fd..98d23db744b 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CacheInfo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CacheInfo.java @@ -16,6 +16,8 @@ package org.springframework.boot.maven; +import org.jspecify.annotations.Nullable; + import org.springframework.boot.buildpack.platform.build.Cache; import org.springframework.util.Assert; @@ -27,7 +29,7 @@ import org.springframework.util.Assert; */ public class CacheInfo { - private Cache cache; + private @Nullable Cache cache; public CacheInfo() { } @@ -38,24 +40,32 @@ public class CacheInfo { public void setVolume(VolumeCacheInfo info) { Assert.state(this.cache == null, "Each image building cache can be configured only once"); - this.cache = Cache.volume(info.getName()); + String name = info.getName(); + Assert.state(name != null, "'name' must not be null"); + this.cache = Cache.volume(name); } public void setBind(BindCacheInfo info) { Assert.state(this.cache == null, "Each image building cache can be configured only once"); - this.cache = Cache.bind(info.getSource()); + String source = info.getSource(); + Assert.state(source != null, "'source' must not be null"); + this.cache = Cache.bind(source); } - Cache asCache() { + @Nullable Cache asCache() { return this.cache; } static CacheInfo fromVolume(VolumeCacheInfo cacheInfo) { - return new CacheInfo(Cache.volume(cacheInfo.getName())); + String name = cacheInfo.getName(); + Assert.state(name != null, "'name' must not be null"); + return new CacheInfo(Cache.volume(name)); } static CacheInfo fromBind(BindCacheInfo cacheInfo) { - return new CacheInfo(Cache.bind(cacheInfo.getSource())); + String source = cacheInfo.getSource(); + Assert.state(source != null, "'source' must not be null"); + return new CacheInfo(Cache.bind(source)); } /** @@ -63,7 +73,7 @@ public class CacheInfo { */ public static class VolumeCacheInfo { - private String name; + private @Nullable String name; public VolumeCacheInfo() { } @@ -72,11 +82,11 @@ public class CacheInfo { this.name = name; } - public String getName() { + public @Nullable String getName() { return this.name; } - void setName(String name) { + void setName(@Nullable String name) { this.name = name; } @@ -87,7 +97,7 @@ public class CacheInfo { */ public static class BindCacheInfo { - private String source; + private @Nullable String source; public BindCacheInfo() { } @@ -96,11 +106,11 @@ public class CacheInfo { this.source = name; } - public String getSource() { + public @Nullable String getSource() { return this.source; } - void setSource(String source) { + void setSource(@Nullable String source) { this.source = source; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CommandLineBuilder.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CommandLineBuilder.java index 8afb7287cd4..687d1bcab77 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CommandLineBuilder.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CommandLineBuilder.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + /** * Helper class to build the command-line arguments of a java process. * @@ -53,7 +55,7 @@ final class CommandLineBuilder { return this; } - CommandLineBuilder withSystemProperties(Map systemProperties) { + CommandLineBuilder withSystemProperties(@Nullable Map systemProperties) { if (systemProperties != null) { systemProperties.entrySet() .stream() @@ -93,7 +95,7 @@ final class CommandLineBuilder { */ private static final class SystemPropertyFormatter { - static String format(String key, String value) { + static String format(@Nullable String key, @Nullable String value) { if (key == null) { return ""; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java index f1c17b53393..5bc0fe8f513 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/CustomLayersProvider.java @@ -29,6 +29,7 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; +import org.jspecify.annotations.Nullable; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -157,7 +158,7 @@ class CustomLayersProvider { return patterns; } - private Element getChildElement(Element element, String tagName) { + private @Nullable Element getChildElement(Element element, String tagName) { NodeList nodes = element.getElementsByTagName(tagName); if (nodes.getLength() == 0) { return null; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java index f86c1cbea5c..e3403dbd038 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Docker.java @@ -17,9 +17,11 @@ package org.springframework.boot.maven; import org.apache.maven.plugin.logging.Log; +import org.jspecify.annotations.Nullable; import org.springframework.boot.buildpack.platform.build.BuilderDockerConfiguration; import org.springframework.boot.buildpack.platform.docker.configuration.DockerRegistryAuthentication; +import org.springframework.util.Assert; /** * Docker configuration options. @@ -30,29 +32,29 @@ import org.springframework.boot.buildpack.platform.docker.configuration.DockerRe */ public class Docker { - private String host; + private @Nullable String host; - private String context; + private @Nullable String context; private boolean tlsVerify; - private String certPath; + private @Nullable String certPath; private boolean bindHostToBuilder; - private DockerRegistry builderRegistry; + private @Nullable DockerRegistry builderRegistry; - private DockerRegistry publishRegistry; + private @Nullable DockerRegistry publishRegistry; /** * The host address of the Docker daemon. * @return the Docker host */ - public String getHost() { + public @Nullable String getHost() { return this.host; } - void setHost(String host) { + void setHost(@Nullable String host) { this.host = host; } @@ -60,11 +62,11 @@ public class Docker { * The Docker context to use to retrieve host configuration. * @return the Docker context */ - public String getContext() { + public @Nullable String getContext() { return this.context; } - public void setContext(String context) { + public void setContext(@Nullable String context) { this.context = context; } @@ -85,11 +87,11 @@ public class Docker { * Docker daemon. * @return the TLS certificate path */ - public String getCertPath() { + public @Nullable String getCertPath() { return this.certPath; } - void setCertPath(String certPath) { + void setCertPath(@Nullable String certPath) { this.certPath = certPath; } @@ -109,7 +111,7 @@ public class Docker { * Configuration of the Docker registry where builder and run images are stored. * @return the registry configuration */ - DockerRegistry getBuilderRegistry() { + @Nullable DockerRegistry getBuilderRegistry() { return this.builderRegistry; } @@ -118,7 +120,7 @@ public class Docker { * registry. * @param builderRegistry the registry configuration */ - void setBuilderRegistry(DockerRegistry builderRegistry) { + void setBuilderRegistry(@Nullable DockerRegistry builderRegistry) { this.builderRegistry = builderRegistry; } @@ -126,7 +128,7 @@ public class Docker { * Configuration of the Docker registry where the generated image will be published. * @return the registry configuration */ - DockerRegistry getPublishRegistry() { + @Nullable DockerRegistry getPublishRegistry() { return this.publishRegistry; } @@ -135,7 +137,7 @@ public class Docker { * registry. * @param builderRegistry the registry configuration */ - void setPublishRegistry(DockerRegistry builderRegistry) { + void setPublishRegistry(@Nullable DockerRegistry builderRegistry) { this.publishRegistry = builderRegistry; } @@ -189,17 +191,22 @@ public class Docker { getRegistryAuthentication("publish", this.publishRegistry, authentication)); } - private DockerRegistryAuthentication getRegistryAuthentication(String type, DockerRegistry registry, + private DockerRegistryAuthentication getRegistryAuthentication(String type, @Nullable DockerRegistry registry, DockerRegistryAuthentication fallback) { if (registry == null || registry.isEmpty()) { return fallback; } if (registry.hasTokenAuth() && !registry.hasUserAuth()) { - return DockerRegistryAuthentication.token(registry.getToken()); + String token = registry.getToken(); + Assert.state(token != null, "'token' must not be null"); + return DockerRegistryAuthentication.token(token); } if (registry.hasUserAuth() && !registry.hasTokenAuth()) { - return DockerRegistryAuthentication.user(registry.getUsername(), registry.getPassword(), registry.getUrl(), - registry.getEmail()); + String username = registry.getUsername(); + String password = registry.getPassword(); + Assert.state(username != null, "'username' must not be null"); + Assert.state(password != null, "'password' must not be null"); + return DockerRegistryAuthentication.user(username, password, registry.getUrl(), registry.getEmail()); } throw new IllegalArgumentException("Invalid Docker " + type + " registry configuration, either token or username/password must be provided"); @@ -210,15 +217,15 @@ public class Docker { */ public static class DockerRegistry { - private String username; + private @Nullable String username; - private String password; + private @Nullable String password; - private String url; + private @Nullable String url; - private String email; + private @Nullable String email; - private String token; + private @Nullable String token; public DockerRegistry() { } @@ -238,11 +245,11 @@ public class Docker { * The username that will be used for user authentication to the registry. * @return the username */ - public String getUsername() { + public @Nullable String getUsername() { return this.username; } - void setUsername(String username) { + void setUsername(@Nullable String username) { this.username = username; } @@ -250,11 +257,11 @@ public class Docker { * The password that will be used for user authentication to the registry. * @return the password */ - public String getPassword() { + public @Nullable String getPassword() { return this.password; } - void setPassword(String password) { + void setPassword(@Nullable String password) { this.password = password; } @@ -262,11 +269,11 @@ public class Docker { * The email address that will be used for user authentication to the registry. * @return the email address */ - public String getEmail() { + public @Nullable String getEmail() { return this.email; } - void setEmail(String email) { + void setEmail(@Nullable String email) { this.email = email; } @@ -274,11 +281,11 @@ public class Docker { * The URL of the registry. * @return the registry URL */ - String getUrl() { + @Nullable String getUrl() { return this.url; } - void setUrl(String url) { + void setUrl(@Nullable String url) { this.url = url; } @@ -286,11 +293,11 @@ public class Docker { * The token that will be used for token authentication to the registry. * @return the authentication token */ - public String getToken() { + public @Nullable String getToken() { return this.token; } - void setToken(String token) { + void setToken(@Nullable String token) { this.token = token; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/EnvVariables.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/EnvVariables.java index a26f04c7f7a..0a2b458d3f8 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/EnvVariables.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/EnvVariables.java @@ -22,6 +22,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; + /** * Utility class for working with Env variables. * @@ -31,11 +33,11 @@ class EnvVariables { private final Map variables; - EnvVariables(Map variables) { + EnvVariables(@Nullable Map variables) { this.variables = parseEnvVariables(variables); } - private static Map parseEnvVariables(Map args) { + private static Map parseEnvVariables(@Nullable Map args) { if (args == null || args.isEmpty()) { return Collections.emptyMap(); } @@ -48,7 +50,7 @@ class EnvVariables { return result; } - private static String getValue(String value) { + private static String getValue(@Nullable String value) { return (value != null) ? value : ""; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java index 5960233aece..0324c8791fb 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java @@ -17,6 +17,7 @@ package org.springframework.boot.maven; import org.apache.maven.plugins.annotations.Parameter; +import org.jspecify.annotations.Nullable; import org.springframework.util.Assert; @@ -33,19 +34,21 @@ public abstract class FilterableDependency { * The groupId of the artifact to exclude. */ @Parameter(required = true) + @SuppressWarnings("NullAway.Init") private String groupId; /** * The artifactId of the artifact to exclude. */ @Parameter(required = true) + @SuppressWarnings("NullAway.Init") private String artifactId; /** * The classifier of the artifact to exclude. */ @Parameter - private String classifier; + private @Nullable String classifier; String getGroupId() { return this.groupId; @@ -63,11 +66,11 @@ public abstract class FilterableDependency { this.artifactId = artifactId; } - String getClassifier() { + @Nullable String getClassifier() { return this.classifier; } - void setClassifier(String classifier) { + void setClassifier(@Nullable String classifier) { this.classifier = classifier; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Image.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Image.java index 96112493508..42e7f7ca4cd 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Image.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Image.java @@ -21,15 +21,18 @@ import java.util.Map; import java.util.function.Function; import org.apache.maven.artifact.Artifact; +import org.jspecify.annotations.Nullable; import org.springframework.boot.buildpack.platform.build.BuildRequest; import org.springframework.boot.buildpack.platform.build.BuildpackReference; +import org.springframework.boot.buildpack.platform.build.Cache; import org.springframework.boot.buildpack.platform.build.PullPolicy; import org.springframework.boot.buildpack.platform.docker.type.Binding; import org.springframework.boot.buildpack.platform.docker.type.ImageName; import org.springframework.boot.buildpack.platform.docker.type.ImageReference; import org.springframework.boot.buildpack.platform.io.Owner; import org.springframework.boot.buildpack.platform.io.TarArchive; +import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -45,55 +48,55 @@ import org.springframework.util.StringUtils; */ public class Image { - String name; + @Nullable String name; - String builder; + @Nullable String builder; - Boolean trustBuilder; + @Nullable Boolean trustBuilder; - String runImage; + @Nullable String runImage; - Map env; + @Nullable Map env; - Boolean cleanCache; + @Nullable Boolean cleanCache; boolean verboseLogging; - PullPolicy pullPolicy; + @Nullable PullPolicy pullPolicy; - Boolean publish; + @Nullable Boolean publish; - List buildpacks; + @Nullable List buildpacks; - List bindings; + @Nullable List bindings; - String network; + @Nullable String network; - List tags; + @Nullable List tags; - CacheInfo buildWorkspace; + @Nullable CacheInfo buildWorkspace; - CacheInfo buildCache; + @Nullable CacheInfo buildCache; - CacheInfo launchCache; + @Nullable CacheInfo launchCache; - String createdDate; + @Nullable String createdDate; - String applicationDirectory; + @Nullable String applicationDirectory; - List securityOptions; + @Nullable List securityOptions; - String imagePlatform; + @Nullable String imagePlatform; /** * The name of the created image. * @return the image name */ - public String getName() { + public @Nullable String getName() { return this.name; } - void setName(String name) { + void setName(@Nullable String name) { this.name = name; } @@ -101,11 +104,11 @@ public class Image { * The name of the builder image to use to create the image. * @return the builder image name */ - public String getBuilder() { + public @Nullable String getBuilder() { return this.builder; } - void setBuilder(String builder) { + void setBuilder(@Nullable String builder) { this.builder = builder; } @@ -113,11 +116,11 @@ public class Image { * If the builder should be treated as trusted. * @return {@code true} if the builder should be treated as trusted */ - public Boolean getTrustBuilder() { + public @Nullable Boolean getTrustBuilder() { return this.trustBuilder; } - void setTrustBuilder(Boolean trustBuilder) { + void setTrustBuilder(@Nullable Boolean trustBuilder) { this.trustBuilder = trustBuilder; } @@ -125,11 +128,11 @@ public class Image { * The name of the run image to use to create the image. * @return the builder image name */ - public String getRunImage() { + public @Nullable String getRunImage() { return this.runImage; } - void setRunImage(String runImage) { + void setRunImage(@Nullable String runImage) { this.runImage = runImage; } @@ -137,7 +140,7 @@ public class Image { * Environment properties that should be passed to the builder. * @return the environment properties */ - public Map getEnv() { + public @Nullable Map getEnv() { return this.env; } @@ -145,11 +148,11 @@ public class Image { * If the cache should be cleaned before building. * @return {@code true} if the cache should be cleaned */ - public Boolean getCleanCache() { + public @Nullable Boolean getCleanCache() { return this.cleanCache; } - void setCleanCache(Boolean cleanCache) { + void setCleanCache(@Nullable Boolean cleanCache) { this.cleanCache = cleanCache; } @@ -165,11 +168,11 @@ public class Image { * If images should be pulled from a remote repository during image build. * @return the pull policy */ - public PullPolicy getPullPolicy() { + public @Nullable PullPolicy getPullPolicy() { return this.pullPolicy; } - void setPullPolicy(PullPolicy pullPolicy) { + void setPullPolicy(@Nullable PullPolicy pullPolicy) { this.pullPolicy = pullPolicy; } @@ -177,11 +180,11 @@ public class Image { * If the built image should be pushed to a registry. * @return {@code true} if the image should be published */ - public Boolean getPublish() { + public @Nullable Boolean getPublish() { return this.publish; } - void setPublish(Boolean publish) { + void setPublish(@Nullable Boolean publish) { this.publish = publish; } @@ -189,11 +192,11 @@ public class Image { * Returns the network the build container will connect to. * @return the network */ - public String getNetwork() { + public @Nullable String getNetwork() { return this.network; } - public void setNetwork(String network) { + public void setNetwork(@Nullable String network) { this.network = network; } @@ -201,11 +204,11 @@ public class Image { * Returns the created date for the image. * @return the created date */ - public String getCreatedDate() { + public @Nullable String getCreatedDate() { return this.createdDate; } - public void setCreatedDate(String createdDate) { + public void setCreatedDate(@Nullable String createdDate) { this.createdDate = createdDate; } @@ -213,11 +216,11 @@ public class Image { * Returns the application content directory for the image. * @return the application directory */ - public String getApplicationDirectory() { + public @Nullable String getApplicationDirectory() { return this.applicationDirectory; } - public void setApplicationDirectory(String applicationDirectory) { + public void setApplicationDirectory(@Nullable String applicationDirectory) { this.applicationDirectory = applicationDirectory; } @@ -227,11 +230,11 @@ public class Image { * operating system and architecture. * @return the image platform */ - public String getImagePlatform() { + public @Nullable String getImagePlatform() { return this.imagePlatform; } - public void setImagePlatform(String imagePlatform) { + public void setImagePlatform(@Nullable String imagePlatform) { this.imagePlatform = imagePlatform; } @@ -281,13 +284,19 @@ public class Image { request = request.withTags(this.tags.stream().map(ImageReference::of).toList()); } if (this.buildWorkspace != null) { - request = request.withBuildWorkspace(this.buildWorkspace.asCache()); + Cache cache = this.buildWorkspace.asCache(); + Assert.state(cache != null, "'cache' must not be null"); + request = request.withBuildWorkspace(cache); } if (this.buildCache != null) { - request = request.withBuildCache(this.buildCache.asCache()); + Cache cache = this.buildCache.asCache(); + Assert.state(cache != null, "'cache' must not be null"); + request = request.withBuildCache(cache); } if (this.launchCache != null) { - request = request.withLaunchCache(this.launchCache.asCache()); + Cache cache = this.launchCache.asCache(); + Assert.state(cache != null, "'cache' must not be null"); + request = request.withLaunchCache(cache); } if (StringUtils.hasText(this.createdDate)) { request = request.withCreatedDate(this.createdDate); diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaCompilerPluginConfiguration.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaCompilerPluginConfiguration.java index 43612027a74..33e8f0f8dd8 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaCompilerPluginConfiguration.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaCompilerPluginConfiguration.java @@ -21,6 +21,9 @@ import java.util.Arrays; import org.apache.maven.model.Plugin; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.jspecify.annotations.Nullable; + +import org.springframework.lang.Contract; /** * Provides access to the Maven Java Compiler plugin configuration. @@ -35,7 +38,7 @@ class JavaCompilerPluginConfiguration { this.project = project; } - String getSourceMajorVersion() { + @Nullable String getSourceMajorVersion() { String version = getConfigurationValue("source"); if (version == null) { @@ -45,7 +48,7 @@ class JavaCompilerPluginConfiguration { return majorVersionFor(version); } - String getTargetMajorVersion() { + @Nullable String getTargetMajorVersion() { String version = getConfigurationValue("target"); if (version == null) { @@ -55,7 +58,7 @@ class JavaCompilerPluginConfiguration { return majorVersionFor(version); } - String getReleaseVersion() { + @Nullable String getReleaseVersion() { String version = getConfigurationValue("release"); if (version == null) { @@ -65,7 +68,7 @@ class JavaCompilerPluginConfiguration { return majorVersionFor(version); } - private String getConfigurationValue(String propertyName) { + private @Nullable String getConfigurationValue(String propertyName) { Plugin plugin = this.project.getPlugin("org.apache.maven.plugins:maven-compiler-plugin"); if (plugin != null) { Object pluginConfiguration = plugin.getConfiguration(); @@ -76,14 +79,14 @@ class JavaCompilerPluginConfiguration { return null; } - private String getPropertyValue(String propertyName) { + private @Nullable String getPropertyValue(String propertyName) { if (this.project.getProperties().containsKey(propertyName)) { return this.project.getProperties().get(propertyName).toString(); } return null; } - private String getNodeValue(Xpp3Dom dom, String... childNames) { + private @Nullable String getNodeValue(Xpp3Dom dom, String... childNames) { Xpp3Dom childNode = dom.getChild(childNames[0]); if (childNode == null) { @@ -97,7 +100,8 @@ class JavaCompilerPluginConfiguration { return childNode.getValue(); } - private String majorVersionFor(String version) { + @Contract("!null -> !null") + private @Nullable String majorVersionFor(@Nullable String version) { if (version != null && version.startsWith("1.")) { return version.substring("1.".length()); } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaProcessExecutor.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaProcessExecutor.java index 28a019d6140..3b1d7f79327 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaProcessExecutor.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/JavaProcessExecutor.java @@ -26,6 +26,7 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.toolchain.Toolchain; import org.apache.maven.toolchain.ToolchainManager; +import org.jspecify.annotations.Nullable; import org.springframework.boot.loader.tools.JavaExecutable; import org.springframework.boot.loader.tools.RunProcess; @@ -43,14 +44,14 @@ class JavaProcessExecutor { private final ToolchainManager toolchainManager; - private final Consumer runProcessCustomizer; + private final @Nullable Consumer runProcessCustomizer; JavaProcessExecutor(MavenSession mavenSession, ToolchainManager toolchainManager) { this(mavenSession, toolchainManager, null); } private JavaProcessExecutor(MavenSession mavenSession, ToolchainManager toolchainManager, - Consumer runProcessCustomizer) { + @Nullable Consumer runProcessCustomizer) { this.mavenSession = mavenSession; this.toolchainManager = toolchainManager; this.runProcessCustomizer = runProcessCustomizer; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layers.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layers.java index 28ec52102b6..9ac86ff3b1a 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layers.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Layers.java @@ -18,6 +18,8 @@ package org.springframework.boot.maven; import java.io.File; +import org.jspecify.annotations.Nullable; + /** * Layer configuration options. * @@ -28,7 +30,7 @@ public class Layers { private boolean enabled = true; - private File configuration; + private @Nullable File configuration; /** * Whether a {@code layers.idx} file should be added to the jar. @@ -44,11 +46,11 @@ public class Layers { * {@code snapshot-dependencies} and {@code dependencies}. * @return the layers configuration file */ - public File getConfiguration() { + public @Nullable File getConfiguration() { return this.configuration; } - public void setConfiguration(File configuration) { + public void setConfiguration(@Nullable File configuration) { this.configuration = configuration; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/MavenBuildOutputTimestamp.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/MavenBuildOutputTimestamp.java index 2bf9f613fa7..8ba41302b47 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/MavenBuildOutputTimestamp.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/MavenBuildOutputTimestamp.java @@ -22,6 +22,8 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeParseException; +import org.jspecify.annotations.Nullable; + import org.springframework.util.StringUtils; /** @@ -42,13 +44,13 @@ class MavenBuildOutputTimestamp { private static final Instant DATE_MAX = Instant.parse("2099-12-31T23:59:59Z"); - private final String timestamp; + private final @Nullable String timestamp; /** * Creates a new {@link MavenBuildOutputTimestamp}. * @param timestamp timestamp or {@code null} */ - MavenBuildOutputTimestamp(String timestamp) { + MavenBuildOutputTimestamp(@Nullable String timestamp) { this.timestamp = timestamp; } @@ -59,7 +61,7 @@ class MavenBuildOutputTimestamp { * integer, or it's not within the valid range 1980-01-01T00:00:02Z to * 2099-12-31T23:59:59Z */ - FileTime toFileTime() { + @Nullable FileTime toFileTime() { Instant instant = toInstant(); if (instant == null) { return null; @@ -74,7 +76,7 @@ class MavenBuildOutputTimestamp { * integer, or it's not within the valid range 1980-01-01T00:00:02Z to * 2099-12-31T23:59:59Z */ - Instant toInstant() { + @Nullable Instant toInstant() { if (!StringUtils.hasLength(this.timestamp)) { return null; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java index c6c940e4e2b..72d38f7815a 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessAotMojo.java @@ -28,6 +28,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.toolchain.ToolchainManager; +import org.jspecify.annotations.Nullable; import org.springframework.util.ObjectUtils; @@ -50,24 +51,28 @@ public class ProcessAotMojo extends AbstractAotMojo { * the archive. */ @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) + @SuppressWarnings("NullAway.Init") private File classesDirectory; /** * Directory containing the generated sources. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/main/sources", required = true) + @SuppressWarnings("NullAway.Init") private File generatedSources; /** * Directory containing the generated resources. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/main/resources", required = true) + @SuppressWarnings("NullAway.Init") private File generatedResources; /** * Directory containing the generated classes. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/main/classes", required = true) + @SuppressWarnings("NullAway.Init") private File generatedClasses; /** @@ -75,18 +80,20 @@ public class ProcessAotMojo extends AbstractAotMojo { * the first compiled class found that contains a 'main' method will be used. */ @Parameter(property = "spring-boot.aot.main-class") - private String mainClass; + private @Nullable String mainClass; /** * Application arguments that should be taken into account for AOT processing. */ @Parameter + @SuppressWarnings("NullAway") // maven-maven-plugin can't handle annotated arrays private String[] arguments; /** * Spring profiles to take into account for AOT processing. */ @Parameter + @SuppressWarnings("NullAway") // maven-maven-plugin can't handle annotated arrays private String[] profiles; @Inject diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java index 8cf523bdf11..a9806a617b8 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ProcessTestAotMojo.java @@ -71,6 +71,7 @@ public class ProcessTestAotMojo extends AbstractAotMojo { * the archive. */ @Parameter(defaultValue = "${project.build.testOutputDirectory}", required = true) + @SuppressWarnings("NullAway.Init") private File testClassesDirectory; /** @@ -78,30 +79,35 @@ public class ProcessTestAotMojo extends AbstractAotMojo { * tests. */ @Parameter(defaultValue = "${project.build.outputDirectory}", required = true) + @SuppressWarnings("NullAway.Init") private File classesDirectory; /** * Directory containing the generated sources. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/test/sources", required = true) + @SuppressWarnings("NullAway.Init") private File generatedSources; /** * Directory containing the generated test resources. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/test/resources", required = true) + @SuppressWarnings("NullAway.Init") private File generatedResources; /** * Directory containing the generated test classes. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/test/classes", required = true) + @SuppressWarnings("NullAway.Init") private File generatedTestClasses; /** * Directory containing the generated test classes. */ @Parameter(defaultValue = "${project.build.directory}/spring-aot/main/classes", required = true) + @SuppressWarnings("NullAway.Init") private File generatedClasses; private final RepositorySystem repositorySystem; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/PropertiesMergingResourceTransformer.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/PropertiesMergingResourceTransformer.java index c324b72137d..4bfbb143211 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/PropertiesMergingResourceTransformer.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/PropertiesMergingResourceTransformer.java @@ -25,6 +25,7 @@ import java.util.jar.JarOutputStream; import org.apache.maven.plugins.shade.relocation.Relocator; import org.apache.maven.plugins.shade.resource.ReproducibleResourceTransformer; +import org.jspecify.annotations.Nullable; /** * Extension for the Maven @@ -38,7 +39,7 @@ import org.apache.maven.plugins.shade.resource.ReproducibleResourceTransformer; public class PropertiesMergingResourceTransformer implements ReproducibleResourceTransformer { // Set this in pom configuration with ... - private String resource; + private @Nullable String resource; private final Properties data = new Properties(); @@ -95,11 +96,11 @@ public class PropertiesMergingResourceTransformer implements ReproducibleResourc this.data.clear(); } - public String getResource() { + public @Nullable String getResource() { return this.resource; } - public void setResource(String resource) { + public void setResource(@Nullable String resource) { this.resource = resource; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java index 9e495ba9620..b23a2226430 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java @@ -34,6 +34,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProjectHelper; +import org.jspecify.annotations.Nullable; import org.springframework.boot.loader.tools.DefaultLaunchScript; import org.springframework.boot.loader.tools.LaunchScript; @@ -41,6 +42,7 @@ import org.springframework.boot.loader.tools.LayoutFactory; import org.springframework.boot.loader.tools.Libraries; import org.springframework.boot.loader.tools.LoaderImplementation; import org.springframework.boot.loader.tools.Repackager; +import org.springframework.lang.Contract; import org.springframework.util.StringUtils; /** @@ -67,13 +69,15 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 1.0.0 */ @Parameter(defaultValue = "${project.build.directory}", required = true) + @SuppressWarnings("NullAway.Init") private File outputDirectory; /** * Name of the generated archive. * @since 1.0.0 */ - @Parameter(defaultValue = "${project.build.finalName}", readonly = true) + @Parameter(defaultValue = "${project.build.finalName}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") private String finalName; /** @@ -96,7 +100,7 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 1.0.0 */ @Parameter - private String classifier; + private @Nullable String classifier; /** * Attach the repackaged archive to be installed into your local Maven repository or @@ -117,7 +121,7 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 1.1.0 */ @Parameter - private List requiresUnpack; + private @Nullable List requiresUnpack; /** * Make a fully executable jar for *nix machines by prepending a launch script to the @@ -139,14 +143,14 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 1.3.0 */ @Parameter - private File embeddedLaunchScript; + private @Nullable File embeddedLaunchScript; /** * Properties that should be expanded in the embedded launch script. * @since 1.3.0 */ @Parameter - private Properties embeddedLaunchScriptProperties; + private @Nullable Properties embeddedLaunchScriptProperties; /** * Timestamp for reproducible output archive entries, either formatted as ISO 8601 @@ -155,7 +159,7 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 2.3.0 */ @Parameter(defaultValue = "${project.build.outputTimestamp}") - private String outputTimestamp; + private @Nullable String outputTimestamp; /** * The type of archive (which corresponds to how the dependencies are laid out inside @@ -164,14 +168,14 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 1.0.0 */ @Parameter(property = "spring-boot.repackage.layout") - private LayoutType layout; + private @Nullable LayoutType layout; /** * The loader implementation that should be used. * @since 3.2.0 */ @Parameter - private LoaderImplementation loaderImplementation; + private @Nullable LoaderImplementation loaderImplementation; /** * The layout factory that will be used to create the executable archive if no @@ -180,7 +184,7 @@ public class RepackageMojo extends AbstractPackagerMojo { * @since 1.5.0 */ @Parameter - private LayoutFactory layoutFactory; + private @Nullable LayoutFactory layoutFactory; @Inject public RepackageMojo(MavenProjectHelper projectHelper) { @@ -193,12 +197,12 @@ public class RepackageMojo extends AbstractPackagerMojo { * is not provided */ @Override - protected LayoutType getLayout() { + protected @Nullable LayoutType getLayout() { return this.layout; } @Override - protected LoaderImplementation getLoaderImplementation() { + protected @Nullable LoaderImplementation getLoaderImplementation() { return this.loaderImplementation; } @@ -209,7 +213,7 @@ public class RepackageMojo extends AbstractPackagerMojo { * parameter is not provided */ @Override - protected LayoutFactory getLayoutFactory() { + protected @Nullable LayoutFactory getLayoutFactory() { return this.layoutFactory; } @@ -245,7 +249,7 @@ public class RepackageMojo extends AbstractPackagerMojo { updateArtifact(source, target, repackager.getBackupFile()); } - private FileTime parseOutputTimestamp() throws MojoExecutionException { + private @Nullable FileTime parseOutputTimestamp() throws MojoExecutionException { try { return new MavenBuildOutputTimestamp(this.outputTimestamp).toFileTime(); } @@ -258,7 +262,7 @@ public class RepackageMojo extends AbstractPackagerMojo { return getConfiguredPackager(() -> new Repackager(source)); } - private LaunchScript getLaunchScript() throws IOException { + private @Nullable LaunchScript getLaunchScript() throws IOException { if (this.executable || this.embeddedLaunchScript != null) { return new DefaultLaunchScript(this.embeddedLaunchScript, buildLaunchScriptProperties()); } @@ -277,7 +281,8 @@ public class RepackageMojo extends AbstractPackagerMojo { return properties; } - private String removeLineBreaks(String description) { + @Contract("!null -> !null") + private @Nullable String removeLineBreaks(@Nullable String description) { return (description != null) ? WHITE_SPACE_PATTERN.matcher(description).replaceAll(" ") : null; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunArguments.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunArguments.java index 5c256dcaf27..2f0783f138e 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunArguments.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunArguments.java @@ -22,6 +22,7 @@ import java.util.LinkedList; import java.util.Objects; import org.codehaus.plexus.util.cli.CommandLineUtils; +import org.jspecify.annotations.Nullable; /** * Parse and expose arguments specified in a single string. @@ -34,7 +35,7 @@ class RunArguments { private final Deque args = new LinkedList<>(); - RunArguments(String arguments) { + RunArguments(@Nullable String arguments) { this(parseArgs(arguments)); } @@ -52,7 +53,7 @@ class RunArguments { return this.args.toArray(new String[0]); } - private static String[] parseArgs(String arguments) { + private static String[] parseArgs(@Nullable String arguments) { if (arguments == null || arguments.trim().isEmpty()) { return NO_ARGS; } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java index c9a533c40be..8992ed3d55f 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/RunMojo.java @@ -59,7 +59,7 @@ public class RunMojo extends AbstractRunMojo { * @since 1.3.0 */ @Parameter(property = "spring-boot.run.useTestClasspath", defaultValue = "false") - private Boolean useTestClasspath; + private boolean useTestClasspath; @Inject public RunMojo(ToolchainManager toolchainManager) { diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java index 1e09838e36d..0a1c2647115 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StartMojo.java @@ -36,6 +36,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.toolchain.ToolchainManager; +import org.jspecify.annotations.Nullable; import org.springframework.boot.loader.tools.RunProcess; @@ -62,6 +63,7 @@ public class StartMojo extends AbstractRunMojo { * spring application. */ @Parameter(defaultValue = SpringApplicationAdminClient.DEFAULT_OBJECT_NAME) + @SuppressWarnings("NullAway.Init") private String jmxName; /** @@ -91,7 +93,7 @@ public class StartMojo extends AbstractRunMojo { * Flag to include the test classpath when running. */ @Parameter(property = "spring-boot.run.useTestClasspath", defaultValue = "false") - private Boolean useTestClasspath; + private boolean useTestClasspath; @Inject public StartMojo(ToolchainManager toolchainManager) { @@ -154,6 +156,7 @@ public class StartMojo extends AbstractRunMojo { } } + @SuppressWarnings("NullAway") // Lambda isn't detected with the correct nullability private void doWaitForSpringApplication(MBeanServerConnection connection) throws MojoExecutionException, MojoFailureException { final SpringApplicationAdminClient client = new SpringApplicationAdminClient(connection, this.jmxName); @@ -178,7 +181,7 @@ public class StartMojo extends AbstractRunMojo { * @return the result * @throws Exception in case of execution errors */ - public T execute(long wait, int maxAttempts, Callable callback) throws Exception { + public T execute(long wait, int maxAttempts, Callable<@Nullable T> callback) throws Exception { getLog().debug("Waiting for spring application to start..."); for (int i = 0; i < maxAttempts; i++) { T result = callback.call(); @@ -206,7 +209,7 @@ public class StartMojo extends AbstractRunMojo { return this.useTestClasspath; } - private class CreateJmxConnector implements Callable { + private class CreateJmxConnector implements Callable<@Nullable JMXConnector> { private final int port; @@ -215,7 +218,7 @@ public class StartMojo extends AbstractRunMojo { } @Override - public JMXConnector call() throws Exception { + public @Nullable JMXConnector call() throws Exception { try { return SpringApplicationAdminClient.connect(this.port); } diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java index 617de231285..d86834cd34d 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/StopMojo.java @@ -45,6 +45,7 @@ public class StopMojo extends AbstractMojo { * @since 1.4.1 */ @Parameter(defaultValue = "${project}", readonly = true, required = true) + @SuppressWarnings("NullAway.Init") private MavenProject project; /** @@ -52,6 +53,7 @@ public class StopMojo extends AbstractMojo { * application. */ @Parameter(defaultValue = SpringApplicationAdminClient.DEFAULT_OBJECT_NAME) + @SuppressWarnings("NullAway.Init") private String jmxName; /** diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/TestRunMojo.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/TestRunMojo.java index 8a9d2413c92..4be0c6185e6 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/TestRunMojo.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/TestRunMojo.java @@ -62,6 +62,7 @@ public class TestRunMojo extends AbstractRunMojo { * the application. */ @Parameter(defaultValue = "${project.build.testOutputDirectory}", required = true) + @SuppressWarnings("NullAway.Init") private File testClassesDirectory; @Inject diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/VersionExtractor.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/VersionExtractor.java index b45113076f4..13a3860795b 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/VersionExtractor.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/VersionExtractor.java @@ -24,6 +24,8 @@ import java.net.URLConnection; import java.util.jar.Attributes; import java.util.jar.JarFile; +import org.jspecify.annotations.Nullable; + /** * Extracts version information for a Class. * @@ -40,7 +42,7 @@ final class VersionExtractor { * @param cls the Class to retrieve the version for * @return the version, or {@code null} if a version can not be extracted */ - static String forClass(Class cls) { + static @Nullable String forClass(Class cls) { String implementationVersion = cls.getPackage().getImplementationVersion(); if (implementationVersion != null) { return implementationVersion; diff --git a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/package-info.java b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/package-info.java index bdb8f5ee5e2..d0829a7de76 100644 --- a/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/package-info.java +++ b/build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/package-info.java @@ -17,4 +17,7 @@ /** * Maven plugin for Spring Boot. */ +@NullMarked package org.springframework.boot.maven; + +import org.jspecify.annotations.NullMarked;