Skip to content

Commit d996dd4

Browse files
committed
GH-2332 - Move to jSpecify for nullability verification.
1 parent c77993b commit d996dd4

File tree

171 files changed

+560
-415
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+560
-415
lines changed

.mvn/jvm.config

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
2+
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
3+
--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
4+
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
5+
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
6+
--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
7+
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
8+
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
9+
--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
10+
--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED

pom.xml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
<artifactory-maven-plugin.version>3.6.2</artifactory-maven-plugin.version>
7373
<assertj.version>3.27.3</assertj.version>
7474
<spring-asciidoctor-backends.version>0.0.7</spring-asciidoctor-backends.version>
75+
<errorprone.version>2.36.0</errorprone.version>
7576
<evo.version>1.3</evo.version>
7677
<logback.version>1.5.18</logback.version>
7778
<jacoco>0.8.12</jacoco>
@@ -81,6 +82,7 @@
8182
<jsonpath.version>2.9.0</jsonpath.version>
8283
<junit.version>5.12.2</junit.version>
8384
<lombok.version>1.18.38</lombok.version>
85+
<nullaway.version>0.12.7</nullaway.version>
8486
<reactor-bom.version>2024.0.6</reactor-bom.version>
8587
<slf4j.version>2.0.17</slf4j.version>
8688
<spring.version>7.0.0-M5</spring.version>
@@ -149,6 +151,54 @@
149151

150152
</profile>
151153

154+
<profile>
155+
<id>nullaway</id>
156+
<build>
157+
<plugins>
158+
<plugin>
159+
<groupId>org.apache.maven.plugins</groupId>
160+
<artifactId>maven-compiler-plugin</artifactId>
161+
<configuration>
162+
<showWarnings>true</showWarnings>
163+
164+
</configuration>
165+
<executions>
166+
<execution>
167+
<id>default-compile</id>
168+
<phase>none</phase>
169+
</execution>
170+
<execution>
171+
<id>java-compile</id>
172+
<phase>compile</phase>
173+
<goals>
174+
<goal>compile</goal>
175+
</goals>
176+
<configuration>
177+
<annotationProcessorPaths>
178+
<path>
179+
<groupId>com.google.errorprone</groupId>
180+
<artifactId>error_prone_core</artifactId>
181+
<version>${errorprone.version}</version>
182+
</path>
183+
<path>
184+
<groupId>com.uber.nullaway</groupId>
185+
<artifactId>nullaway</artifactId>
186+
<version>${nullaway.version}</version>
187+
</path>
188+
</annotationProcessorPaths>
189+
<compilerArgs>
190+
<arg>-XDcompilePolicy=simple</arg>
191+
<arg>--should-stop=ifError=FLOW</arg>
192+
<arg>-Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract</arg>
193+
</compilerArgs>
194+
</configuration>
195+
</execution>
196+
</executions>
197+
</plugin>
198+
</plugins>
199+
</build>
200+
</profile>
201+
152202
<profile>
153203
<id>artifactory</id>
154204
<properties>
@@ -469,6 +519,11 @@
469519
<artifactId>kotlinx-coroutines-reactor</artifactId>
470520
<optional>true</optional>
471521
</dependency>
522+
<dependency>
523+
<groupId>org.jspecify</groupId>
524+
<artifactId>jspecify</artifactId>
525+
<version>1.0.0</version>
526+
</dependency>
472527
<dependency>
473528
<groupId>org.jetbrains.kotlin</groupId>
474529
<artifactId>kotlin-test</artifactId>

src/main/java/org/springframework/hateoas/Affordance.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
import java.util.Map;
2020
import java.util.Objects;
2121

22+
import org.jspecify.annotations.Nullable;
2223
import org.springframework.http.MediaType;
23-
import org.springframework.lang.Nullable;
24+
import org.springframework.util.Assert;
2425

2526
/**
2627
* Hold the {@link AffordanceModel}s for all supported media types.
@@ -42,15 +43,32 @@ public Affordance(Map<MediaType, AffordanceModel> models) {
4243
/**
4344
* Look up the {@link AffordanceModel} for the requested {@link MediaType}.
4445
*
45-
* @param mediaType
46-
* @return
46+
* @param mediaType must not be {@literal null}.
47+
* @return can be {@literal null}.
4748
*/
4849
@Nullable
4950
@SuppressWarnings("unchecked")
5051
public <T extends AffordanceModel> T getAffordanceModel(MediaType mediaType) {
5152
return (T) this.models.get(mediaType);
5253
}
5354

