Skip to content

Commit cbf898f

Browse files
Migrate to JSpecify annotations for nullability constraints.
Closes: #4874
1 parent ecce387 commit cbf898f

File tree

422 files changed

+3143
-1761
lines changed

Some content is hidden

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

422 files changed

+3143
-1761
lines changed

spring-data-mongodb/pom.xml

+69-1
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,76 @@
353353

354354
</dependencies>
355355

356-
<build>
356+
<profiles>
357+
<profile>
358+
<id>nullaway</id>
359+
<build>
360+
<plugins>
361+
<plugin>
362+
<groupId>org.apache.maven.plugins</groupId>
363+
<artifactId>maven-compiler-plugin</artifactId>
364+
<configuration>
365+
<annotationProcessorPaths>
366+
<path>
367+
<groupId>com.querydsl</groupId>
368+
<artifactId>querydsl-apt</artifactId>
369+
<version>${querydsl}</version>
370+
</path>
371+
<path>
372+
<groupId>org.openjdk.jmh</groupId>
373+
<artifactId>jmh-generator-annprocess</artifactId>
374+
<version>${jmh}</version>
375+
</path>
376+
<path>
377+
<groupId>com.google.errorprone</groupId>
378+
<artifactId>error_prone_core</artifactId>
379+
<version>${errorprone}</version>
380+
</path>
381+
<path>
382+
<groupId>com.uber.nullaway</groupId>
383+
<artifactId>nullaway</artifactId>
384+
<version>${nullaway}</version>
385+
</path>
386+
</annotationProcessorPaths>
387+
</configuration>
388+
<executions>
389+
<execution>
390+
<id>default-compile</id>
391+
<phase>none</phase>
392+
</execution>
393+
<execution>
394+
<id>default-testCompile</id>
395+
<phase>none</phase>
396+
</execution>
397+
<execution>
398+
<id>java-compile</id>
399+
<phase>compile</phase>
400+
<goals>
401+
<goal>compile</goal>
402+
</goals>
403+
<configuration>
404+
<compilerArgs>
405+
<arg>-XDcompilePolicy=simple</arg>
406+
<arg>--should-stop=ifError=FLOW</arg>
407+
<arg>-Xplugin:ErrorProne -XepDisableAllChecks -Xep:NullAway:ERROR -XepOpt:NullAway:OnlyNullMarked=true -XepOpt:NullAway:TreatGeneratedAsUnannotated=true -XepOpt:NullAway:CustomContractAnnotations=org.springframework.lang.Contract</arg>
408+
</compilerArgs>
409+
</configuration>
410+
</execution>
411+
<execution>
412+
<id>java-test-compile</id>
413+
<phase>test-compile</phase>
414+
<goals>
415+
<goal>testCompile</goal>
416+
</goals>
417+
</execution>
418+
</executions>
419+
</plugin>
420+
</plugins>
421+
</build>
422+
</profile>
423+
</profiles>
357424

425+
<build>
358426
<plugins>
359427

360428
<plugin>

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BindableMongoExpression.java

