SimpleMessageListenerContainer - AMQP 接收消息时出现 ClassNotFoundException 警告
SimpleMessageListenerContainer - ClassNotFoundException warning on AMQP receive message
我刚刚将我的应用程序更新到 spring-integration-amqp-5.2.4.RELEASE
版本,当我从队列中收到消息时一切正常,但我注意到 DefaultAmqpHeaderMapper
class 中的警告 java.lang.ClassNotFoundException
。我使用自定义 DefaultJackson2JavaTypeMapper
和 IdClassMapping
。如何避免跟踪警告?
@Bean
public Jackson2JavaTypeMapper defaultJackson2JavaTypeMapper() {
DefaultJackson2JavaTypeMapper defaultJackson2JavaTypeMapper = new DefaultJackson2JavaTypeMapper();
Map<String, Class<?>> classMapping = new HashMap<>();
classMapping.put("event.request", RequestDTO.class);
defaultJackson2JavaTypeMapper.setIdClassMapping(classMapping);
return defaultJackson2JavaTypeMapper;
}
@Bean
public MessageConverter messageConverterJson(ObjectMapper objectMapper) {
Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter(objectMapper);
messageConverter.setJavaTypeMapper(defaultJackson2JavaTypeMapper());
return messageConverter;
}
日志警告
o.s.i.a.support.DefaultAmqpHeaderMapper : error occurred while mapping from AMQP properties to MessageHeaders
java.lang.IllegalStateException: java.lang.ClassNotFoundException: event.request
at org.springframework.integration.mapping.support.JsonHeaders.getClassForValue(JsonHeaders.java:89)
at org.springframework.integration.mapping.support.JsonHeaders.buildResolvableType(JsonHeaders.java:72)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.createJsonResolvableTypHeaderInAny(DefaultAmqpHeaderMapper.java:169)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.extractStandardHeaders(DefaultAmqpHeaderMapper.java:155)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.extractStandardHeaders(DefaultAmqpHeaderMapper.java:61)
at org.springframework.integration.mapping.AbstractHeaderMapper.toHeaders(AbstractHeaderMapper.java:266)
at org.springframework.integration.mapping.AbstractHeaderMapper.toHeadersFromRequest(AbstractHeaderMapper.java:203)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.toHeadersFromRequest(DefaultAmqpHeaderMapper.java:337)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.toHeadersFromRequest(DefaultAmqpHeaderMapper.java:61)
at org.springframework.integration.amqp.inbound.AmqpInboundGateway$Listener.convert(AmqpInboundGateway.java:351)
at org.springframework.integration.amqp.inbound.AmqpInboundGateway$Listener.onMessage(AmqpInboundGateway.java:314)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1579)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1486)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1477)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1421)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:963)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access00(SimpleMessageListenerContainer.java:81)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: event.request
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:92)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:282)
at org.springframework.integration.mapping.support.JsonHeaders.getClassForValue(JsonHeaders.java:86)
... 21 common frames omitted
由于您已经通过 Jackson2JsonMessageConverter
将 AMQP 消息映射到目标负载中,看起来您根本不需要任何传入的 headers。
为了避免警告和额外的映射工作,我建议您注入自定义 AmqpHeaderMapper
。可能只是 DefaultAmqpHeaderMapper
的扩展,当你 return 一个空的 headers 用于从请求映射时:
amqpInboundGateway.setHeaderMapper(new DefaultAmqpHeaderMapper(null, null) {
@Override
public Map<String, Object> toHeadersFromRequest(MessageProperties source) {
return new HashMap<>();
}
});
另一方面,它只是一个警告:您可以简单地将 org.springframework.integration.amqp.inbound
类别的日志记录级别降低到错误。
关键是,如果我们找不到 __Type__
header 的 class,我们不能忽略这样的错误。该框架无法做出您所期望的假设。
另一种可能的修复方法是在覆盖 fromMessage()
时从 Jackson2JsonMessageConverter
扩展的 MessageProperties.getHeaders()
中删除那些 JSON header。
我刚刚将我的应用程序更新到 spring-integration-amqp-5.2.4.RELEASE
版本,当我从队列中收到消息时一切正常,但我注意到 DefaultAmqpHeaderMapper
class 中的警告 java.lang.ClassNotFoundException
。我使用自定义 DefaultJackson2JavaTypeMapper
和 IdClassMapping
。如何避免跟踪警告?
@Bean
public Jackson2JavaTypeMapper defaultJackson2JavaTypeMapper() {
DefaultJackson2JavaTypeMapper defaultJackson2JavaTypeMapper = new DefaultJackson2JavaTypeMapper();
Map<String, Class<?>> classMapping = new HashMap<>();
classMapping.put("event.request", RequestDTO.class);
defaultJackson2JavaTypeMapper.setIdClassMapping(classMapping);
return defaultJackson2JavaTypeMapper;
}
@Bean
public MessageConverter messageConverterJson(ObjectMapper objectMapper) {
Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter(objectMapper);
messageConverter.setJavaTypeMapper(defaultJackson2JavaTypeMapper());
return messageConverter;
}
日志警告
o.s.i.a.support.DefaultAmqpHeaderMapper : error occurred while mapping from AMQP properties to MessageHeaders
java.lang.IllegalStateException: java.lang.ClassNotFoundException: event.request
at org.springframework.integration.mapping.support.JsonHeaders.getClassForValue(JsonHeaders.java:89)
at org.springframework.integration.mapping.support.JsonHeaders.buildResolvableType(JsonHeaders.java:72)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.createJsonResolvableTypHeaderInAny(DefaultAmqpHeaderMapper.java:169)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.extractStandardHeaders(DefaultAmqpHeaderMapper.java:155)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.extractStandardHeaders(DefaultAmqpHeaderMapper.java:61)
at org.springframework.integration.mapping.AbstractHeaderMapper.toHeaders(AbstractHeaderMapper.java:266)
at org.springframework.integration.mapping.AbstractHeaderMapper.toHeadersFromRequest(AbstractHeaderMapper.java:203)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.toHeadersFromRequest(DefaultAmqpHeaderMapper.java:337)
at org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper.toHeadersFromRequest(DefaultAmqpHeaderMapper.java:61)
at org.springframework.integration.amqp.inbound.AmqpInboundGateway$Listener.convert(AmqpInboundGateway.java:351)
at org.springframework.integration.amqp.inbound.AmqpInboundGateway$Listener.onMessage(AmqpInboundGateway.java:314)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1579)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1498)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1486)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1477)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1421)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:963)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:913)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access00(SimpleMessageListenerContainer.java:81)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1284)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1190)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: event.request
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:92)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:282)
at org.springframework.integration.mapping.support.JsonHeaders.getClassForValue(JsonHeaders.java:86)
... 21 common frames omitted
由于您已经通过 Jackson2JsonMessageConverter
将 AMQP 消息映射到目标负载中,看起来您根本不需要任何传入的 headers。
为了避免警告和额外的映射工作,我建议您注入自定义 AmqpHeaderMapper
。可能只是 DefaultAmqpHeaderMapper
的扩展,当你 return 一个空的 headers 用于从请求映射时:
amqpInboundGateway.setHeaderMapper(new DefaultAmqpHeaderMapper(null, null) {
@Override
public Map<String, Object> toHeadersFromRequest(MessageProperties source) {
return new HashMap<>();
}
});
另一方面,它只是一个警告:您可以简单地将 org.springframework.integration.amqp.inbound
类别的日志记录级别降低到错误。
关键是,如果我们找不到 __Type__
header 的 class,我们不能忽略这样的错误。该框架无法做出您所期望的假设。
另一种可能的修复方法是在覆盖 fromMessage()
时从 Jackson2JsonMessageConverter
扩展的 MessageProperties.getHeaders()
中删除那些 JSON header。