Skip to content

Commit 93c7661

Browse files
authored
Apply JSpecify Nullify to the Channel and AOT packages
* Apply JSpecify Nullify to the Channel and AOT packages * Adjust PR to resolve code review issues * In code segments where performance is critical remove null checks and suppress warnings. * Format code to improve readability * Cleanup some Nullable's in a couple locations Continued effort or issue: #10083 * Resolve issues identified in 2nd code review * Optimize use of originalMessage in code where performance is critical * Remove unnecessary check in remove method in AbstractMessageChannel * Correct formating
1 parent 45b4338 commit 93c7661

File tree

19 files changed

+63
-54
lines changed

19 files changed

+63
-54
lines changed

spring-integration-amqp/src/main/java/org/springframework/integration/amqp/channel/PollableAmqpChannel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ public boolean removeInterceptor(ChannelInterceptor interceptor) {
322322
}
323323

324324
@Override
325-
public @Nullable ChannelInterceptor removeInterceptor(int index) {
325+
public ChannelInterceptor removeInterceptor(int index) {
326326
ChannelInterceptor interceptor = super.removeInterceptor(index);
327327
if (interceptor instanceof ExecutorChannelInterceptor) {
328328
this.executorInterceptorsSize--;

spring-integration-core/src/main/java/org/springframework/integration/aot/CoreRuntimeHints.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import java.util.function.Supplier;
2727
import java.util.stream.Stream;
2828

29+
import org.jspecify.annotations.Nullable;
30+
2931
import org.springframework.aop.framework.AopProxyUtils;
3032
import org.springframework.aot.hint.ExecutableMode;
3133
import org.springframework.aot.hint.MemberCategory;
@@ -79,7 +81,7 @@
7981
class CoreRuntimeHints implements RuntimeHintsRegistrar {
8082

8183
@Override
82-
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
84+
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
8385
ReflectionHints reflectionHints = hints.reflection();
8486
Stream.of(
8587
GenericSelector.class,
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/**
22
* Provides classes to support Spring AOT.
33
*/
4-
@org.springframework.lang.NonNullApi
5-
@org.springframework.lang.NonNullFields
4+
@org.jspecify.annotations.NullMarked
65
package org.springframework.integration.aot;

spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractExecutorChannel.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@
5959
public abstract class AbstractExecutorChannel extends AbstractSubscribableChannel
6060
implements ExecutorChannelInterceptorAware {
6161

62-
protected Executor executor; // NOSONAR
62+
protected @Nullable Executor executor;
6363

64-
protected AbstractDispatcher dispatcher; // NOSONAR
64+
@SuppressWarnings("NullAway.Init")
65+
protected AbstractDispatcher dispatcher;
6566

66-
protected Integer maxSubscribers; // NOSONAR
67+
@Nullable
68+
protected Integer maxSubscribers;
6769

68-
protected int executorInterceptorsSize; // NOSONAR
70+
protected int executorInterceptorsSize;
6971

7072
public AbstractExecutorChannel(@Nullable Executor executor) {
7173
this.executor = executor;
@@ -117,7 +119,6 @@ public boolean removeInterceptor(ChannelInterceptor interceptor) {
117119
}
118120

119121
@Override
120-
@Nullable
121122
public ChannelInterceptor removeInterceptor(int index) {
122123
ChannelInterceptor interceptor = super.removeInterceptor(index);
123124
if (interceptor instanceof ExecutorChannelInterceptor) {
@@ -167,7 +168,7 @@ public void run() {
167168
if (!CollectionUtils.isEmpty(interceptorStack)) {
168169
triggerAfterMessageHandled(message, ex, interceptorStack);
169170
}
170-
if (ex instanceof MessagingException) { // NOSONAR
171+
if (ex instanceof MessagingException) {
171172
throw new MessagingExceptionWrapper(message, (MessagingException) ex);
172173
}
173174
String description = "Failed to handle " + message + " to " + this + " in " + messageHandler;
@@ -195,7 +196,7 @@ private Message<?> applyBeforeHandle(Message<?> message, Deque<ExecutorChannelIn
195196
logger.debug(() -> executorInterceptor.getClass().getSimpleName()
196197
+ " returned null from beforeHandle, i.e. precluding the send.");
197198
}
198-
triggerAfterMessageHandled(null, null, interceptorStack);
199+
triggerAfterMessageHandled(message, null, interceptorStack);
199200
return null;
200201
}
201202
interceptorStack.add(executorInterceptor);
@@ -204,13 +205,13 @@ private Message<?> applyBeforeHandle(Message<?> message, Deque<ExecutorChannelIn
204205
return theMessage;
205206
}
206207

207-
private void triggerAfterMessageHandled(@Nullable Message<?> message, @Nullable Exception ex,
208+
private void triggerAfterMessageHandled(Message<?> message, @Nullable Exception ex,
208209
Deque<ExecutorChannelInterceptor> interceptorStack) {
209210
Iterator<ExecutorChannelInterceptor> iterator = interceptorStack.descendingIterator();
210211
while (iterator.hasNext()) {
211212
ExecutorChannelInterceptor interceptor = iterator.next();
212213
try {
213-
interceptor.afterMessageHandled(message, AbstractExecutorChannel.this, //NOSONAR
214+
interceptor.afterMessageHandled(message, AbstractExecutorChannel.this,
214215
this.delegate.getMessageHandler(), ex);
215216
}
216217
catch (Throwable ex2) { //NOSONAR

spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractMessageChannel.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,28 +95,27 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
9595

9696
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
9797

98-
@Nullable
99-
private MessageSenderObservationConvention observationConvention;
98+
private @Nullable MessageSenderObservationConvention observationConvention;
10099

101100
private boolean shouldTrack = false;
102101

103102
private Class<?>[] datatypes = new Class<?>[0];
104103

105-
private MessageConverter messageConverter;
104+
private @Nullable MessageConverter messageConverter;
106105

107106
private boolean loggingEnabled = true;
108107

109-
private MetricsCaptor metricsCaptor;
108+
private @Nullable MetricsCaptor metricsCaptor;
110109

111-
private TimerFacade successTimer;
110+
private @Nullable TimerFacade successTimer;
112111

113-
private TimerFacade failureTimer;
112+
private @Nullable TimerFacade failureTimer;
114113

115-
private volatile String fullChannelName;
114+
private volatile @Nullable String fullChannelName;
116115

117116
private volatile boolean applicationRunning;
118117

119-
private volatile Lifecycle applicationRunningController;
118+
private volatile @Nullable Lifecycle applicationRunningController;
120119

121120
@Override
122121
public String getComponentType() {
@@ -235,7 +234,6 @@ public boolean removeInterceptor(ChannelInterceptor interceptor) {
235234
}
236235

237236
@Override
238-
@Nullable
239237
public ChannelInterceptor removeInterceptor(int index) {
240238
return this.interceptors.remove(index);
241239
}
@@ -391,16 +389,19 @@ private boolean sendWithObservation(Message<?> message, long timeout) {
391389
Boolean observe = observation.observe(() -> {
392390
Message<?> messageToSendInternal = messageToSend;
393391
if (message instanceof ErrorMessage errorMessage) {
392+
Message<?> originalMessage = errorMessage.getOriginalMessage();
394393
messageToSendInternal =
395-
new ErrorMessage(errorMessage.getPayload(),
394+
(originalMessage != null) ? new ErrorMessage(errorMessage.getPayload(),
396395
messageToSend.getHeaders(),
397-
errorMessage.getOriginalMessage());
396+
originalMessage) : new ErrorMessage(errorMessage.getPayload(),
397+
messageToSend.getHeaders());
398398
}
399399
return sendInternal(messageToSendInternal, timeout);
400400
});
401401
return Boolean.TRUE.equals(observe);
402402
}
403403

404+
@SuppressWarnings("NullAway") // Dataflow analysis limitation
404405
private boolean sendWithMetrics(Message<?> message, long timeout) {
405406
SampleFacade sample = this.metricsCaptor.start();
406407
try {
@@ -468,6 +469,7 @@ private TimerFacade sendTimer(boolean sent) {
468469
}
469470
}
470471

472+
@SuppressWarnings("NullAway") // Dataflow analysis limitation
471473
private TimerFacade buildSendTimer(boolean success, String exception) {
472474
TimerFacade timer = this.metricsCaptor.timerBuilder(SEND_TIMER_NAME)
473475
.tag("type", "channel")
@@ -676,12 +678,9 @@ public boolean remove(ChannelInterceptor interceptor) {
676678
}
677679
}
678680

679-
@Nullable
680681
public ChannelInterceptor remove(int index) {
681682
ChannelInterceptor removed = this.interceptors.remove(index);
682-
if (removed != null) {
683-
this.size--;
684-
}
683+
this.size--;
685684
return removed;
686685
}
687686

spring-integration-core/src/main/java/org/springframework/integration/channel/AbstractPollableChannel.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public abstract class AbstractPollableChannel extends AbstractMessageChannel
4545

4646
private int executorInterceptorsSize;
4747

48-
private CounterFacade receiveCounter;
48+
private @Nullable CounterFacade receiveCounter;
4949

5050
@Override
5151
public IntegrationPatternType getIntegrationPatternType() {
@@ -186,7 +186,6 @@ public boolean removeInterceptor(ChannelInterceptor interceptor) {
186186
}
187187

188188
@Override
189-
@Nullable
190189
public ChannelInterceptor removeInterceptor(int index) {
191190
ChannelInterceptor interceptor = super.removeInterceptor(index);
192191
if (interceptor instanceof ExecutorChannelInterceptor) {

spring-integration-core/src/main/java/org/springframework/integration/channel/ChannelPurger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class ChannelPurger {
4848

4949
private final QueueChannel[] channels;
5050

51-
private final MessageSelector selector;
51+
private final @Nullable MessageSelector selector;
5252

5353
public ChannelPurger(QueueChannel... channels) {
5454
this(null, channels);

spring-integration-core/src/main/java/org/springframework/integration/channel/DefaultHeaderChannelRegistry.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public class DefaultHeaderChannelRegistry extends IntegrationObjectSupport
6767

6868
private long reaperDelay;
6969

70-
private volatile ScheduledFuture<?> reaperScheduledFuture;
70+
private volatile @Nullable ScheduledFuture<?> reaperScheduledFuture;
7171

7272
private volatile boolean running;
7373

@@ -147,8 +147,9 @@ public void stop() {
147147
this.lock.lock();
148148
try {
149149
this.running = false;
150-
if (this.reaperScheduledFuture != null) {
151-
this.reaperScheduledFuture.cancel(true);
150+
ScheduledFuture<?> reaperScheduledFutureToCancel = this.reaperScheduledFuture;
151+
if (reaperScheduledFutureToCancel != null) {
152+
reaperScheduledFutureToCancel.cancel(true);
152153
this.reaperScheduledFuture = null;
153154
}
154155
this.explicitlyStopped = true;
@@ -221,8 +222,9 @@ public MessageChannel channelNameToChannel(@Nullable String name) {
221222
public void runReaper() {
222223
this.lock.lock();
223224
try {
224-
if (this.reaperScheduledFuture != null) {
225-
this.reaperScheduledFuture.cancel(true);
225+
ScheduledFuture<?> reaperScheduledFutureToCancel = this.reaperScheduledFuture;
226+
if (reaperScheduledFutureToCancel != null) {
227+
reaperScheduledFutureToCancel.cancel(true);
226228
this.reaperScheduledFuture = null;
227229
}
228230

spring-integration-core/src/main/java/org/springframework/integration/channel/DirectChannel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class DirectChannel extends AbstractSubscribableChannel {
3939

4040
private final UnicastingDispatcher dispatcher = new UnicastingDispatcher();
4141

42-
private volatile Integer maxSubscribers;
42+
private volatile @Nullable Integer maxSubscribers;
4343

4444
/**
4545
* Create a channel with default {@link RoundRobinLoadBalancingStrategy}.

spring-integration-core/src/main/java/org/springframework/integration/channel/ExecutorChannel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
*/
5050
public class ExecutorChannel extends AbstractExecutorChannel {
5151

52-
private final LoadBalancingStrategy loadBalancingStrategy;
52+
private final @Nullable LoadBalancingStrategy loadBalancingStrategy;
5353

5454
private Predicate<Exception> failoverStrategy = (exception) -> true;
5555

0 commit comments

Comments
 (0)