micronaut-projects / micronaut-jms

Integration between Micronaut and JMS
Apache License 2.0
14 stars 14 forks source link

Exception while sending jms messages to Apache ActiveMQ classic queue. #444

Open t0bro opened 11 months ago

t0bro commented 11 months ago

Expected Behavior

Try to send messages to ActiveMQ classic queue and then see it with the ActiveMQ web console.

Actual Behaviour

Exception while sending jms messages to Apache ActiveMQ classic queue. Looks like request and release methods in the AbstractPool.java are not thread safe.

For example code

 T object = pool.remove(0);

on line 60 can be executed when where are no elements in the pool. Look the output below.

Output

Micronaut (v3.10.1) 10:15:04.099 [main] DEBUG i.m.j.a.c.c.ActiveMqClassicConfiguration - created ConnectionFactory bean 'activeMqConnectionFactory' (ActiveMQConnectionFactory) for broker URL 'tcp://localhost:61616' 10:15:04.137 [main] DEBUG i.m.j.c.JMSConnectionFactoryBeanProcessor - created JMSConnectionPool bean 'activeMqConnectionFactory' for ConnectionFactory org.apache.activemq.ActiveMQConnectionFactory 10:15:04.181 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 655ms. Server Running: 0 active message listeners. io.micronaut.messaging.exceptions.MessagingClientException: Problem sending message to samples.q1 at io.micronaut.jms.templates.JmsProducer.send(JmsProducer.java:93) at io.micronaut.jms.configuration.JMSProducerMethodInterceptor.intercept(JMSProducerMethodInterceptor.java:116) at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137) at my.samples.micronaut.jms_send_test.MessageProducer$Intercepted.sendToQ1(Unknown Source) at my.samples.micronaut.jms_send_test.Sender1.sendMessage(Sender1.java:14) at my.samples.micronaut.jms_send_test.$Sender1$Definition$Exec.dispatch(Unknown Source) at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invoke(AbstractExecutableMethodsDefinition.java:371) at io.micronaut.inject.DelegatingExecutableMethod.invoke(DelegatingExecutableMethod.java:76) at io.micronaut.scheduling.processor.ScheduledMethodProcessor.lambda$process$5(ScheduledMethodProcessor.java:127) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.base/java.util.LinkedList.checkElementIndex(LinkedList.java:559) at java.base/java.util.LinkedList.remove(LinkedList.java:529) at java.base/java.util.Collections$SynchronizedList.remove(Collections.java:2435) at io.micronaut.jms.pool.AbstractPool.request(AbstractPool.java:60) at io.micronaut.jms.pool.JMSConnectionPool.createConnection(JMSConnectionPool.java:73) at io.micronaut.jms.templates.JmsProducer.send(JmsProducer.java:88) ... 14 more io.micronaut.messaging.exceptions.MessagingClientException: Problem sending message to samples.q1 at io.micronaut.jms.templates.JmsProducer.send(JmsProducer.java:93) at io.micronaut.jms.configuration.JMSProducerMethodInterceptor.intercept(JMSProducerMethodInterceptor.java:116) at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137) at my.samples.micronaut.jms_send_test.MessageProducer$Intercepted.sendToQ1(Unknown Source) at my.samples.micronaut.jms_send_test.Sender2.sendMessage(Sender2.java:14) at my.samples.micronaut.jms_send_test.$Sender2$Definition$Exec.dispatch(Unknown Source) at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invoke(AbstractExecutableMethodsDefinition.java:371) at io.micronaut.inject.DelegatingExecutableMethod.invoke(DelegatingExecutableMethod.java:76) at io.micronaut.scheduling.processor.ScheduledMethodProcessor.lambda$process$5(ScheduledMethodProcessor.java:127) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:829) Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.base/java.util.LinkedList.checkElementIndex(LinkedList.java:559) at java.base/java.util.LinkedList.remove(LinkedList.java:529) at java.base/java.util.Collections$SynchronizedList.remove(Collections.java:2435) at io.micronaut.jms.pool.AbstractPool.request(AbstractPool.java:60) at io.micronaut.jms.pool.JMSConnectionPool.createConnection(JMSConnectionPool.java:73) at io.micronaut.jms.templates.JmsProducer.send(JmsProducer.java:88) ... 14 more

Task :Application.main() FAILED e

Steps To Reproduce

  1. Install and run the Apache ActiveMQ classic 5.18.2
  2. Create a gradle project with micronaut version and dependencies shown above.
  3. Run the application
  4. See the exception in the applicaiton output

Environment Information

OS: ubuntu linux 22.04 JDK: openjdk version "1.8.0_362" Application: gradle project

// gradle.properties
micronautVersion=3.10.1

// build.gradle
plugins {
    id("com.github.johnrengelman.shadow") version "7.1.2"
    id("io.micronaut.minimal.application") version "3.7.10"
}
// skipped
dependencies {
    implementation("io.micronaut.jms:micronaut-jms-activemq-classic")
}
// skipped
micronaut {
    runtime("none")
// skipped
}
// application.yml
micronaut:
  jms:
    activemq:
      classic:
        enabled: true
        connection-string: tcp://localhost:61616
        username: username
        password: password
// MessageProducer.java
@JMSProducer(CONNECTION_FACTORY_BEAN_NAME)
public interface MessageProducer {
    @Queue("samples.q1")
    void sendToQ1(@MessageBody String body);
}

// Sender1.java
@Singleton
public class Sender1 {
    @Inject MessageProducer messageProducer;

    @Scheduled(initialDelay = "10s", fixedDelay = "30s")
    void sendMessage() {
        try {
            messageProducer.sendToQ1("Sender1 test");
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }
}

//Sender2 and Sender3 are the same.

Example Application

No response

Version

3.10.1