Skip to content

Commit f989e48

Browse files
committed
jspecify nullability changes in core and support packages
Kotlin related docs code changes spring-projects#3762 Signed-off-by: Soby Chacko <[email protected]>
1 parent 85aa161 commit f989e48

16 files changed

+119
-90
lines changed

Diff for: spring-kafka-docs/src/main/kotlin/org/springframework/kafka/kdocs/requestreply/Application.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ class Application {
6363
}
6464

6565
@Bean
66-
fun kafkaTemplate(pf: ProducerFactory<*, *>?) = KafkaTemplate(pf)
66+
fun <K : Any, V : Any> kafkaTemplate(pf: ProducerFactory<K, V>?): KafkaTemplate<K, V> {
67+
return KafkaTemplate<K, V>(pf!!)
68+
}
6769

6870
// tag::beans[]
6971
@Bean
@@ -75,7 +77,7 @@ class Application {
7577
replyContainer.containerProperties.groupId = "request.replies"
7678
val template = ReplyingKafkaTemplate<String, String, String>(pf, replyContainer)
7779
template.messageConverter = ByteArrayJsonMessageConverter()
78-
template.defaultTopic = "requests"
80+
template.setDefaultTopic("requests")
7981
return template
8082
}
8183
// end::beans[]

Diff for: spring-kafka-docs/src/main/kotlin/org/springframework/kafka/kdocs/started/producer/Application.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2021 the original author or authors.
2+
* Copyright 2021-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,9 +38,9 @@ class Application {
3838
fun topic() = NewTopic("topic1", 10, 1)
3939

4040
@Bean
41-
fun runner(template: KafkaTemplate<String?, String?>) =
41+
fun runner(template: KafkaTemplate<String, String>) =
4242
ApplicationRunner { template.send("topic1", "test") }
43-
43+
4444
companion object {
4545
@JvmStatic
4646
fun main(args: Array<String>) = runApplication<Application>(*args)

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/ConsumerFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ default void consumerAdded(String id, Consumer<K, V> consumer) {
242242
* period).
243243
* @param consumer the consumer.
244244
*/
245-
default void consumerRemoved(String id, Consumer<K, V> consumer) {
245+
default void consumerRemoved(@Nullable String id, Consumer<K, V> consumer) {
246246
}
247247

248248
}

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/DefaultKafkaConsumerFactory.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Iterator;
2525
import java.util.List;
2626
import java.util.Map;
27+
import java.util.Objects;
2728
import java.util.Optional;
2829
import java.util.Properties;
2930
import java.util.Set;
@@ -87,15 +88,15 @@ public class DefaultKafkaConsumerFactory<K, V> extends KafkaResourceFactory
8788

8889
private final List<ConsumerPostProcessor<K, V>> postProcessors = new ArrayList<>();
8990

90-
private Supplier<Deserializer<K>> keyDeserializerSupplier;
91+
private @Nullable Supplier<Deserializer<K>> keyDeserializerSupplier;
9192

92-
private Supplier<Deserializer<V>> valueDeserializerSupplier;
93+
private @Nullable Supplier<Deserializer<V>> valueDeserializerSupplier;
9394

9495
private String beanName = "not.managed.by.Spring";
9596

9697
private boolean configureDeserializers = true;
9798

98-
private ApplicationContext applicationContext;
99+
private @Nullable ApplicationContext applicationContext;
99100

100101
/**
101102
* Construct a factory with the provided configuration.
@@ -245,12 +246,12 @@ public Map<String, Object> getConfigurationProperties() {
245246

246247
@Override
247248
public Deserializer<K> getKeyDeserializer() {
248-
return this.keyDeserializerSupplier.get();
249+
return Objects.requireNonNull(this.keyDeserializerSupplier).get();
249250
}
250251

251252
@Override
252253
public Deserializer<V> getValueDeserializer() {
253-
return this.valueDeserializerSupplier.get();
254+
return Objects.requireNonNull(this.valueDeserializerSupplier).get();
254255
}
255256

256257
/**
@@ -492,7 +493,7 @@ private Deserializer<V> valueDeserializer(Map<String, Object> configs) {
492493

493494
protected class ExtendedKafkaConsumer extends KafkaConsumer<K, V> {
494495

495-
private String idForListeners;
496+
private @Nullable String idForListeners;
496497

497498
protected ExtendedKafkaConsumer(Map<String, Object> configProps) {
498499
super(configProps, keyDeserializer(configProps), valueDeserializer(configProps));

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/DefaultKafkaProducerFactory.java

+30-22
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,17 @@ public class DefaultKafkaProducerFactory<K, V> extends KafkaResourceFactory
142142

143143
private TransactionIdSuffixStrategy transactionIdSuffixStrategy = new DefaultTransactionIdSuffixStrategy(0);
144144

145-
private Supplier<Serializer<K>> keySerializerSupplier;
145+
private @Nullable Supplier<Serializer<K>> keySerializerSupplier;
146146

147-
private Supplier<Serializer<V>> valueSerializerSupplier;
147+
private @Nullable Supplier<Serializer<V>> valueSerializerSupplier;
148148

149-
private Supplier<Serializer<K>> rawKeySerializerSupplier;
149+
private @Nullable Supplier<Serializer<K>> rawKeySerializerSupplier;
150150

151-
private Supplier<Serializer<V>> rawValueSerializerSupplier;
151+
private @Nullable Supplier<Serializer<V>> rawValueSerializerSupplier;
152152

153153
private Duration physicalCloseTimeout = DEFAULT_PHYSICAL_CLOSE_TIMEOUT;
154154

155-
private ApplicationContext applicationContext;
155+
private @Nullable ApplicationContext applicationContext;
156156

157157
private String beanName = "not.managed.by.Spring";
158158

@@ -162,11 +162,11 @@ public class DefaultKafkaProducerFactory<K, V> extends KafkaResourceFactory
162162

163163
private boolean configureSerializers = true;
164164

165-
private volatile String transactionIdPrefix;
165+
private volatile @Nullable String transactionIdPrefix;
166166

167-
private volatile String clientIdPrefix;
167+
private volatile @Nullable String clientIdPrefix;
168168

169-
private volatile CloseSafeProducer<K, V> producer;
169+
private volatile @Nullable CloseSafeProducer<K, V> producer;
170170

171171
/**
172172
* Construct a factory with the provided configuration.
@@ -267,7 +267,7 @@ public DefaultKafkaProducerFactory(Map<String, Object> configs,
267267
}
268268
}
269269

270-
private Supplier<Serializer<K>> keySerializerSupplier(@Nullable Supplier<Serializer<K>> keySerializerSupplier) {
270+
private @Nullable Supplier<Serializer<K>> keySerializerSupplier(@Nullable Supplier<Serializer<K>> keySerializerSupplier) {
271271
this.rawKeySerializerSupplier = keySerializerSupplier;
272272
if (!this.configureSerializers) {
273273
return keySerializerSupplier;
@@ -283,7 +283,7 @@ private Supplier<Serializer<K>> keySerializerSupplier(@Nullable Supplier<Seriali
283283
};
284284
}
285285

286-
private Supplier<Serializer<V>> valueSerializerSupplier(@Nullable Supplier<Serializer<V>> valueSerializerSupplier) {
286+
private @Nullable Supplier<Serializer<V>> valueSerializerSupplier(@Nullable Supplier<Serializer<V>> valueSerializerSupplier) {
287287
this.rawValueSerializerSupplier = valueSerializerSupplier;
288288
if (!this.configureSerializers) {
289289
return valueSerializerSupplier;
@@ -456,21 +456,23 @@ public boolean isProducerPerThread() {
456456
@Override
457457
@Nullable
458458
public Serializer<K> getKeySerializer() {
459-
return this.keySerializerSupplier.get();
459+
return this.keySerializerSupplier == null ? null : this.keySerializerSupplier.get();
460460
}
461461

462462
@Override
463463
@Nullable
464464
public Serializer<V> getValueSerializer() {
465-
return this.valueSerializerSupplier.get();
465+
return this.valueSerializerSupplier == null ? null : this.valueSerializerSupplier.get();
466466
}
467467

468468
@Override
469+
@Nullable
469470
public Supplier<Serializer<K>> getKeySerializerSupplier() {
470471
return this.rawKeySerializerSupplier;
471472
}
472473

473474
@Override
475+
@Nullable
474476
public Supplier<Serializer<V>> getValueSerializerSupplier() {
475477
return this.rawValueSerializerSupplier;
476478
}
@@ -546,9 +548,11 @@ public int getPhase() {
546548
* properties applied
547549
*/
548550
@Override
549-
public ProducerFactory<K, V> copyWithConfigurationOverride(Map<String, Object> overrideProperties) {
551+
public ProducerFactory<K, V> copyWithConfigurationOverride(@Nullable Map<String, Object> overrideProperties) {
550552
Map<String, Object> producerProperties = new HashMap<>(getConfigurationProperties());
551-
producerProperties.putAll(overrideProperties);
553+
if (overrideProperties != null) {
554+
producerProperties.putAll(overrideProperties);
555+
}
552556
producerProperties = ensureExistingTransactionIdPrefixInProperties(producerProperties);
553557
DefaultKafkaProducerFactory<K, V> newFactory = new DefaultKafkaProducerFactory<>(producerProperties,
554558
getKeySerializerSupplier(),
@@ -850,7 +854,7 @@ protected Producer<K, V> createTransactionalProducer() {
850854
return createTransactionalProducer(this.transactionIdPrefix);
851855
}
852856

853-
protected Producer<K, V> createTransactionalProducer(String txIdPrefix) {
857+
protected Producer<K, V> createTransactionalProducer(@Nullable String txIdPrefix) {
854858
BlockingQueue<CloseSafeProducer<K, V>> queue = getCache(txIdPrefix);
855859
Assert.notNull(queue, () -> "No cache found for " + txIdPrefix);
856860
CloseSafeProducer<K, V> cachedProducer = queue.poll();
@@ -912,7 +916,7 @@ private void removeTransactionProducer(CloseSafeProducer<K, V> producer, Duratio
912916
listeners.forEach(listener -> listener.producerRemoved(producer.clientId, producer));
913917
}
914918

915-
private CloseSafeProducer<K, V> doCreateTxProducer(String prefix, String suffix,
919+
private CloseSafeProducer<K, V> doCreateTxProducer(@Nullable String prefix, String suffix,
916920
BiPredicate<CloseSafeProducer<K, V>, Duration> remover) {
917921
Producer<K, V> newProducer = createRawProducer(getTxProducerConfigs(prefix + suffix));
918922
try {
@@ -941,7 +945,8 @@ private CloseSafeProducer<K, V> doCreateTxProducer(String prefix, String suffix,
941945

942946
protected Producer<K, V> createRawProducer(Map<String, Object> rawConfigs) {
943947
Producer<K, V> kafkaProducer =
944-
new KafkaProducer<>(rawConfigs, this.keySerializerSupplier.get(), this.valueSerializerSupplier.get());
948+
new KafkaProducer<>(rawConfigs, this.keySerializerSupplier == null ? null : this.keySerializerSupplier.get(),
949+
this.valueSerializerSupplier == null ? null : this.valueSerializerSupplier.get());
945950
for (ProducerPostProcessor<K, V> pp : this.postProcessors) {
946951
kafkaProducer = pp.apply(kafkaProducer);
947952
}
@@ -1033,9 +1038,9 @@ protected static class CloseSafeProducer<K, V> implements Producer<K, V> {
10331038

10341039
private final BiPredicate<CloseSafeProducer<K, V>, Duration> removeProducer;
10351040

1036-
final String txIdPrefix; // NOSONAR
1041+
final @Nullable String txIdPrefix; // NOSONAR
10371042

1038-
final String txIdSuffix; // NOSONAR
1043+
final @Nullable String txIdSuffix; // NOSONAR
10391044

10401045
final long created; // NOSONAR
10411046

@@ -1045,7 +1050,7 @@ protected static class CloseSafeProducer<K, V> implements Producer<K, V> {
10451050

10461051
final int epoch; // NOSONAR
10471052

1048-
private volatile Exception producerFailed;
1053+
private volatile @Nullable Exception producerFailed;
10491054

10501055
volatile boolean closed; // NOSONAR
10511056

@@ -1186,8 +1191,11 @@ public void commitTransaction() throws ProducerFencedException {
11861191
public void abortTransaction() throws ProducerFencedException {
11871192
LOGGER.debug(() -> toString() + " abortTransaction()");
11881193
if (this.producerFailed != null) {
1189-
LOGGER.debug(() -> "abortTransaction ignored - previous txFailed: " + this.producerFailed.getMessage()
1190-
+ ": " + this);
1194+
LOGGER.debug(() -> {
1195+
String message = this.producerFailed == null ? "" : this.producerFailed.getMessage();
1196+
return "abortTransaction ignored - previous txFailed: " + message
1197+
+ ": " + this;
1198+
});
11911199
}
11921200
else {
11931201
try {

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/DefaultTransactionIdSuffixStrategy.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public DefaultTransactionIdSuffixStrategy(int maxCache) {
6464
* @throws NoProducerAvailableException if caching is enabled and no suffixes are available.
6565
*/
6666
@Override
67-
public String acquireSuffix(String txIdPrefix) {
67+
public String acquireSuffix(@Nullable String txIdPrefix) {
6868
Assert.notNull(txIdPrefix, "'txIdPrefix' must not be null");
6969
BlockingQueue<String> cache = getSuffixCache(txIdPrefix);
7070
if (cache == null) {
@@ -79,7 +79,7 @@ public String acquireSuffix(String txIdPrefix) {
7979
}
8080

8181
@Override
82-
public void releaseSuffix(String txIdPrefix, String suffix) {
82+
public void releaseSuffix(@Nullable String txIdPrefix, @Nullable String suffix) {
8383
Assert.notNull(txIdPrefix, "'txIdPrefix' must not be null");
8484
Assert.notNull(suffix, "'suffix' must not be null");
8585
if (this.maxCache <= 0) {

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/KafkaAdmin.java

+20-17
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public class KafkaAdmin extends KafkaResourceFactory
102102

103103
private final Map<String, Object> configs;
104104

105-
private ApplicationContext applicationContext;
105+
private @Nullable ApplicationContext applicationContext;
106106

107107
private Predicate<NewTopic> createOrModifyTopic = nt -> true;
108108

@@ -118,7 +118,7 @@ public class KafkaAdmin extends KafkaResourceFactory
118118

119119
private boolean modifyTopicConfigs;
120120

121-
private String clusterId;
121+
private @Nullable String clusterId;
122122

123123
/**
124124
* Create an instance with an {@link Admin} based on the supplied
@@ -227,7 +227,7 @@ public void setClusterId(String clusterId) {
227227
* @return the cluster id.
228228
* @since 3.1.8
229229
*/
230-
public String getClusterId() {
230+
public @Nullable String getClusterId() {
231231
return this.clusterId;
232232
}
233233

@@ -321,6 +321,7 @@ private void updateClusterId(Admin adminClient) throws InterruptedException, Exe
321321
* @see #setCreateOrModifyTopic(Predicate)
322322
*/
323323
protected Collection<NewTopic> newTopics() {
324+
Assert.state(this.applicationContext != null, "'applicationContext' cannot be null");
324325
Map<String, NewTopic> newTopicsMap = new HashMap<>(
325326
this.applicationContext.getBeansOfType(NewTopic.class, false, false));
326327
Map<String, NewTopics> wrappers = this.applicationContext.getBeansOfType(NewTopics.class, false, false);
@@ -550,18 +551,20 @@ private Map<String, NewPartitions> checkPartitions(Map<String, NewTopic> topicNa
550551
topicInfo.topicNameValues().forEach((n, f) -> {
551552
NewTopic topic = topicNameToTopic.get(n);
552553
try {
553-
TopicDescription topicDescription = f.get(this.operationTimeout, TimeUnit.SECONDS);
554-
if (topic.numPartitions() >= 0 && topic.numPartitions() < topicDescription.partitions().size()) {
555-
LOGGER.info(() -> String.format(
556-
"Topic '%s' exists but has a different partition count: %d not %d", n,
557-
topicDescription.partitions().size(), topic.numPartitions()));
558-
}
559-
else if (topic.numPartitions() > topicDescription.partitions().size()) {
560-
LOGGER.info(() -> String.format(
561-
"Topic '%s' exists but has a different partition count: %d not %d, increasing "
562-
+ "if the broker supports it", n,
563-
topicDescription.partitions().size(), topic.numPartitions()));
564-
topicsToModify.put(n, NewPartitions.increaseTo(topic.numPartitions()));
554+
if (topic != null) {
555+
TopicDescription topicDescription = f.get(this.operationTimeout, TimeUnit.SECONDS);
556+
if (topic.numPartitions() >= 0 && topic.numPartitions() < topicDescription.partitions().size()) {
557+
LOGGER.info(() -> String.format(
558+
"Topic '%s' exists but has a different partition count: %d not %d", n,
559+
topicDescription.partitions().size(), topic.numPartitions()));
560+
}
561+
else if (topic.numPartitions() > topicDescription.partitions().size()) {
562+
LOGGER.info(() -> String.format(
563+
"Topic '%s' exists but has a different partition count: %d not %d, increasing "
564+
+ "if the broker supports it", n,
565+
topicDescription.partitions().size(), topic.numPartitions()));
566+
topicsToModify.put(n, NewPartitions.increaseTo(topic.numPartitions()));
567+
}
565568
}
566569
}
567570
catch (@SuppressWarnings("unused") InterruptedException e) {
@@ -594,7 +597,7 @@ private void addTopics(Admin adminClient, List<NewTopic> topicsToAdd) {
594597
LOGGER.debug(e.getCause(), "Failed to create topics");
595598
}
596599
else {
597-
LOGGER.error(e.getCause(), "Failed to create topics");
600+
LOGGER.error(e.getCause() != null ? e.getCause() : e, "Failed to create topics");
598601
throw new KafkaException("Failed to create topics", e.getCause()); // NOSONAR
599602
}
600603
}
@@ -617,7 +620,7 @@ private void createMissingPartitions(Admin adminClient, Map<String, NewPartition
617620
LOGGER.debug(e.getCause(), "Failed to create partitions");
618621
}
619622
else {
620-
LOGGER.error(e.getCause(), "Failed to create partitions");
623+
LOGGER.error(e.getCause() != null ? e.getCause() : e, "Failed to create partitions");
621624
if (!(e.getCause() instanceof UnsupportedVersionException)) {
622625
throw new KafkaException("Failed to create partitions", e.getCause()); // NOSONAR
623626
}

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/KafkaMetricsSupport.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ private KafkaClientMetrics createAdminMetrics(AdminClient adminClient, List<Tag>
168168
* @param id the unique identifier for the client to manage in store.
169169
* @param client the Kafka client instance to unbind.
170170
*/
171-
protected final void unbindClient(String id, C client) {
171+
protected final void unbindClient(@Nullable String id, C client) {
172172
AutoCloseable removed = (AutoCloseable) this.metrics.remove(id);
173173
if (removed != null) {
174174
try {

Diff for: spring-kafka/src/main/java/org/springframework/kafka/core/KafkaResourceFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
*/
3232
public abstract class KafkaResourceFactory {
3333

34-
private Supplier<String> bootstrapServersSupplier;
34+
private @Nullable Supplier<String> bootstrapServersSupplier;
3535

3636
@Nullable
3737
protected String getBootstrapServers() {

0 commit comments

Comments
 (0)