55+
/**
56+
* Look up the {@link AffordanceModel} for the requested {@link MediaType}.
57+
*
58+
* @param mediaType must not be {@literal null}.
59+
* @return will never be {@literal null}.
60+
* @since 3.0
61+
*/
62+
@SuppressWarnings("unchecked")
63+
public <T extends AffordanceModel> T getRequiredAffordanceModel(MediaType mediaType) {
64+
65+
var result = getAffordanceModel(mediaType);
66+
67+
Assert.notNull(result, () -> "No affordance model found for %s!".formatted(mediaType));
68+
69+
return (T) result;
70+
}
71+
5472
/*
5573
* (non-Javadoc)
5674
* @see java.lang.Iterable#iterator()

src/main/java/org/springframework/hateoas/AffordanceModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
import java.util.stream.Collectors;
2525
import java.util.stream.Stream;
2626

27+
import org.jspecify.annotations.Nullable;
2728
import org.springframework.core.ResolvableType;
2829
import org.springframework.http.HttpMethod;
2930
import org.springframework.http.MediaType;
30-
import org.springframework.lang.Nullable;
3131
import org.springframework.util.Assert;
3232

3333
/**

src/main/java/org/springframework/hateoas/CollectionModel.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
import java.util.Iterator;
2323
import java.util.Objects;
2424

25+
import org.jspecify.annotations.NonNull;
26+
import org.jspecify.annotations.Nullable;
2527
import org.springframework.core.ParameterizedTypeReference;
2628
import org.springframework.core.ResolvableType;
2729
import org.springframework.core.ResolvableTypeProvider;
28-
import org.springframework.lang.NonNull;
29-
import org.springframework.lang.Nullable;
3030
import org.springframework.util.Assert;
3131
import org.springframework.util.ClassUtils;
3232

@@ -44,7 +44,7 @@ public class CollectionModel<T> extends RepresentationModel<CollectionModel<T>>
4444

4545
private final Collection<T> content;
4646
private final @Nullable ResolvableType fallbackType;
47-
private ResolvableType fullType;
47+
private @Nullable ResolvableType fullType;
4848

4949
/**
5050
* Creates an empty {@link CollectionModel} instance.

src/main/java/org/springframework/hateoas/EntityModel.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
import java.util.Collections;
2222
import java.util.LinkedHashMap;
2323
import java.util.Map;
24+
import java.util.Objects;
2425

25-
import org.springframework.lang.NonNull;
26-
import org.springframework.lang.Nullable;
26+
import org.jspecify.annotations.NonNull;
27+
import org.jspecify.annotations.Nullable;
2728
import org.springframework.util.Assert;
2829

2930
import com.fasterxml.jackson.annotation.JsonAnyGetter;
@@ -50,7 +51,7 @@
5051
*/
5152
public class EntityModel<T> extends RepresentationModel<EntityModel<T>> {
5253

53-
private T content;
54+
private @Nullable T content;
5455

5556
/**
5657
* Creates an empty {@link EntityModel}.
@@ -118,19 +119,17 @@ public static <T> EntityModel<T> of(T content, Iterable<Link> links) {
118119
*
119120
* @return the content
120121
*/
121-
@Nullable
122122
@JsonUnwrapped
123123
@JsonSerialize(using = MapSuppressingUnwrappingSerializer.class)
124124
public T getContent() {
125-
return content;
125+
return Objects.requireNonNull(content);
126126
}
127127

128128
// Hacks to allow deserialization into an EntityModel<Map<String, Object>>
129129

130-
@Nullable
131130
@JsonAnyGetter
132131
@SuppressWarnings("unchecked")
133-
private Map<String, Object> getMapContent() {
132+
private @Nullable Map<String, Object> getMapContent() {
134133
return Map.class.isInstance(content) ? (Map<String, Object>) content : null;
135134
}
136135

src/main/java/org/springframework/hateoas/InputType.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import java.lang.annotation.Retention;
2323
import java.lang.annotation.Target;
2424

25-
import org.springframework.hateoas.mediatype.html.HtmlInputType;
26-
2725
/**
2826
* Annotation to declare a dedicated input type for a property of an representation model. Input types are usually
2927
* derived from the property's type or JSR-303 validation annotations. Use this annotation to override the type.

src/main/java/org/springframework/hateoas/Link.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import java.util.Map;
2424
import java.util.Objects;
2525

26-
import org.springframework.lang.Nullable;
26+
import org.jspecify.annotations.Nullable;
2727
import org.springframework.util.Assert;
2828

2929
import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -184,7 +184,10 @@ public static Link of(UriTemplate template, LinkRelation relation) {
184184
* Empty constructor required by the marshaling framework.
185185
*/
186186
protected Link() {
187+
187188
this.affordances = new ArrayList<>();
189+
this.rel = LinkRelation.of("__synthetic__");
190+
this.href = "__synthetic__";
188191
}
189192

190193
/**

src/main/java/org/springframework/hateoas/Links.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.util.stream.Stream;
2929
import java.util.stream.StreamSupport;
3030

31-
import org.springframework.lang.Nullable;
31+
import org.jspecify.annotations.Nullable;
3232
import org.springframework.util.Assert;
3333
import org.springframework.util.StringUtils;
3434

src/main/java/org/springframework/hateoas/NonComposite.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import java.lang.annotation.Retention;
2222
import java.lang.annotation.Target;
2323

24-
import org.springframework.web.bind.annotation.RequestParam;
25-
2624
/**
2725
* Annotation to be used in combination with {@link RequestParam} to indicate that collection based values are supposed
2826
* to be rendered as non-composite values, i.e. like {@code param=value1,value2,value3} rather than

0 commit comments

Comments
 (0)