+11-9
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
import org.bson.Document;
2121
import org.bson.codecs.DocumentCodec;
2222
import org.bson.codecs.configuration.CodecRegistry;
23+
import org.jspecify.annotations.Nullable;
2324
import org.springframework.data.mongodb.util.json.ParameterBindingDocumentCodec;
2425
import org.springframework.data.util.Lazy;
25-
import org.springframework.lang.Nullable;
26+
import org.springframework.lang.Contract;
2627
import org.springframework.util.Assert;
2728
import org.springframework.util.ObjectUtils;
2829
import org.springframework.util.StringUtils;
@@ -31,8 +32,7 @@
3132
* A {@link MongoExpression} using the {@link ParameterBindingDocumentCodec} for parsing a raw ({@literal json})
3233
* expression. The expression will be wrapped within <code>{ ... }</code> if necessary. The actual parsing and parameter
3334
* binding of placeholders like {@code ?0} is delayed upon first call on the target {@link Document} via
34-
* {@link #toDocument()}.
35-
* <br />
35+
* {@link #toDocument()}. <br />
3636
*
3737
* <pre class="code">
3838
* $toUpper : $name -> { '$toUpper' : '$name' }
@@ -55,17 +55,17 @@ public class BindableMongoExpression implements MongoExpression {
5555

5656
private final @Nullable CodecRegistryProvider codecRegistryProvider;
5757

58-
private final @Nullable Object[] args;
58+
private final Object @Nullable [] args;
5959

6060
private final Lazy<Document> target;
6161

6262
/**
6363
* Create a new instance of {@link BindableMongoExpression}.
6464
*
6565
* @param expression must not be {@literal null}.
66-
* @param args can be {@literal null}.
66+
* @param args must not be {@literal null} but may contain {@literal null} elements.
6767
*/
68-
public BindableMongoExpression(String expression, @Nullable Object[] args) {
68+
public BindableMongoExpression(String expression, Object @Nullable [] args) {
6969
this(expression, null, args);
7070
}
7171

@@ -74,10 +74,10 @@ public BindableMongoExpression(String expression, @Nullable Object[] args) {
7474
*
7575
* @param expression must not be {@literal null}.
7676
* @param codecRegistryProvider can be {@literal null}.
77-
* @param args can be {@literal null}.
77+
* @param args must not be {@literal null} but may contain {@literal null} elements.
7878
*/
7979
public BindableMongoExpression(String expression, @Nullable CodecRegistryProvider codecRegistryProvider,
80-
@Nullable Object[] args) {
80+
Object @Nullable [] args) {
8181

8282
Assert.notNull(expression, "Expression must not be null");
8383

@@ -93,6 +93,7 @@ public BindableMongoExpression(String expression, @Nullable CodecRegistryProvide
9393
* @param codecRegistry must not be {@literal null}.
9494
* @return new instance of {@link BindableMongoExpression}.
9595
*/
96+
@Contract("_ -> new")
9697
public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) {
9798
return new BindableMongoExpression(expressionString, () -> codecRegistry, args);
9899
}
@@ -103,6 +104,7 @@ public BindableMongoExpression withCodecRegistry(CodecRegistry codecRegistry) {
103104
* @param args must not be {@literal null}.
104105
* @return new instance of {@link BindableMongoExpression}.
105106
*/
107+
@Contract("_ -> new")
106108
public BindableMongoExpression bind(Object... args) {
107109
return new BindableMongoExpression(expressionString, codecRegistryProvider, args);
108110
}
@@ -139,7 +141,7 @@ private Document parse() {
139141

140142
private static String wrapJsonIfNecessary(String json) {
141143

142-
if(!StringUtils.hasText(json)) {
144+
if (!StringUtils.hasText(json)) {
143145
return json;
144146
}
145147

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/BulkOperationException.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.List;
1919

20+
import org.jspecify.annotations.Nullable;
2021
import org.springframework.dao.DataAccessException;
2122

2223
import com.mongodb.MongoBulkWriteException;
@@ -40,10 +41,10 @@ public class BulkOperationException extends DataAccessException {
4041
/**
4142
* Creates a new {@link BulkOperationException} with the given message and source {@link MongoBulkWriteException}.
4243
*
43-
* @param message must not be {@literal null}.
44+
* @param message can be {@literal null}.
4445
* @param source must not be {@literal null}.
4546
*/
46-
public BulkOperationException(String message, MongoBulkWriteException source) {
47+
public BulkOperationException(@Nullable String message, MongoBulkWriteException source) {
4748

4849
super(message, source);
4950

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/ClientSessionException.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18+
import org.jspecify.annotations.Nullable;
1819
import org.springframework.dao.NonTransientDataAccessException;
19-
import org.springframework.lang.Nullable;
2020

2121
/**
2222
* {@link NonTransientDataAccessException} specific to MongoDB {@link com.mongodb.session.ClientSession} related data

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/DefaultMongoTransactionOptionsResolver.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import java.util.Map;
1919
import java.util.Set;
2020

21-
import org.springframework.lang.Nullable;
21+
import org.jspecify.annotations.Nullable;
2222

2323
/**
2424
* Default implementation of {@link MongoTransactionOptions} using {@literal mongo:} as {@link #getLabelPrefix() label
@@ -42,9 +42,8 @@ public MongoTransactionOptions convert(Map<String, String> options) {
4242
return SimpleMongoTransactionOptions.of(options);
4343
}
4444

45-
@Nullable
4645
@Override
47-
public String getLabelPrefix() {
46+
public @Nullable String getLabelPrefix() {
4847
return PREFIX;
4948
}
5049

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoDatabaseUtils.java

+6-11
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18-
import org.springframework.lang.Nullable;
18+
import org.jspecify.annotations.Nullable;
1919
import org.springframework.transaction.support.ResourceHolderSynchronization;
2020
import org.springframework.transaction.support.TransactionSynchronization;
2121
import org.springframework.transaction.support.TransactionSynchronizationManager;
@@ -29,8 +29,7 @@
2929
/**
3030
* Helper class for managing a {@link MongoDatabase} instances via {@link MongoDatabaseFactory}. Used for obtaining
3131
* {@link ClientSession session bound} resources, such as {@link MongoDatabase} and
32-
* {@link com.mongodb.client.MongoCollection} suitable for transactional usage.
33-
* <br />
32+
* {@link com.mongodb.client.MongoCollection} suitable for transactional usage. <br />
3433
* <strong>Note:</strong> Intended for internal usage only.
3534
*
3635
* @author Christoph Strobl
@@ -42,8 +41,7 @@ public class MongoDatabaseUtils {
4241

4342
/**
4443
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory} using
45-
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
46-
* <br />
44+
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}. <br />
4745
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
4846
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
4947
*
@@ -55,8 +53,7 @@ public static MongoDatabase getDatabase(MongoDatabaseFactory factory) {
5553
}
5654

5755
/**
58-
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}.
59-
* <br />
56+
* Obtain the default {@link MongoDatabase database} form the given {@link MongoDatabaseFactory factory}. <br />
6057
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
6158
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
6259
*
@@ -70,8 +67,7 @@ public static MongoDatabase getDatabase(MongoDatabaseFactory factory, SessionSyn
7067

7168
/**
7269
* Obtain the {@link MongoDatabase database} with given name form the given {@link MongoDatabaseFactory factory} using
73-
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}.
74-
* <br />
70+
* {@link SessionSynchronization#ON_ACTUAL_TRANSACTION native session synchronization}. <br />
7571
* Registers a {@link MongoSessionSynchronization MongoDB specific transaction synchronization} within the current
7672
* {@link Thread} if {@link TransactionSynchronizationManager#isSynchronizationActive() synchronization is active}.
7773
*
@@ -139,8 +135,7 @@ public static boolean isTransactionActive(MongoDatabaseFactory dbFactory) {
139135
return resourceHolder != null && resourceHolder.hasActiveTransaction();
140136
}
141137

142-
@Nullable
143-
private static ClientSession doGetSession(MongoDatabaseFactory dbFactory,
138+
private static @Nullable ClientSession doGetSession(MongoDatabaseFactory dbFactory,
144139
SessionSynchronization sessionSynchronization) {
145140

146141
MongoResourceHolder resourceHolder = (MongoResourceHolder) TransactionSynchronizationManager.getResource(dbFactory);

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoResourceHolder.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18-
import org.springframework.lang.Nullable;
18+
import org.jspecify.annotations.Nullable;
1919
import org.springframework.transaction.TransactionDefinition;
2020
import org.springframework.transaction.support.ResourceHolderSupport;
2121

2222
import com.mongodb.client.ClientSession;
2323

2424
/**
2525
* MongoDB specific {@link ResourceHolderSupport resource holder}, wrapping a {@link ClientSession}.
26-
* {@link MongoTransactionManager} binds instances of this class to the thread.
27-
* <br />
26+
* {@link MongoTransactionManager} binds instances of this class to the thread. <br />
2827
* <strong>Note:</strong> Intended for internal usage only.
2928
*
3029
* @author Christoph Strobl

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionException.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18-
import org.springframework.lang.Nullable;
18+
import org.jspecify.annotations.Nullable;
1919

2020
/**
2121
* A specific {@link ClientSessionException} related to issues with a transaction such as aborted or non existing

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoTransactionManager.java

+12-14
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18+
import org.jspecify.annotations.Nullable;
1819
import org.springframework.beans.factory.InitializingBean;
19-
import org.springframework.lang.Nullable;
2020
import org.springframework.transaction.TransactionDefinition;
2121
import org.springframework.transaction.TransactionException;
2222
import org.springframework.transaction.TransactionSystemException;
@@ -36,19 +36,15 @@
3636

3737
/**
3838
* A {@link org.springframework.transaction.PlatformTransactionManager} implementation that manages
39-
* {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}.
40-
* <br />
41-
* Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread.
42-
* <br />
39+
* {@link ClientSession} based transactions for a single {@link MongoDatabaseFactory}. <br />
40+
* Binds a {@link ClientSession} from the specified {@link MongoDatabaseFactory} to the thread. <br />
4341
* {@link TransactionDefinition#isReadOnly() Readonly} transactions operate on a {@link ClientSession} and enable causal
4442
* consistency, and also {@link ClientSession#startTransaction() start}, {@link ClientSession#commitTransaction()
45-
* commit} or {@link ClientSession#abortTransaction() abort} a transaction.
46-
* <br />
43+
* commit} or {@link ClientSession#abortTransaction() abort} a transaction. <br />
4744
* Application code is required to retrieve the {@link com.mongodb.client.MongoDatabase} via
4845
* {@link MongoDatabaseUtils#getDatabase(MongoDatabaseFactory)} instead of a standard
4946
* {@link MongoDatabaseFactory#getMongoDatabase()} call. Spring classes such as
50-
* {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly.
51-
* <br />
47+
* {@link org.springframework.data.mongodb.core.MongoTemplate} use this strategy implicitly. <br />
5248
* By default failure of a {@literal commit} operation raises a {@link TransactionSystemException}. One may override
5349
* {@link #doCommit(MongoTransactionObject)} to implement the
5450
* <a href="https://docs.mongodb.com/manual/core/transactions/#retry-commit-operation">Retry Commit Operation</a>
@@ -80,7 +76,9 @@ public class MongoTransactionManager extends AbstractPlatformTransactionManager
8076
* @see #setTransactionSynchronization(int)
8177
*/
8278
public MongoTransactionManager() {
79+
8380
this.transactionOptionsResolver = MongoTransactionOptionsResolver.defaultResolver();
81+
this.options = MongoTransactionOptions.NONE;
8482
}
8583

8684
/**
@@ -151,7 +149,8 @@ protected void doBegin(Object transaction, TransactionDefinition definition) thr
151149
}
152150

153151
try {
154-
MongoTransactionOptions mongoTransactionOptions = transactionOptionsResolver.resolve(definition).mergeWith(options);
152+
MongoTransactionOptions mongoTransactionOptions = transactionOptionsResolver.resolve(definition)
153+
.mergeWith(options);
155154
mongoTransactionObject.startTransaction(mongoTransactionOptions.toDriverOptions());
156155
} catch (MongoException ex) {
157156
throw new TransactionSystemException(String.format("Could not start Mongo transaction for session %s.",
@@ -206,6 +205,7 @@ protected final void doCommit(DefaultTransactionStatus status) throws Transactio
206205
* By default those labels are ignored, nevertheless one might check for
207206
* {@link MongoException#UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL transient commit errors labels} and retry the the
208207
* commit. <br />
208+
*
209209
* <pre>
210210
* <code>
211211
* int retries = 3;
@@ -302,8 +302,7 @@ public void setOptions(@Nullable TransactionOptions options) {
302302
*
303303
* @return can be {@literal null}.
304304
*/
305-
@Nullable
306-
public MongoDatabaseFactory getDatabaseFactory() {
305+
public @Nullable MongoDatabaseFactory getDatabaseFactory() {
307306
return databaseFactory;
308307
}
309308

@@ -461,8 +460,7 @@ void closeSession() {
461460
}
462461
}
463462

464-
@Nullable
465-
public ClientSession getSession() {
463+
public @Nullable ClientSession getSession() {
466464
return resourceHolder != null ? resourceHolder.getSession() : null;
467465
}
468466

0 commit comments

Comments
 (0)