Activemq JmsTemplate JMSDeliveryTime 错误

Activemq JmsTemplate JMSDeliveryTime Error

美好的一天, 我是 ActiveMQ 的新手并且正在尝试学习,但是当我使用 JMSDeliveryTime 在发布之前延迟我的消息时出现此错误。任何遇到此错误的人请帮助。我搜索了类似的主题,我注意到有人说这是因为 JMS 2.0,但事实并非如此。我正在使用 ActiveMQ 经典版。

java.lang.AbstractMethodError: Receiver class org.apache.activemq.command.ActiveMQTextMessage does not define or inherit an implementation of the resolved method 'abstract void setJMSDeliveryTime(long)' of interface javax.jms.Message.
    at com.activemq.poc5.ProducerResource.postProcessMessage(ProducerResource.java:38) ~[classes/:na]
    at org.springframework.jms.core.JmsTemplate.lambda$convertAndSend(JmsTemplate.java:682) ~[spring-jms-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:604) ~[spring-jms-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jms.core.JmsTemplate.lambda$send(JmsTemplate.java:577) ~[spring-jms-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504) ~[spring-jms-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:576) ~[spring-jms-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:680) ~[spring-jms-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at com.activemq.poc5.ProducerResource.publish(ProducerResource.java:35) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at 

我正在发送的 API 电话

    @GetMapping("/{message}")
    public String publish(@PathVariable("message")
            final String message) {

        for (int i = 1; i <= 3; i++) {
           // jmsTemplate.setPriority(2);
//            jmsTemplate.convertAndSend(queue, message); //this method sends the given object to the queue destination, converting the object to JMS message
           jmsTemplate.convertAndSend(queue, message, new MessagePostProcessor() {
               @Override
               public Message postProcessMessage(Message msg) throws JMSException {
                   msg.setJMSDeliveryTime(20000);
                   return msg;
               }
           });
           
        }
        return "Published Successfully";
    }

我使用 ScheduledMessage 而不是 JMSDeliveryDelay 解决了我的问题

    jmsTemplate.convertAndSend(queue, message, new MessagePostProcessor() {
        @Override
        public Message postProcessMessage(Message msg) throws JMSException {
            msg.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000);
            return msg;
        }
    });
}

确实,错误消息没有明确说问题是与 JMS 2 不兼容,但 实际上是问题。 ActiveMQ 5.x(即“经典”)仅实现 JMS 1.1。它没有实现 JMS 2.0。 setJMSDeliveryTime 方法是在 JMS 2.0 中添加的。因此,您不能将 setJMSDeliveryTime 与 ActiveMQ 5.x 客户端一起使用。

在评论中您说您正在使用 spring-boot-starter-activemq 依赖项。此依赖项明确排除了 JMS 1.1 API:

      <exclusions>
        <exclusion>
          <artifactId>geronimo-jms_1.1_spec</artifactId>
          <groupId>org.apache.geronimo.specs</groupId>
        </exclusion>
      </exclusions>

而是包含雅加达版本:

    <dependency>
      <groupId>jakarta.jms</groupId>
      <artifactId>jakarta.jms-api</artifactId>
      <scope>compile</scope>
    </dependency>

这个依赖的版本是2.0.3,支持JMS 2.0。这意味着 JMS API 版本实际上与 ActiveMQ 5.x 客户端不兼容,这就是您的 IDE and/or 编译器不抱怨您正在使用的原因不支持的方法(即 setJMSDeliveryTime)。

我建议您从您的类路径中删除 JMS 2.0 API(例如,在您的 Maven 依赖项中使用您自己的 <excludes>),这样您就可以在构建时捕获这些类型的错误您可以利用类似 ActiveMQ 的 scheduled message functionality or move to a client/broker that actually supports JMS 2.0 like ActiveMQ Artemis.

如果您选择坚持使用 ActiveMQ 5.x 并使用其计划的消息功能,那么如果您将来转移到不同的 JMS 代理,您的应用程序将无法正常运行,因为 ActiveMQ [=] 使用的属性41=] 来实现计划的消息功能,对 ActiveMQ 来说是独一无二的。但是,如果移动到支持 JMS 2.0 的代理并使用标准 setJMSDeliveryTime,那么您的应用程序将能够在支持 JMS 2.0 的 任何 代理上工作。