From babcf31fbf7df44671c55e838d068f217b2334a0 Mon Sep 17 00:00:00 2001 From: Andrew Bates Date: Tue, 9 Jun 2026 14:34:09 -0600 Subject: [PATCH 1/2] Migrate from AWS Java SDK v1 to v2 and KPL 1.x AWS Java SDK 1.x reached end of support on Dec 31, 2025. Port the SNS, SQS, and Kinesis producers off the com.amazonaws namespace to keep receiving security and bug fixes. SNS/SQS move to SnsAsyncClient / SqsAsyncClient with CompletableFuture.whenComplete() in place of the v1 AsyncHandler callbacks; KPL moves to software.amazon.kinesis 1.0.7 (internals already on SDK v2) which is just an import rename. The FilterParser's stray com.amazonaws.util.StringInputStream is replaced with ByteArrayInputStream. Behavior, config flags, and credential chain are preserved. Co-Authored-By: Claude Opus 4.7 (1M context) --- pom.xml | 44 +++++----- .../maxwell/filtering/FilterParser.java | 11 +-- .../producer/MaxwellKinesisProducer.java | 10 +-- .../maxwell/producer/MaxwellSNSProducer.java | 81 +++++++++---------- .../maxwell/producer/MaxwellSQSProducer.java | 66 ++++++++------- .../maxwell/producer/KinesisCallbackTest.java | 2 +- .../producer/MaxwellSNSProducerTest.java | 52 ++++++------ 7 files changed, 133 insertions(+), 133 deletions(-) diff --git a/pom.xml b/pom.xml index d0a4e9f9a..bfacca9a7 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,8 @@ UTF-8 5.19.0 0.28.3 - 1.12.782 + 2.34.0 + 1.0.7 2.15.2 1.8 1.8 @@ -154,6 +155,18 @@ + + + + software.amazon.awssdk + bom + ${aws-sdk-v2.version} + pom + import + + + + @@ -166,11 +179,6 @@ c3p0 0.9.5.5 - - com.amazonaws - aws-java-sdk-core - 1.12.782 - commons-io commons-io @@ -276,29 +284,21 @@ 2.49.0 - com.amazonaws - aws-java-sdk-core - 1.12.782 - - - com.amazonaws - aws-java-sdk-sns - ${aws-java.version} + software.amazon.awssdk + sns - com.amazonaws - aws-java-sdk-sqs - ${aws-java.version} + software.amazon.awssdk + sqs - com.amazonaws - aws-java-sdk-sts - ${aws-java.version} + software.amazon.awssdk + sts - com.amazonaws + software.amazon.kinesis amazon-kinesis-producer - 0.15.12 + ${kpl.version} javax.xml.bind diff --git a/src/main/java/com/zendesk/maxwell/filtering/FilterParser.java b/src/main/java/com/zendesk/maxwell/filtering/FilterParser.java index 821126078..84ce3ff78 100644 --- a/src/main/java/com/zendesk/maxwell/filtering/FilterParser.java +++ b/src/main/java/com/zendesk/maxwell/filtering/FilterParser.java @@ -1,11 +1,10 @@ package com.zendesk.maxwell.filtering; -import com.amazonaws.util.StringInputStream; - +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -22,11 +21,7 @@ public FilterParser(String input) { } public List parse() throws InvalidFilterException { - try { - this.inputStream = new InputStreamReader(new StringInputStream(input)); - } catch ( UnsupportedEncodingException e ) { - throw new InvalidFilterException(e.getMessage()); - } + this.inputStream = new InputStreamReader(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8))); this.tokenizer = new StreamTokenizer(inputStream); try { diff --git a/src/main/java/com/zendesk/maxwell/producer/MaxwellKinesisProducer.java b/src/main/java/com/zendesk/maxwell/producer/MaxwellKinesisProducer.java index 07489cf17..447838b61 100644 --- a/src/main/java/com/zendesk/maxwell/producer/MaxwellKinesisProducer.java +++ b/src/main/java/com/zendesk/maxwell/producer/MaxwellKinesisProducer.java @@ -18,11 +18,11 @@ import com.zendesk.maxwell.replication.Position; import com.zendesk.maxwell.row.RowMap; -import com.amazonaws.services.kinesis.producer.Attempt; -import com.amazonaws.services.kinesis.producer.KinesisProducer; -import com.amazonaws.services.kinesis.producer.KinesisProducerConfiguration; -import com.amazonaws.services.kinesis.producer.UserRecordFailedException; -import com.amazonaws.services.kinesis.producer.UserRecordResult; +import software.amazon.kinesis.producer.Attempt; +import software.amazon.kinesis.producer.KinesisProducer; +import software.amazon.kinesis.producer.KinesisProducerConfiguration; +import software.amazon.kinesis.producer.UserRecordFailedException; +import software.amazon.kinesis.producer.UserRecordResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/java/com/zendesk/maxwell/producer/MaxwellSNSProducer.java b/src/main/java/com/zendesk/maxwell/producer/MaxwellSNSProducer.java index 9aa4688b3..a839619ad 100644 --- a/src/main/java/com/zendesk/maxwell/producer/MaxwellSNSProducer.java +++ b/src/main/java/com/zendesk/maxwell/producer/MaxwellSNSProducer.java @@ -1,31 +1,25 @@ package com.zendesk.maxwell.producer; -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.client.builder.AwsClientBuilder; -import com.amazonaws.handlers.AsyncHandler; -import com.amazonaws.services.sns.AmazonSNSAsync; -import com.amazonaws.services.sns.AmazonSNSAsyncClientBuilder; -import com.amazonaws.services.sns.model.MessageAttributeValue; -import com.amazonaws.services.sns.model.PublishRequest; -import com.amazonaws.services.sns.model.PublishResult; import com.zendesk.maxwell.MaxwellContext; import com.zendesk.maxwell.producer.partitioners.MaxwellSNSPartitioner; import com.zendesk.maxwell.replication.Position; import com.zendesk.maxwell.row.RowMap; -import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.sns.SnsAsyncClient; +import software.amazon.awssdk.services.sns.model.MessageAttributeValue; +import software.amazon.awssdk.services.sns.model.PublishRequest; +import software.amazon.awssdk.services.sns.model.PublishResponse; +import java.net.URI; import java.util.HashMap; import java.util.Map; public class MaxwellSNSProducer extends AbstractAsyncProducer { - private AmazonSNSAsync client; + private SnsAsyncClient client; private String topic; - private String[] stringFelds = {"database", "table"}; - private String[] numberFields = {"ts", "xid"}; private MaxwellSNSPartitioner partitioner; public MaxwellSNSProducer(MaxwellContext context, String topic, String serviceEndpoint, String signingRegion) { @@ -35,12 +29,13 @@ public MaxwellSNSProducer(MaxwellContext context, String topic, String serviceEn // Only configure custom endpoint if both serviceEndpoint and signingRegion are provided if (serviceEndpoint != null && !serviceEndpoint.trim().isEmpty() && signingRegion != null && !signingRegion.trim().isEmpty()) { - this.client = AmazonSNSAsyncClientBuilder.standard() - .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(serviceEndpoint, signingRegion)) + this.client = SnsAsyncClient.builder() + .endpointOverride(URI.create(serviceEndpoint)) + .region(Region.of(signingRegion)) .build(); } else { // Use default client configuration when endpoint parameters are not provided - this.client = AmazonSNSAsyncClientBuilder.defaultClient(); + this.client = SnsAsyncClient.create(); } String partitionKey = context.getConfig().producerPartitionKey; String partitionColumns = context.getConfig().producerPartitionColumns; @@ -48,17 +43,15 @@ public MaxwellSNSProducer(MaxwellContext context, String topic, String serviceEn this.partitioner = new MaxwellSNSPartitioner(partitionKey, partitionColumns, partitionFallback); } - public void setClient(AmazonSNSAsync client) { + public void setClient(SnsAsyncClient client) { this.client = client; } @Override public void sendAsync(RowMap r, CallbackCompleter cc) throws Exception { String value = r.toJSON(outputConfig); - // Publish a message to an Amazon SNS topic. - final PublishRequest publishRequest = new PublishRequest(topic, value); - Map messageAttributes = new HashMap<>(); + Map messageAttributes = new HashMap<>(); final String configuredAttributes = context.getConfig().snsAttrs; if (configuredAttributes != null) { for (String element: configuredAttributes.split(",")) { @@ -66,33 +59,39 @@ public void sendAsync(RowMap r, CallbackCompleter cc) throws Exception { case "database": messageAttributes.put( "database", - new MessageAttributeValue().withDataType("String").withStringValue(r.getDatabase()) + MessageAttributeValue.builder().dataType("String").stringValue(r.getDatabase()).build() ); break; case "table": messageAttributes.put( "table", - new MessageAttributeValue().withDataType("String").withStringValue(r.getTable()) + MessageAttributeValue.builder().dataType("String").stringValue(r.getTable()).build() ); break; } } } - if ( topic.endsWith(".fifo")) { + PublishRequest.Builder builder = PublishRequest.builder() + .topicArn(topic) + .message(value) + .messageAttributes(messageAttributes); + + if (topic.endsWith(".fifo")) { String key = this.partitioner.getSNSKey(r); - publishRequest.setMessageGroupId(key); + builder.messageGroupId(key); } - publishRequest.setMessageAttributes(messageAttributes); + + PublishRequest publishRequest = builder.build(); SNSCallback callback = new SNSCallback(cc, r.getNextPosition(), value, r.getDatabase(), r.getTable(), r.getRowIdentity().toConcatString(), r.getApproximateSize(), context); - client.publishAsync(publishRequest, callback); + client.publish(publishRequest).whenComplete(callback); } } -class SNSCallback implements AsyncHandler { +class SNSCallback implements java.util.function.BiConsumer { public static final Logger logger = LoggerFactory.getLogger(SNSCallback.class); private final AbstractAsyncProducer.CallbackCompleter cc; @@ -118,23 +117,23 @@ public SNSCallback(AbstractAsyncProducer.CallbackCompleter cc, Position position } @Override - public void onError(Exception t) { - logger.error(t.getClass().getSimpleName() + " @ " + position + " -- "); - logger.error("Database:" + database + ", Table:" + table + ", PK:" + pk + ", Approx Size:" + Long.toString(approximateRowSize)); - logger.error(t.getLocalizedMessage()); - logger.error("Exception during put", t); - - if (!context.getConfig().ignoreProducerError) { - context.terminate(new RuntimeException(t)); - } else { - cc.markCompleted(); + public void accept(PublishResponse response, Throwable t) { + if (t != null) { + logger.error(t.getClass().getSimpleName() + " @ " + position + " -- "); + logger.error("Database:" + database + ", Table:" + table + ", PK:" + pk + ", Approx Size:" + Long.toString(approximateRowSize)); + logger.error(t.getLocalizedMessage()); + logger.error("Exception during put", t); + + if (!context.getConfig().ignoreProducerError) { + context.terminate(new RuntimeException(t)); + } else { + cc.markCompleted(); + } + return; } - }; - @Override - public void onSuccess(PublishRequest request, PublishResult result) { if (logger.isDebugEnabled()) { - logger.debug("-> MessageId: {}", result.getMessageId()); + logger.debug("-> MessageId: {}", response.messageId()); } cc.markCompleted(); } diff --git a/src/main/java/com/zendesk/maxwell/producer/MaxwellSQSProducer.java b/src/main/java/com/zendesk/maxwell/producer/MaxwellSQSProducer.java index 027afe5d6..838fadc5a 100644 --- a/src/main/java/com/zendesk/maxwell/producer/MaxwellSQSProducer.java +++ b/src/main/java/com/zendesk/maxwell/producer/MaxwellSQSProducer.java @@ -1,30 +1,30 @@ package com.zendesk.maxwell.producer; -import com.amazonaws.client.builder.AwsClientBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.amazonaws.handlers.AsyncHandler; -import com.amazonaws.services.sqs.AmazonSQSAsync; -import com.amazonaws.services.sqs.AmazonSQSAsyncClientBuilder; -import com.amazonaws.services.sqs.model.SendMessageRequest; -import com.amazonaws.services.sqs.model.SendMessageResult; import com.zendesk.maxwell.MaxwellContext; import com.zendesk.maxwell.producer.partitioners.MaxwellSQSPartitioner; import com.zendesk.maxwell.replication.Position; import com.zendesk.maxwell.row.RowMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.sqs.SqsAsyncClient; +import software.amazon.awssdk.services.sqs.model.SendMessageRequest; +import software.amazon.awssdk.services.sqs.model.SendMessageResponse; + +import java.net.URI; public class MaxwellSQSProducer extends AbstractAsyncProducer { - private AmazonSQSAsync client; + private SqsAsyncClient client; private String queueUri; private MaxwellSQSPartitioner partitioner; public MaxwellSQSProducer(MaxwellContext context, String queueUri, String serviceEndpoint, String signingRegion) { super(context); this.queueUri = queueUri; - this.client = AmazonSQSAsyncClientBuilder.standard() - .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(serviceEndpoint, signingRegion)) + this.client = SqsAsyncClient.builder() + .endpointOverride(URI.create(serviceEndpoint)) + .region(Region.of(signingRegion)) .build(); String partitionKey = context.getConfig().producerPartitionKey; String partitionColumns = context.getConfig().producerPartitionColumns; @@ -35,18 +35,24 @@ public MaxwellSQSProducer(MaxwellContext context, String queueUri, String servic @Override public void sendAsync(RowMap r, CallbackCompleter cc) throws Exception { String value = r.toJSON(outputConfig); - SendMessageRequest messageRequest = new SendMessageRequest(queueUri, value); - if ( queueUri.endsWith(".fifo")) { + + SendMessageRequest.Builder builder = SendMessageRequest.builder() + .queueUrl(queueUri) + .messageBody(value); + + if (queueUri.endsWith(".fifo")) { String key = this.partitioner.getSQSKey(r); - messageRequest.setMessageGroupId(key); + builder.messageGroupId(key); } + + SendMessageRequest messageRequest = builder.build(); SQSCallback callback = new SQSCallback(cc, r.getNextPosition(), value, context); - client.sendMessageAsync(messageRequest, callback); + client.sendMessage(messageRequest).whenComplete(callback); } } -class SQSCallback implements AsyncHandler { +class SQSCallback implements java.util.function.BiConsumer { public static final Logger logger = LoggerFactory.getLogger(SQSCallback.class); private final AbstractAsyncProducer.CallbackCompleter cc; @@ -63,23 +69,23 @@ public SQSCallback(AbstractAsyncProducer.CallbackCompleter cc, Position position } @Override - public void onError(Exception t) { - logger.error(t.getClass().getSimpleName() + " @ " + position + " -- "); - logger.error(t.getLocalizedMessage()); - logger.error("Exception during put", t); - - if (!context.getConfig().ignoreProducerError) { - context.terminate(new RuntimeException(t)); - } else { - cc.markCompleted(); + public void accept(SendMessageResponse response, Throwable t) { + if (t != null) { + logger.error(t.getClass().getSimpleName() + " @ " + position + " -- "); + logger.error(t.getLocalizedMessage()); + logger.error("Exception during put", t); + + if (!context.getConfig().ignoreProducerError) { + context.terminate(new RuntimeException(t)); + } else { + cc.markCompleted(); + } + return; } - }; - @Override - public void onSuccess(SendMessageRequest request, SendMessageResult result) { if (logger.isDebugEnabled()) { logger.debug("-> Message id:{}, sequence number:{} {} {}", - result.getMessageId(), result.getSequenceNumber(), json, position); + response.messageId(), response.sequenceNumber(), json, position); } cc.markCompleted(); } diff --git a/src/test/java/com/zendesk/maxwell/producer/KinesisCallbackTest.java b/src/test/java/com/zendesk/maxwell/producer/KinesisCallbackTest.java index 555837dbf..1470ed0aa 100644 --- a/src/test/java/com/zendesk/maxwell/producer/KinesisCallbackTest.java +++ b/src/test/java/com/zendesk/maxwell/producer/KinesisCallbackTest.java @@ -2,7 +2,7 @@ import com.codahale.metrics.Counter; import com.codahale.metrics.Meter; -import com.amazonaws.services.kinesis.producer.IrrecoverableError; +import software.amazon.kinesis.producer.IrrecoverableError; import com.zendesk.maxwell.MaxwellConfig; import com.zendesk.maxwell.MaxwellContext; import com.zendesk.maxwell.replication.BinlogPosition; diff --git a/src/test/java/com/zendesk/maxwell/producer/MaxwellSNSProducerTest.java b/src/test/java/com/zendesk/maxwell/producer/MaxwellSNSProducerTest.java index 033c85e11..9ff1b84ed 100644 --- a/src/test/java/com/zendesk/maxwell/producer/MaxwellSNSProducerTest.java +++ b/src/test/java/com/zendesk/maxwell/producer/MaxwellSNSProducerTest.java @@ -1,12 +1,5 @@ package com.zendesk.maxwell.producer; -import com.amazonaws.services.sns.AmazonSNS; -import com.amazonaws.services.sns.AmazonSNSAsync; -import com.amazonaws.services.sns.AmazonSNSAsyncClient; -import com.amazonaws.services.sns.AmazonSNSAsyncClientBuilder; -import com.amazonaws.services.sns.model.MessageAttributeValue; -import com.amazonaws.services.sns.model.PublishRequest; -import com.amazonaws.services.sns.model.PublishResult; import com.zendesk.maxwell.MaxwellConfig; import com.zendesk.maxwell.MaxwellContext; import com.zendesk.maxwell.monitoring.NoOpMetrics; @@ -22,21 +15,29 @@ import org.mockito.Captor; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import software.amazon.awssdk.services.sns.SnsAsyncClient; +import software.amazon.awssdk.services.sns.model.MessageAttributeValue; +import software.amazon.awssdk.services.sns.model.PublishRequest; +import software.amazon.awssdk.services.sns.model.PublishResponse; import java.util.ArrayList; import java.util.Map; -import java.util.concurrent.Future; +import java.util.concurrent.CompletableFuture; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.when; -import static org.mockito.Mockito.*; + public class MaxwellSNSProducerTest { private static final long TIMESTAMP_MILLISECONDS = 1496712943447L; private static final String TOPIC = "topic"; private static final String FIFO_TOPIC = "topic.fifo"; private static final Position POSITION = new Position(new BinlogPosition(1L, "binlog-0001"), 0L); - private static final Future mockedFuture = Mockito.mock(Future.class); + private static final CompletableFuture mockedFuture = + CompletableFuture.completedFuture(PublishResponse.builder().messageId("mid").build()); + @Rule public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); @@ -55,7 +56,7 @@ public void beforeEach() { @Test public void publishesRecord() throws Exception { - AmazonSNSAsyncClient client = Mockito.mock(AmazonSNSAsyncClient.class); + SnsAsyncClient client = Mockito.mock(SnsAsyncClient.class); MaxwellContext context = mock(MaxwellContext.class); when(context.getConfig()).thenReturn(new MaxwellConfig()); when(context.getMetrics()).thenReturn(new NoOpMetrics()); @@ -63,16 +64,16 @@ public void publishesRecord() throws Exception { producer.setClient(client); String payload = rowMap.toJSON(); AbstractAsyncProducer.CallbackCompleter cc = mock(AbstractAsyncProducer.CallbackCompleter.class); - when(client.publishAsync(any())).thenReturn(mockedFuture); + when(client.publish(any(PublishRequest.class))).thenReturn(mockedFuture); producer.sendAsync(rowMap, cc); - Mockito.verify(client, times(1)).publishAsync(arguments.capture(), any()); - Assert.assertEquals(arguments.getValue().getTopicArn(), TOPIC); - Assert.assertEquals(arguments.getValue().getMessage(), payload); + Mockito.verify(client, times(1)).publish(arguments.capture()); + Assert.assertEquals(arguments.getValue().topicArn(), TOPIC); + Assert.assertEquals(arguments.getValue().message(), payload); } @Test public void setsMessageAttributes() throws Exception { - AmazonSNSAsyncClient client = Mockito.mock(AmazonSNSAsyncClient.class); + SnsAsyncClient client = Mockito.mock(SnsAsyncClient.class); MaxwellContext context = mock(MaxwellContext.class); MaxwellConfig config = new MaxwellConfig(); config.snsAttrs = "database,table"; @@ -81,29 +82,28 @@ public void setsMessageAttributes() throws Exception { MaxwellSNSProducer producer = new MaxwellSNSProducer(context, TOPIC, "", ""); producer.setClient(client); AbstractAsyncProducer.CallbackCompleter cc = mock(AbstractAsyncProducer.CallbackCompleter.class); - when(client.publishAsync(any())).thenReturn(mockedFuture); + when(client.publish(any(PublishRequest.class))).thenReturn(mockedFuture); producer.sendAsync(rowMap, cc); - Mockito.verify(client, times(1)).publishAsync(arguments.capture(), any()); - Map attributes = arguments.getValue().getMessageAttributes(); + Mockito.verify(client, times(1)).publish(arguments.capture()); + Map attributes = arguments.getValue().messageAttributes(); Assert.assertNotNull(attributes.getOrDefault("table", null)); - Assert.assertEquals("MyTable", attributes.get("table").getStringValue()); + Assert.assertEquals("MyTable", attributes.get("table").stringValue()); Assert.assertNotNull(attributes.getOrDefault("database", null)); - Assert.assertEquals("MyDatabase", attributes.get("database").getStringValue()); + Assert.assertEquals("MyDatabase", attributes.get("database").stringValue()); } @Test public void ensureMessageGroupIdOnFifo() throws Exception { - AmazonSNSAsyncClient client = Mockito.mock(AmazonSNSAsyncClient.class); + SnsAsyncClient client = Mockito.mock(SnsAsyncClient.class); MaxwellContext context = mock(MaxwellContext.class); when(context.getConfig()).thenReturn(new MaxwellConfig()); when(context.getMetrics()).thenReturn(new NoOpMetrics()); MaxwellSNSProducer producer = new MaxwellSNSProducer(context, FIFO_TOPIC, "", ""); producer.setClient(client); AbstractAsyncProducer.CallbackCompleter cc = mock(AbstractAsyncProducer.CallbackCompleter.class); - when(client.publishAsync(any())).thenReturn(mockedFuture); + when(client.publish(any(PublishRequest.class))).thenReturn(mockedFuture); producer.sendAsync(rowMap, cc); - Mockito.verify(client, times(1)).publishAsync(arguments.capture(), any()); - Map attributes = arguments.getValue().getMessageAttributes(); - Assert.assertEquals("MyDatabase", arguments.getValue().getMessageGroupId()); + Mockito.verify(client, times(1)).publish(arguments.capture()); + Assert.assertEquals("MyDatabase", arguments.getValue().messageGroupId()); } } From 7c0fab010b82eee9d4b1043340b6a75a5ef4b118 Mon Sep 17 00:00:00 2001 From: Andrew Bates Date: Tue, 9 Jun 2026 14:47:07 -0600 Subject: [PATCH 2/2] Pin protobuf-java to 4.29.0 for KPL 1.x compatibility KPL 1.x's generated protobuf code requires protobuf-java 4.x's RuntimeVersion class. Without this pin, BigQuery's transitive protobuf-java 3.25.5 wins and KinesisProducerConfiguration fails to load. protobuf-java 4.x is binary-compatible with 3.x generated code, so the BigQuery / PubSub paths still work (verified via their unit tests). Co-Authored-By: Claude Opus 4.7 (1M context) --- pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bfacca9a7..e4c0f29bf 100644 --- a/pom.xml +++ b/pom.xml @@ -164,6 +164,13 @@ pom import + + + com.google.protobuf + protobuf-java + 4.29.0 + @@ -323,7 +330,6 @@ com.google.protobuf protobuf-java - 3.25.5 redis.clients