From 6bc96a47b7540ce6a4d44386c629d553b5ec4251 Mon Sep 17 00:00:00 2001 From: Dean Wette Date: Mon, 18 Mar 2024 12:28:09 -0500 Subject: [PATCH] breaks: Remove deprecations for Micronaut Framework 5 and document breaking changes. (#518) * Remove deprecations for Micronaut Framework 5 and document breaking changes. closes #506 * bump up to test-resources 2.3.3 --------- Co-authored-by: Sergio del Amo --- config/accepted-api-changes.json | 152 ++++++++++- .../jms/docs/binding/MapConsumer.groovy | 10 +- .../exceptions/ErrorThrowingConsumer.groovy | 5 +- .../jms/docs/quickstart/TextConsumer.groovy | 9 +- .../SuccessHandlingConsumer.groovy | 6 +- .../micronaut/jms/docs/binding/MapConsumer.kt | 18 +- .../docs/exceptions/ErrorThrowingConsumer.kt | 5 +- .../jms/docs/quickstart/TextConsumer.kt | 9 +- .../successhandler/SuccessHandlingConsumer.kt | 5 +- gradle/libs.versions.toml | 2 +- .../io/micronaut/jms/annotations/Queue.java | 32 +-- .../io/micronaut/jms/annotations/Topic.java | 16 +- .../listener/ConcurrentMessageHandler.java | 83 ------ .../jms/listener/JMSListenerContainer.java | 250 ------------------ .../listener/JMSListenerContainerFactory.java | 142 ---------- src/main/docs/guide/breaks.adoc | 19 +- .../src/main/java/example/TasksListener.java | 4 +- .../src/main/java/example/TasksListener.java | 3 +- 18 files changed, 205 insertions(+), 565 deletions(-) delete mode 100644 jms-core/src/main/java/io/micronaut/jms/listener/ConcurrentMessageHandler.java delete mode 100644 jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainer.java delete mode 100644 jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainerFactory.java diff --git a/config/accepted-api-changes.json b/config/accepted-api-changes.json index 3d314aec..14caf5bd 100644 --- a/config/accepted-api-changes.json +++ b/config/accepted-api-changes.json @@ -58,5 +58,155 @@ "type": "io.micronaut.jms.pool.SessionPool", "member": "Constructor io.micronaut.jms.pool.SessionPool(int,int,javax.jms.Connection,io.micronaut.jms.pool.MessageProducerPoolFactory)", "reason": "Migration from javax.jms to jakarta.jms" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Field $ANNOTATION_METADATA", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Constructor io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference()", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.core.annotation.AnnotationSource", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.inject.BeanContextConditional", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.core.annotation.AnnotationMetadataProvider", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.core.beans.BeanInfo", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.core.annotation.AnnotationMetadataDelegate", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.core.annotation.AnnotationMetadata", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.inject.QualifiedBeanType", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.core.type.ArgumentCoercible", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.inject.BeanType", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.$JMSListenerContainerFactory$Definition$Reference", + "member": "Implemented interface io.micronaut.inject.BeanDefinitionReference", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.ConcurrentMessageHandler", + "member": "Constructor io.micronaut.jms.listener.ConcurrentMessageHandler(io.micronaut.jms.listener.MessageHandler,java.util.concurrent.ExecutorService)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.ConcurrentMessageHandler", + "member": "Constructor io.micronaut.jms.listener.ConcurrentMessageHandler(io.micronaut.jms.listener.MessageHandler)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.ConcurrentMessageHandler", + "member": "Implemented interface io.micronaut.jms.listener.MessageHandler", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.JMSListener", + "member": "Constructor io.micronaut.jms.listener.JMSListener(javax.jms.Session,javax.jms.MessageListener,io.micronaut.jms.model.JMSDestinationType,java.lang.String,java.util.concurrent.ExecutorService,java.util.Optional)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.JMSListenerContainer", + "member": "Constructor io.micronaut.jms.listener.JMSListenerContainer(io.micronaut.jms.pool.JMSConnectionPool,io.micronaut.jms.model.JMSDestinationType,int)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.JMSListenerContainer", + "member": "Constructor io.micronaut.jms.listener.JMSListenerContainer(io.micronaut.jms.pool.JMSConnectionPool,io.micronaut.jms.model.JMSDestinationType,int,int)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.JMSListenerContainerFactory", + "member": "Constructor io.micronaut.jms.listener.JMSListenerContainerFactory()", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.listener.MessageHandlerAdapter", + "member": "Implemented interface javax.jms.MessageListener", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.JMSConnectionPool", + "member": "Constructor io.micronaut.jms.pool.JMSConnectionPool(javax.jms.ConnectionFactory,int,int)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.JMSConnectionPool", + "member": "Implemented interface javax.jms.ConnectionFactory", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.MessageProducerPool", + "member": "Constructor io.micronaut.jms.pool.MessageProducerPool(int,int,javax.jms.Session)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.PooledConnection", + "member": "Constructor io.micronaut.jms.pool.PooledConnection(javax.jms.Connection,io.micronaut.jms.pool.AbstractPool)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.PooledConnection", + "member": "Implemented interface javax.jms.Connection", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.PooledProducer", + "member": "Constructor io.micronaut.jms.pool.PooledProducer(io.micronaut.jms.pool.AbstractPool,javax.jms.MessageProducer)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.PooledProducer", + "member": "Implemented interface javax.jms.MessageProducer", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.PooledSession", + "member": "Constructor io.micronaut.jms.pool.PooledSession(io.micronaut.jms.pool.AbstractPool,javax.jms.Session,io.micronaut.jms.pool.MessageProducerPool)", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.PooledSession", + "member": "Implemented interface javax.jms.Session", + "reason": "Removed deprecated code for Micronaut Framework 5" + }, + { + "type": "io.micronaut.jms.pool.SessionPool", + "member": "Constructor io.micronaut.jms.pool.SessionPool(int,int,javax.jms.Connection,io.micronaut.jms.pool.MessageProducerPoolFactory)", + "reason": "Removed deprecated code for Micronaut Framework 5" } -] \ No newline at end of file +] diff --git a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/binding/MapConsumer.groovy b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/binding/MapConsumer.groovy index 68cce29b..85e55f19 100644 --- a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/binding/MapConsumer.groovy +++ b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/binding/MapConsumer.groovy @@ -1,14 +1,16 @@ package io.micronaut.jms.docs.binding +import io.micronaut.context.annotation.Requires +import io.micronaut.core.annotation.Nullable + // tag::imports[] -import io.micronaut.core.annotation.Nullable + import io.micronaut.jms.annotations.JMSListener import io.micronaut.jms.annotations.Message import io.micronaut.jms.annotations.Queue import io.micronaut.messaging.annotation.MessageBody import io.micronaut.messaging.annotation.MessageHeader - import jakarta.jms.Destination import static io.micronaut.jms.activemq.classic.configuration.ActiveMqClassicConfiguration.CONNECTION_FACTORY_BEAN_NAME @@ -22,8 +24,8 @@ import static io.micronaut.jms.model.JMSHeaders.JMS_REDELIVERED import static io.micronaut.jms.model.JMSHeaders.JMS_REPLY_TO import static io.micronaut.jms.model.JMSHeaders.JMS_TIMESTAMP import static io.micronaut.jms.model.JMSHeaders.JMS_TYPE + // end::imports[] -import io.micronaut.context.annotation.Requires @Requires(property = 'spec.name', value = 'BindingSpec') // tag::clazz[] @@ -34,7 +36,7 @@ class MapConsumer { List> messageHeaders = [].asSynchronized() List messages = [].asSynchronized() - @Queue(value = 'queue_map', concurrency = '1-5') + @Queue(value = 'queue_map') void receive(@MessageBody Map body, @Message jakarta.jms.Message message, @MessageHeader(JMS_CORRELATION_ID) @Nullable String correlationId, diff --git a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.groovy b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.groovy index 7a80811d..fc683220 100644 --- a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.groovy +++ b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.groovy @@ -2,14 +2,13 @@ package io.micronaut.jms.docs.exceptions import io.micronaut.context.annotation.Requires import io.micronaut.jms.annotations.JMSListener +import io.micronaut.jms.annotations.Queue // tag::imports[] -import io.micronaut.jms.annotations.Queue import io.micronaut.jms.listener.JMSListenerErrorHandler import io.micronaut.messaging.annotation.MessageBody import jakarta.inject.Singleton - import jakarta.jms.Message import jakarta.jms.Session @@ -24,7 +23,7 @@ class ErrorThrowingConsumer { Collection messages = Collections.synchronizedSet(new HashSet()) - @Queue(value = "error-queue", concurrency = "1-1", errorHandlers = [CountingErrorHandler.class]) // <2> + @Queue(value = "error-queue", errorHandlers = [CountingErrorHandler.class]) // <2> void receive(@MessageBody String message) { if (message == "throw an error") { throw new RuntimeException("this is an error") // <3> diff --git a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/quickstart/TextConsumer.groovy b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/quickstart/TextConsumer.groovy index a5a4c0a5..c842c045 100644 --- a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/quickstart/TextConsumer.groovy +++ b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/quickstart/TextConsumer.groovy @@ -1,13 +1,16 @@ package io.micronaut.jms.docs.quickstart -// tag::imports[] +import io.micronaut.context.annotation.Requires import io.micronaut.jms.annotations.JMSListener + +// tag::imports[] + import io.micronaut.jms.annotations.Queue import io.micronaut.messaging.annotation.MessageBody import static io.micronaut.jms.activemq.classic.configuration.ActiveMqClassicConfiguration.CONNECTION_FACTORY_BEAN_NAME + // end::imports[] -import io.micronaut.context.annotation.Requires @Requires(property = 'spec.name', value = 'QuickstartSpec') // tag::clazz[] @@ -16,7 +19,7 @@ class TextConsumer { List messages = [].asSynchronized() - @Queue(value = 'queue_text', concurrency = '1-5') // <2> + @Queue(value = 'queue_text') // <2> void receive(@MessageBody String body) { // <3> messages << body } diff --git a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.groovy b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.groovy index ed311772..cd46bec2 100644 --- a/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.groovy +++ b/docs-examples/example-groovy/src/test/groovy/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.groovy @@ -4,14 +4,14 @@ import io.micronaut.context.annotation.Requires import io.micronaut.jms.annotations.JMSListener import io.micronaut.jms.annotations.Queue import io.micronaut.jms.listener.JMSListenerSuccessHandler +import io.micronaut.messaging.annotation.MessageBody // tag::imports[] -import io.micronaut.messaging.annotation.MessageBody import jakarta.inject.Singleton - import jakarta.jms.Message import jakarta.jms.Session + import java.util.concurrent.atomic.AtomicInteger import static io.micronaut.jms.activemq.classic.configuration.ActiveMqClassicConfiguration.CONNECTION_FACTORY_BEAN_NAME @@ -25,7 +25,7 @@ class SuccessHandlingConsumer { Collection messages = Collections.synchronizedSet(new HashSet()) - @Queue(value = "success-queue", concurrency = "1-1", successHandlers = [CountingSuccessHandler.class]) // <2> + @Queue(value = "success-queue", successHandlers = [CountingSuccessHandler.class]) // <2> void receive(@MessageBody String message) { messages.add(message) } diff --git a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/binding/MapConsumer.kt b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/binding/MapConsumer.kt index ed0fb449..08f97156 100644 --- a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/binding/MapConsumer.kt +++ b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/binding/MapConsumer.kt @@ -1,25 +1,17 @@ package io.micronaut.jms.docs.binding -import io.micronaut.context.annotation.Requires // tag::imports[] +import io.micronaut.context.annotation.Requires import io.micronaut.jms.activemq.classic.configuration.ActiveMqClassicConfiguration.CONNECTION_FACTORY_BEAN_NAME import io.micronaut.jms.annotations.JMSListener import io.micronaut.jms.annotations.Message import io.micronaut.jms.annotations.Queue -import io.micronaut.jms.model.JMSHeaders.JMS_CORRELATION_ID -import io.micronaut.jms.model.JMSHeaders.JMS_DELIVERY_MODE -import io.micronaut.jms.model.JMSHeaders.JMS_DESTINATION -import io.micronaut.jms.model.JMSHeaders.JMS_EXPIRATION -import io.micronaut.jms.model.JMSHeaders.JMS_MESSAGE_ID -import io.micronaut.jms.model.JMSHeaders.JMS_PRIORITY -import io.micronaut.jms.model.JMSHeaders.JMS_REDELIVERED -import io.micronaut.jms.model.JMSHeaders.JMS_REPLY_TO -import io.micronaut.jms.model.JMSHeaders.JMS_TIMESTAMP -import io.micronaut.jms.model.JMSHeaders.JMS_TYPE +import io.micronaut.jms.model.JMSHeaders.* import io.micronaut.messaging.annotation.MessageBody import io.micronaut.messaging.annotation.MessageHeader -import java.io.Serializable import jakarta.jms.Destination +import java.io.Serializable + // end::imports[] @Requires(property = "spec.name", value = "BindingSpec") @@ -31,7 +23,7 @@ class MapConsumer { val messageHeaders = mutableListOf>() val messages = mutableListOf() - @Queue(value = "queue_map", concurrency = "1-5") + @Queue(value = "queue_map") fun receive( @MessageBody body: Map, @Message message: jakarta.jms.Message, diff --git a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.kt b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.kt index c4a1baa3..446426b8 100644 --- a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.kt +++ b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/exceptions/ErrorThrowingConsumer.kt @@ -7,10 +7,10 @@ import io.micronaut.jms.annotations.Queue import io.micronaut.jms.listener.JMSListenerErrorHandler import io.micronaut.messaging.annotation.MessageBody import jakarta.inject.Singleton -import java.util.* -import java.util.concurrent.atomic.AtomicInteger import jakarta.jms.Message import jakarta.jms.Session +import java.util.* +import java.util.concurrent.atomic.AtomicInteger // end::imports[] @@ -24,7 +24,6 @@ class ErrorThrowingConsumer { @Queue( value = "error-queue", - concurrency = "1-1", errorHandlers = [CountingErrorHandler::class]) // <2> fun receive(@MessageBody message: String) { if (message == "throw an error") { diff --git a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/quickstart/TextConsumer.kt b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/quickstart/TextConsumer.kt index be91d44c..9b7bd03e 100644 --- a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/quickstart/TextConsumer.kt +++ b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/quickstart/TextConsumer.kt @@ -1,14 +1,13 @@ package io.micronaut.jms.docs.quickstart // tag::imports[] +// end::imports[] +import io.micronaut.context.annotation.Requires import io.micronaut.jms.activemq.classic.configuration.ActiveMqClassicConfiguration.CONNECTION_FACTORY_BEAN_NAME import io.micronaut.jms.annotations.JMSListener import io.micronaut.jms.annotations.Queue import io.micronaut.messaging.annotation.MessageBody -import java.util.ArrayList -import java.util.Collections -// end::imports[] -import io.micronaut.context.annotation.Requires +import java.util.* @Requires(property = "spec.name", value = "QuickstartSpec") // tag::clazz[] @@ -17,7 +16,7 @@ class TextConsumer { val messages: MutableList = Collections.synchronizedList(ArrayList()) - @Queue(value = "queue_text", concurrency = "1-5") // <2> + @Queue(value = "queue_text") // <2> fun receive(@MessageBody body: String) { // <3> messages.add(body) } diff --git a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.kt b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.kt index 0af63779..d12cee5c 100644 --- a/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.kt +++ b/docs-examples/example-kotlin/src/test/kotlin/io/micronaut/jms/docs/successhandler/SuccessHandlingConsumer.kt @@ -7,10 +7,10 @@ import io.micronaut.jms.annotations.Queue import io.micronaut.jms.listener.JMSListenerSuccessHandler import io.micronaut.messaging.annotation.MessageBody import jakarta.inject.Singleton -import java.util.* -import java.util.concurrent.atomic.AtomicInteger import jakarta.jms.Message import jakarta.jms.Session +import java.util.* +import java.util.concurrent.atomic.AtomicInteger // end::imports[] @@ -24,7 +24,6 @@ class SuccessHandlingConsumer { @Queue( value = "success-queue", - concurrency = "1-1", successHandlers = [CountingSuccessHandler::class]) // <2> fun receive(@MessageBody message: String) { processed.add(message) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4de02ecb..88fd38d6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ micronaut-docs = "2.0.0" micronaut = "4.3.11" micronaut-test = "4.1.1" micronaut-aws = "4.4.3" -micronaut-test-resources = "2.3.2" +micronaut-test-resources = "2.3.3" micronaut-platform = "4.2.3" amazon-sqs-messaging = '2.1.2' micronaut-validation = "4.4.4" diff --git a/jms-core/src/main/java/io/micronaut/jms/annotations/Queue.java b/jms-core/src/main/java/io/micronaut/jms/annotations/Queue.java index 3ab82ff0..cc3be592 100644 --- a/jms-core/src/main/java/io/micronaut/jms/annotations/Queue.java +++ b/jms-core/src/main/java/io/micronaut/jms/annotations/Queue.java @@ -25,9 +25,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; +import static jakarta.jms.Session.AUTO_ACKNOWLEDGE; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import static jakarta.jms.Session.AUTO_ACKNOWLEDGE; /** * Binds a {@link jakarta.jms.Queue} to a method for receiving or sending a {@link jakarta.jms.Message}. @@ -73,23 +73,6 @@ @AliasFor(annotation = MessageMapping.class, member = "value") String value(); - /** - * The size of the thread pool to use when used in conjunction with - * {@link JMSListener}. The value must be of the form x-y where x is the - * initial size of the thread pool and y is the maximum size. If this - * option is specified, a new thread pool will be created and destroyed - * with the {@link io.micronaut.jms.listener.JMSListener}. This - * option cannot be used in conjunction with {@link Queue#executor()}; if - * both are specified the {@link Queue#executor()} value will be used. - * - * @deprecated since 3.0.0, to align the implementation with the JMS model and the messaging libraries' presumptions. - * - * - * @return the initial and max size of the thread pool - */ - @Deprecated - String concurrency() default "1-1"; - /** * The name of a {@link io.micronaut.jms.serdes.Serializer} in the bean * context to use to serialize an object into a {@link jakarta.jms.Message} @@ -100,19 +83,6 @@ */ String serializer() default ""; - /** - * The name of an {@link java.util.concurrent.ExecutorService} in the bean - * context to execute tasks on when receiving a {@link jakarta.jms.Message} - * as part of a {@link JMSListener}. The executor can be maintained by - * Micronaut using the {@link io.micronaut.scheduling.executor.UserExecutorConfiguration}. - * - * @deprecated since 3.0.0, to align the implementation with the JMS model and the messaging libraries' presumptions. - * - * @return the executor service bean name - */ - @Deprecated - String executor() default ""; - /** * @return the acknowledge mode for the {@link io.micronaut.jms.listener.JMSListener}. * @see jakarta.jms.Session diff --git a/jms-core/src/main/java/io/micronaut/jms/annotations/Topic.java b/jms-core/src/main/java/io/micronaut/jms/annotations/Topic.java index f9cba02e..3e1100ce 100644 --- a/jms-core/src/main/java/io/micronaut/jms/annotations/Topic.java +++ b/jms-core/src/main/java/io/micronaut/jms/annotations/Topic.java @@ -25,9 +25,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; +import static jakarta.jms.Session.AUTO_ACKNOWLEDGE; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import static jakarta.jms.Session.AUTO_ACKNOWLEDGE; /** * Annotation to bind a {@link jakarta.jms.Topic} to a method for receiving or @@ -66,20 +66,6 @@ @AliasFor(annotation = MessageMapping.class, member = "value") String value(); - /** - * The name of an {@link java.util.concurrent.ExecutorService} in the bean - * context to execute tasks on when receiving a {@link jakarta.jms.Message} - * as part of a {@link JMSListener}. The executor can be maintained by - * Micronaut using the {@link io.micronaut.scheduling.executor.UserExecutorConfiguration}. - * - * @deprecated since 3.0.0, to align the implementation with the JMS model and the messaging libraries' presumptions. - * - * - * @return the executor service name - */ - @Deprecated - String executor() default ""; - /** * The name of a {@link io.micronaut.jms.serdes.Serializer} in the bean * context to use to serialize an object into a {@link jakarta.jms.Message} diff --git a/jms-core/src/main/java/io/micronaut/jms/listener/ConcurrentMessageHandler.java b/jms-core/src/main/java/io/micronaut/jms/listener/ConcurrentMessageHandler.java deleted file mode 100644 index f4506076..00000000 --- a/jms-core/src/main/java/io/micronaut/jms/listener/ConcurrentMessageHandler.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.jms.listener; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static java.util.concurrent.TimeUnit.SECONDS; - -/** - * A {@link MessageHandler} decorator that wraps a delegate implementation in - * an {@link ExecutorService} to handle many incoming messages concurrently on - * different threads. A default single-threaded executor is provided if no - * {@link ExecutorService} is provided. - * - * @param the type of the object that the handler is expecting. - * @author Elliott Pope - * @since 1.0.0 - * - * @deprecated as of 2.1.1 - */ -@Deprecated -public class ConcurrentMessageHandler implements MessageHandler { - - private static final long DEFAULT_AWAIT_TIMEOUT = 10; // TODO configurable - - private final MessageHandler delegate; - private final ExecutorService executorService; - - /** - * Allows for concurrent handling of messages by handing of the logic to - * a delegate {@link MessageHandler} but wrapping those calls within - * an {@link ExecutorService#execute(Runnable)}. - * - * @param delegate the {@link MessageHandler} to actually handle the incoming messages - * @param executorService the {@link ExecutorService} to submit handling requests to. - */ - public ConcurrentMessageHandler(MessageHandler delegate, - ExecutorService executorService) { - this.delegate = delegate; - this.executorService = executorService; - } - - /** - * Submits incoming handling requests on a single threaded executor to - * avoid blocking the main thread. - * - * @param delegate the {@link MessageHandler} to actually handle the incoming messages/ - */ - public ConcurrentMessageHandler(MessageHandler delegate) { - this(delegate, Executors.newSingleThreadExecutor()); - } - - @Override - public void handle(T message) { - executorService.submit(() -> delegate.handle(message)); - } - - /** - * Closes the MessageHandler and terminates the {@link ConcurrentMessageHandler#executorService}. - * - * @return true if the {@link ConcurrentMessageHandler#executorService} is successfully shut down. - * @throws InterruptedException if there is a timeout waiting for the executor service to shut down - */ - public boolean shutdown() throws InterruptedException { - executorService.shutdown(); - executorService.awaitTermination(DEFAULT_AWAIT_TIMEOUT, SECONDS); - return executorService.isShutdown(); - } -} diff --git a/jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainer.java b/jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainer.java deleted file mode 100644 index dfab5cb0..00000000 --- a/jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainer.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.jms.listener; - -import io.micronaut.core.util.ArgumentUtils; -import io.micronaut.jms.model.JMSDestinationType; -import io.micronaut.jms.pool.JMSConnectionPool; -import io.micronaut.messaging.exceptions.MessageListenerException; -import jakarta.annotation.PreDestroy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jakarta.jms.Connection; -import jakarta.jms.Destination; -import jakarta.jms.JMSException; -import jakarta.jms.MessageConsumer; -import jakarta.jms.MessageListener; -import jakarta.jms.Session; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicBoolean; - -import static io.micronaut.jms.model.JMSDestinationType.QUEUE; -import static java.util.concurrent.TimeUnit.SECONDS; -import static jakarta.jms.Session.AUTO_ACKNOWLEDGE; - -/** - * Sets up and manages {@link MessageListener}s created by the - * {@link io.micronaut.jms.annotations.JMSListener} and - * {@link io.micronaut.jms.configuration.AbstractJMSListenerMethodProcessor} - * processing. There is support for programmatically instantiating listeners - * however this has not been fully incorporated into a coherent API yet and has - * not been fully tested. It is recommended to instead use the - * {@link io.micronaut.jms.annotations.JMSListener} annotation on existing classes. - * - * @param the {@link jakarta.jms.Message} object type to convert to before handling - * @author Elliott Pope - * @since 1.0.0 - * - * @deprecated as of 2.1.1 - */ -@Deprecated -public class JMSListenerContainer { - - private static final Logger LOGGER = LoggerFactory.getLogger(JMSListenerContainer.class); - private static final long DEFAULT_KEEP_ALIVE_TIME = 5; // TODO configurable - private static final int DEFAULT_EXECUTOR_QUEUE_SIZE = 10; // TODO configurable - private static final boolean DEFAULT_TRANSACTED = false; // TODO configurable - private static final int DEFAULT_ACKNOWLEDGE_MODE = AUTO_ACKNOWLEDGE; // TODO configurable - - private final Set openConnections = new HashSet<>(); - private final JMSConnectionPool connectionPool; - private final int threadPoolSize; - private final int maxThreadPoolSize; - private final JMSDestinationType type; - - /** - * @param connectionPool the {@link JMSConnectionPool} to pull - * {@link Connection}s from to create {@link MessageListener}s - * @param type either {@link JMSDestinationType#QUEUE} or {@link JMSDestinationType#TOPIC}. - * @param threadPoolSize the pool size - */ - public JMSListenerContainer(JMSConnectionPool connectionPool, - JMSDestinationType type, - int threadPoolSize) { - this(connectionPool, type, threadPoolSize, threadPoolSize); - } - - /** - * @param connectionPool the {@link JMSConnectionPool} to pull - * {@link Connection}s from to create {@link MessageListener}s - * @param type either {@link JMSDestinationType#QUEUE} or {@link JMSDestinationType#TOPIC}. - * @param threadPoolSize the minimum core thread pool size - * @param maxThreadPoolSize the maximum number of threads to use handling incoming requests - */ - public JMSListenerContainer(JMSConnectionPool connectionPool, - JMSDestinationType type, - int threadPoolSize, - int maxThreadPoolSize) { - ArgumentUtils.check(() -> maxThreadPoolSize >= threadPoolSize) - .orElseFail("maxThreadPoolSize cannot be smaller than the threadPoolSize"); - - this.connectionPool = connectionPool; - this.type = type; - this.threadPoolSize = threadPoolSize; - this.maxThreadPoolSize = maxThreadPoolSize; - } - - /** - * Registers a {@link JMSListenerContainer} with default concurrency. - *

- * NOTE: this method is not recommended; instead use the annotation driven - * {@link io.micronaut.jms.annotations.JMSListener} - * - * @param destination the queue or topic name - * @param listener the message handler - * @param clazz the message type - */ - @SuppressWarnings("java:S2095") - public void registerListener(String destination, - MessageHandler listener, - Class clazz) { - try { - final Connection connection = connectionPool.createConnection(); - final Session session = connection.createSession(DEFAULT_TRANSACTED, DEFAULT_ACKNOWLEDGE_MODE); - openConnections.add(connection); - final MessageConsumer consumer = session.createConsumer( - lookupDestination(destination, session)); - consumer.setMessageListener( - new MessageHandlerAdapter<>( - new ConcurrentMessageHandler<>( - listener, - new ThreadPoolExecutor( - threadPoolSize, - maxThreadPoolSize, - DEFAULT_KEEP_ALIVE_TIME, - SECONDS, - new LinkedBlockingQueue<>(DEFAULT_EXECUTOR_QUEUE_SIZE), - Executors.defaultThreadFactory())), - clazz)); - LOGGER.debug("registered {} listener {} for destination '{}' and class {}", - type.name().toLowerCase(), listener, destination, clazz.getName()); - } catch (Exception e) { - throw new MessageListenerException( - "Problem registering a MessageConsumer for " + destination, e); - } - } - - /** - * Internal method used by the {@link JMSListenerContainerFactory} for - * registering new listeners. - *

- * NOTE: this method is used internally by the - * {@link io.micronaut.jms.configuration.AbstractJMSListenerMethodProcessor} - * and is not recommended for use. Instead the annotation driven - * {@link io.micronaut.jms.annotations.JMSListener} is preferred. - * - * @param destination the queue or topic name - * @param listener the message handler - * @param clazz the message type - * @param transacted indicates whether the session will use a local transaction - * @param acknowledgeMode when transacted is false, indicates how messages - * received by the session will be acknowledged - * @param messageSelector the message selector for the listener - * @see Session#AUTO_ACKNOWLEDGE - * @see Session#CLIENT_ACKNOWLEDGE - * @see Session#DUPS_OK_ACKNOWLEDGE - */ - @SuppressWarnings("java:S2095") - public void registerListener(String destination, - MessageListener listener, - Class clazz, // TODO unused - boolean transacted, - int acknowledgeMode, - Optional messageSelector) { - try { - final Connection connection = connectionPool.createConnection(); - final Session session = connection.createSession(transacted, acknowledgeMode); - openConnections.add(connection); - MessageConsumer consumer; - if (!messageSelector.isPresent()) { - consumer = session.createConsumer( - lookupDestination(destination, session)); - } else { - consumer = session.createConsumer( - lookupDestination(destination, session), messageSelector.get()); - } - - consumer.setMessageListener((message) -> { - try { - listener.onMessage(message); - if (transacted) { - session.commit(); - } - } catch (Exception e) { - if (transacted) { - try { - session.rollback(); - } catch (JMSException | RuntimeException e2) { - throw new MessageListenerException( - "Problem rolling back transaction", e2); - } - } - throw new MessageListenerException(e.getMessage(), e); - } - }); - LOGGER.debug("registered {} listener {} for destination '{}'; " + - "transacted: {}, ack mode: {}", - type.name().toLowerCase(), listener, destination, transacted, acknowledgeMode); - } catch (JMSException | RuntimeException e) { - throw new MessageListenerException( - "Problem registering a MessageConsumer for " + destination, e); - } - } - - /** - * Safely shuts down all open connections linked to the listener container. - * To be executed when the bean is destroyed. - * - * @return true if all open connections are successfully closed - */ - @PreDestroy - public boolean shutdown() { - final AtomicBoolean success = new AtomicBoolean(true); - for (Connection connection : openConnections) { - try { - connection.stop(); - } catch (JMSException | RuntimeException e) { - success.set(false); - LOGGER.error("Failed to stop connection", e); - } - } - return success.get(); - } - - @Override - public String toString() { - return "JMSListenerContainer{" + - "openConnections=" + openConnections + - ", connectionPool=" + connectionPool + - ", threadPoolSize=" + threadPoolSize + - ", maxThreadPoolSize=" + maxThreadPoolSize + - ", type=" + type + - '}'; - } - - private Destination lookupDestination(String destination, - Session session) throws JMSException { - return type == QUEUE ? - session.createQueue(destination) : - session.createTopic(destination); - } -} diff --git a/jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainerFactory.java b/jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainerFactory.java deleted file mode 100644 index 202b11e9..00000000 --- a/jms-core/src/main/java/io/micronaut/jms/listener/JMSListenerContainerFactory.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2017-2020 original authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.micronaut.jms.listener; - -import io.micronaut.jms.model.JMSDestinationType; -import io.micronaut.jms.pool.JMSConnectionPool; -import jakarta.annotation.PreDestroy; -import jakarta.inject.Singleton; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jakarta.jms.MessageListener; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Generates and tracks {@link JMSListenerContainer} within the Bean Context. - * - * @author Elliott Pope - * @see JMSListenerContainer - * @since 1.0.0 - * - * @deprecated as of 2.1.1 - */ -@Singleton // to do -@Deprecated -public class JMSListenerContainerFactory { - - private static final int THREAD_POOL_SIZE = 1; // TODO configurable? - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - // TODO one listener per destination??? at least error/warn if replacing - private final Map> listeners = new ConcurrentHashMap<>(); - - /** - * Generates a new {@link JMSListenerContainer} and registers the - * provided {@link MessageHandler} as the receiving executable method. - *

- * NOTE: this method is not recommended for registering new {@link JMSListenerContainer}s - * however can be used to register them dynamically and allow for safe shutdown - * within the Bean Context. - * - * @param connectionPool the pool - * @param destination the queue or topic name - * @param listener the message listener - * @param clazz the message type - * @param type the destination type - * @param the class type - */ - public void registerListener(final JMSConnectionPool connectionPool, - final String destination, - final MessageHandler listener, - final Class clazz, - final JMSDestinationType type) { - final JMSListenerContainer container = new JMSListenerContainer<>( - connectionPool, type, THREAD_POOL_SIZE); - container.registerListener(destination, listener, clazz); - listeners.put(destination, container); - logger.debug("registered {} listener for '{}' {} for type '{}' and pool {}", - type.name().toLowerCase(), destination, listener, clazz.getName(), connectionPool); - } - - /** - * Generates a new {@link JMSListenerContainer} and registers the - * provided {@link MessageListener} as the receiving executable method. - *

- * NOTE: this method is not recommended for registering new - * {@link JMSListenerContainer}s however it can be used to register them - * dynamically and allow for safe shutdown within the Bean Context. - * - * @param the class type - * @param connectionPool the pool - * @param destination the queue or topic name - * @param listener the message listener - * @param clazz the message type - * @param transacted indicates whether the session will use a local transaction - * @param acknowledgeMode when transacted is false, indicates how messages - * received by the session will be acknowledged - * @param type the destination type - * @param messageSelector the message selector for the listener - * @see jakarta.jms.Session#AUTO_ACKNOWLEDGE - * @see jakarta.jms.Session#CLIENT_ACKNOWLEDGE - * @see jakarta.jms.Session#DUPS_OK_ACKNOWLEDGE - */ - public void registerListener(final JMSConnectionPool connectionPool, - final String destination, - final MessageListener listener, - final Class clazz, - final boolean transacted, - final int acknowledgeMode, - final JMSDestinationType type, - final Optional messageSelector) { - final JMSListenerContainer container = new JMSListenerContainer<>( - connectionPool, type, THREAD_POOL_SIZE); - container.registerListener(destination, listener, clazz, transacted, acknowledgeMode, messageSelector); - listeners.put(destination, container); - logger.debug("registered {} listener for '{}' {} for type '{}'" + - " and pool {}; transacted: {}, ack mode {}, messageSelector {}", - type.name().toLowerCase(), destination, listener, clazz.getName(), - connectionPool, transacted, acknowledgeMode, messageSelector); - } - - /** - * The {@link JMSListenerContainer} that is listening to the given {@code destination}. - * - * @param destination the name of a queue or topic - * @return the container - */ - public JMSListenerContainer getRegisteredListener(String destination) { - return listeners.get(destination); - } - - /** - * Shuts down the listeners registered with this factory. - */ - @PreDestroy - public void shutdown() { - for (JMSListenerContainer listener : listeners.values()) { - listener.shutdown(); - } - } - - @Override - public String toString() { - return "JMSListenerContainerFactory{listeners=" + listeners + '}'; - } -} diff --git a/src/main/docs/guide/breaks.adoc b/src/main/docs/guide/breaks.adoc index ea5cc02a..a2eb9a81 100644 --- a/src/main/docs/guide/breaks.adoc +++ b/src/main/docs/guide/breaks.adoc @@ -1,6 +1,6 @@ == 4.0.0 -=== Removal of `javax.jms` namespace +==== Removal of `javax.jms` namespace Version 4 switches from the deprecated `javax.jms` namespace to the new Jakarta EE `jakarta.jms` namespace. @@ -11,3 +11,20 @@ The ActiveMQ Classic client has been updated https://activemq.apache.org/new-fea ==== ActiveMQ Artemis The client dependency for ActiveMq Artemis has changed from `org.apache.activemq:artemis-jms-client` to `org.apache.activemq:artemis-jakarta-client` which uses the new namespace. + +==== Deprecations + +** The annotation `io.micronaut.jms.annotations.Queue` removes the following attributes that were deprecated previously. This is to align the implementation with the JMS model and the messaging libraries' presumptions. + +*** `String concurrency() default "1-1"` +*** `String executor() default ""` + +** The annotation `io.micronaut.jms.annotations.Topic` removes the following attributes that were deprecated previously. This is to align the implementation with the JMS model and the messaging libraries' presumptions. + +*** `String executor() default ""` + +** The following classes in the `io.micronaut.jms.listener` package were deprecated previously are now removed. + +*** `ConcurrentMessageHandler` +*** `JMSListenerContainer` +*** `JMSListenerContainerFactory` diff --git a/tests/tasks-activemq-classic/src/main/java/example/TasksListener.java b/tests/tasks-activemq-classic/src/main/java/example/TasksListener.java index eb16f522..423d35a7 100644 --- a/tests/tasks-activemq-classic/src/main/java/example/TasksListener.java +++ b/tests/tasks-activemq-classic/src/main/java/example/TasksListener.java @@ -17,10 +17,10 @@ public class TasksListener { public static final AtomicInteger TASKS_PROCESSED = new AtomicInteger(); - @Queue(value = TaskConstants.FIFO_QUEUE, concurrency = "1-1") + @Queue(value = TaskConstants.FIFO_QUEUE) public void receive(@MessageBody Task task) { LOGGER.info("Received task with id: {}", task.getId()); TASKS_PROCESSED.incrementAndGet(); } -} \ No newline at end of file +} diff --git a/tests/tasks-sqs/src/main/java/example/TasksListener.java b/tests/tasks-sqs/src/main/java/example/TasksListener.java index 99cbd1c0..6b27ad32 100644 --- a/tests/tasks-sqs/src/main/java/example/TasksListener.java +++ b/tests/tasks-sqs/src/main/java/example/TasksListener.java @@ -6,7 +6,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jakarta.jms.Session; import java.util.concurrent.atomic.AtomicInteger; import static io.micronaut.jms.sqs.configuration.SqsConfiguration.CONNECTION_FACTORY_BEAN_NAME; @@ -18,7 +17,7 @@ public class TasksListener { public static final AtomicInteger TASKS_PROCESSED = new AtomicInteger(); - @Queue(value = TaskConstants.FIFO_QUEUE, concurrency = "1-1") + @Queue(value = TaskConstants.FIFO_QUEUE) public void receive(@MessageBody Task task) { LOG.info("Received task with id: {}", task.getId()); TASKS_PROCESSED.incrementAndGet();