首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >测试IBM-MQ的服务器和客户端应用程序中的问题

测试IBM-MQ的服务器和客户端应用程序中的问题
EN

Stack Overflow用户
提问于 2021-10-04 12:36:59
回答 2查看 462关注 0票数 0

我有两个用于测试MQ事件的应用程序。其中一个用于发送消息,另一个用于接收消息。它们都是SpringBoot应用程序。发送者应用程序运行在port: 8000上,接收程序运行在port: 8050上。

pom.xml

代码语言:javascript
复制
    <dependency>
        <groupId>com.ibm.mq</groupId>
        <artifactId>mq-jms-spring-boot-starter</artifactId>
        <version>2.5.0</version>
    </dependency>

这是发送者的应用程序。

代码语言:javascript
复制
@SpringBootApplication
@EnableJms
@RestController
public class MqTestApplication {

    private static final String ISSUER = "254874125487";
    private static final String ACCOUNT_NO = "1234567890123";

    @Autowired
    private JmsTemplate jmsTemplate;

    public static void main(String[] args) {
        SpringApplication.run(MqTestApplication.class, args);
    }

    public Event getEvent() {
        Event event = new Event();
        Map<String, Object> argument = new HashMap<>();
        argument.put("key-accNo", ACCOUNT_NO);
        event.setMessageId(String.valueOf(UUID.randomUUID()));
        event.setIssuer(ISSUER);
        event.setType(EventType.ACCOUNT);
        event.setName(EventName.OPEN_ACCOUNT);
        event.setArgument(argument);
        event.setDateTime(LocalDateTime.now());
        return event;
    }

    @GetMapping("send/event")
    public void sendEvent() {
        try {
            jmsTemplate.convertAndSend("DESTINATION", getEvent());
        } catch (JmsException ex) {
            ex.printStackTrace();
        }
    }
}

接收机应用

代码语言:javascript
复制
@SpringBootApplication
@EnableSwagger2
@EnableJms
public class Application {

public static void main(String[] args) {
       SpringApplication.run(Application.class, args);
}

}
代码语言:javascript
复制
@Service
public class MQServiceImpl{

    private final JmsTemplate jmsTemplate;
    
    @Autowired
    public MQServiceImpl(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    @JmsListener(destination = "DESTINATION")
    public void receiveEvent() {
        Event event = (Event) jmsTemplate.receiveAndConvert("DESTINATION");
        System.out.println(event.toString());
    }    
}

但是当我运行接收应用程序时,我会快速而持续地面对下面的异常。

代码语言:javascript
复制
DefaultMessageListenerContainer-1] WARN  o.s.j.l.DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void .service.MQServiceImpl.receiveEvent()' threw exception; nested exception is org.springframework.jms.MessageFormatException: JMSCC0053: An exception occurred deserializing a message, exception: 'java.lang.ClassNotFoundException: null class'.; nested exception is com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0053: An exception occurred deserializing a message, exception: 'java.lang.ClassNotFoundException: null class'.
It was not possible to deserialize the message because of the exception shown.
Examine the linked exception for details of the error.

Caused by: org.springframework.jms.MessageFormatException: JMSCC0053: An exception occurred deserializing a message, exception: 'java.lang.ClassNotFoundException: null class'.; nested exception is com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0053: An exception occurred deserializing a message, exception: 'java.lang.ClassNotFoundException: null class'.
It was not possible to deserialize the message because of the exception shown.
Examine the linked exception for details of the error.

我查了一下日志,但没有一个答案对我有帮助。如果有人想办法解决这个问题,我很感激。

更新

在发送方和接收方应用程序中,事件类都是这样的。

代码语言:javascript
复制
@Data
public class Event implements Serializable {

    private static final long serialVersionUID = 2529600986924604571L;

    private String messageId;
    private String issuer;
    private EventType type;
    private EventName name;
    private Map<String, Object> argument;
    private LocalDateTime dateTime;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-11 19:16:04

过了几天,我找到了答案。我应该将事件对象转换为JSON,然后从发送方应用程序发送它,并从发送方接收JSON,并将其转换为事件对象。实际上,我们不能通过MQ直接发送或接收对象。

发件人

代码语言:javascript
复制
  String stringEvent = objectMapper.writeValueAsString(EVENT_OBJ);
  jmsTemplate.convertAndSend(SEND_QUEUE_NAME, stringEvent);

接收机

代码语言:javascript
复制
  @Override
    @JmsListener(destination = "${mq.receive_queue}")
    public void receive(Message message) {
        try {
            String jsonEvent = ((TextMessage) message).getText();
            Event event = objectMapper.readValue(jsonEvent, Event.class);
        } catch (JMSException | IOException e) {
            e.printStackTrace();
        }
    }
票数 0
EN

Stack Overflow用户

发布于 2021-10-05 09:12:24

正如在注释中所暗示的那样,您的Event类需要是可序列化的,它看起来是可序列化的,侦听器代码应该如下所示:

代码语言:javascript
复制
@JmsListener(destination = "DESTINATION")
public void receiveEvent(Event event) {
   ...

Spring将负责将对象序列化为@JmsListener注释的一部分。

尽管硬编码目标不是很好,但是您应该从application.properties中提取它。

如果您仍然得到一个

更新,那么正在触发的序列化将无法找到类。如果您的代码正在编译,那么您的类路径中可能有一个类Event,但由于某种原因,它无法与接收应用程序所期望的对象兼容。

从表面上看,似乎您的Event对象是正确的,但是具有相同属性和相同serialVersionUID的类需要同时出现在发送方和接收方代码中。如果你改变了其中一种,那就必须存在于另一种。强制执行此操作的最简单方法是将类放入两个应用程序都使用的.jar中。如果对于发送方和接收方来说,Event类位于不同的包中,那么它将被视为不同的类。

如果您添加了@data注释,spring将为您处理大量的序列化锅炉板。例如:

代码语言:javascript
复制
import lombok.Data;

@Data 
public class Event implements Serializable {    
   ... 

如果这仍然不起作用,那么您可以选择接收ObjectMessage并自己执行序列化。您可能会发现spring自动序列化失败的原因。

例如:

代码语言:javascript
复制
import javax.jms.ObjectMessage; 
import java.io.Serializable;

@JmsListener(destination = "DESTINATION") 
public void receiveEvent(ObjectMessage message) {    
   Serializable serObj = message.getObject();    
   try {
      Event event = (Event) serObj;
      ...    
   } catch (ClassCastException e) {
      ...    
   }    
   ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69436096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档