2016-07-11 7 views
0

Я хочу реализовать RabbitMq (AMQP) обмен сообщениями в java SpringBoot, но когда я получаю сообщение, он говорит, что messaGE не может быть десериализован, потому что я - класс для объекта, который Я должен был получить, не был найден, даже если у меня есть этот класс int classpath.AMQP (RabbitMQ) Не удалось десериализовать объект, ClassNotFoundException

RabbitMqListener.java:

@EnableRabbit 
@Component 
public class RabbitMqListener { 
    Logger logger = Logger.getLogger(RabbitMqListener.class); 

    @RabbitListener(queues = "queue2") 
    public void processQueue1(Product message) { 

     logger.info("Received from queue 2: " + message); 
    } 

} 

RabbitConfiguration.java:

@Configuration 
public class RabbitConfiguration { 
    Logger logger = Logger.getLogger(RabbitConfiguration.class); 
    @Bean 
    public ConnectionFactory connectionFactory() { 
     CachingConnectionFactory connectionFactory = 
       new CachingConnectionFactory("localhost"); 
     return connectionFactory; 
    } 

    @Bean 
    public AmqpAdmin amqpAdmin() { 
     return new RabbitAdmin(connectionFactory()); 
    } 

    @Bean 
    public MessageConverter jsonMessageConverter(){ 
     return new JsonMessageConverter(); 
    } 

    @Bean 
    public RabbitTemplate rabbitTemplate() { 
     RabbitTemplate template = new RabbitTemplate(connectionFactory()); 
     template.setMessageConverter(jsonMessageConverter()); 
     return template; 
    } 


    @Bean 
    public Queue myQueue1() { 

     return new Queue("queue1"); 
    } 

    @Bean 
    public Queue myQueue2() { 

     return new Queue("queue2"); 
    } 

} 

SampleController.java:

@Controller 
public class SampleController { 
    Logger logger = Logger.getLogger(SampleController.class); 

    @Autowired 
    AmqpTemplate template; 

    @RequestMapping("/emit") 
    @ResponseBody 
    String queue1() { 
     logger.info("Emit to queue1"); 
     template.convertAndSend("queue1","Message to queue 1"); 
     return "Emit to queue 1"; 
    } 
} 

Product.java:

public class Product implements Serializable{ 

    private Long id; 

    private String name; 

    private int stock; 

    private int price; 



    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getStock() { 
     return stock; 
    } 

    public void setStock(int stock) { 
     this.stock = stock; 
    } 

    public Product() { 
    } 

    @Override 
    public String toString() { 
     return "Product{" + 
       "id=" + id + 
       ", name='" + name + '\'' + 
       ", stock=" + stock + 
       ", price=" + price + 
       '}'; 
    } 
} 

И StackTrace:

2016-07-11 09:34:02.840 WARN [order-service,,,] 4084 --- [cTaskExecutor-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed. 

org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:865) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:760) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:680) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:93) [spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:183) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1358) [spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:661) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1102) [spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1086) [spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1100(SimpleMessageListenerContainer.java:93) [spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1203) [spring-rabbit-1.5.6.RELEASE.jar:na] 
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91] 
Caused by: java.lang.IllegalStateException: Could not deserialize object type 
    at org.springframework.amqp.utils.SerializationUtils.deserialize(SerializationUtils.java:82) ~[spring-amqp-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.support.converter.SimpleMessageConverter.fromMessage(SimpleMessageConverter.java:110) ~[spring-amqp-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:185) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter$MessagingMessageConverterAdapter.extractPayload(MessagingMessageListenerAdapter.java:173) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.support.converter.MessagingMessageConverter.fromMessage(MessagingMessageConverter.java:118) ~[spring-amqp-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.toMessagingMessage(MessagingMessageListenerAdapter.java:102) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:88) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:757) ~[spring-rabbit-1.5.6.RELEASE.jar:na] 
    ... 10 common frames omitted 
Caused by: java.lang.ClassNotFoundException: com.productservice.model.Product 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91] 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91] 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_91] 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91] 
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:250) ~[spring-core-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.core.ConfigurableObjectInputStream.resolveClass(ConfigurableObjectInputStream.java:75) ~[spring-core-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.amqp.support.converter.SimpleMessageConverter$1.resolveClass(SimpleMessageConverter.java:179) ~[spring-amqp-1.5.6.RELEASE.jar:na] 
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620) ~[na:1.8.0_91] 
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521) ~[na:1.8.0_91] 
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781) ~[na:1.8.0_91] 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) ~[na:1.8.0_91] 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373) ~[na:1.8.0_91] 
    at org.springframework.amqp.utils.SerializationUtils.deserialize(SerializationUtils.java:76) ~[spring-amqp-1.5.6.RELEASE.jar:na] 
    ... 17 common frames omitted 


Process finished with exit code -1 
+0

Он похож на специфический для класса класс путь и не связан с amqp или rabbitMQ> Пожалуйста, повторите установку проекта еще раз – Karthik

+1

Обнаружена проблема. Обмен сообщениями происходит между двумя модулями, в одном модуле у меня есть Person.java, а в другом модуле у меня есть еще один Person.java, для десериализации мне нужен точно такой же класс, поэтому решение состоит в создании нового общего модуля, который содержит Person.java и импортировать его в приемник и в модули эмиттера. –

+0

@FlaviuCicio: вы также можете преобразовать сообщение в json перед отправкой и конвертированием обратно на свой объект при получении, если это позволяют ваши требования. Таким образом, вы получаете гораздо большую гибкость, чтобы обрабатывать данные, когда они получены. Кроме того, этот метод может упростить ваш код, поскольку вы будете отправлять и получать только строку. У –

ответ

2

В фрагменте кода вы зарегистрировали jsonMessageConverter и в то же время вы делаете ваш Person.java сериализации. Вы должны использовать сериализацию или подход json. Кроме того, проблема заключается в структуре пакета Person.java. Я столкнулся с той же проблемой, разрешив ее, взяв ту же структуру пакета для объекта, который передается производителем и потребителем. Причина этого заключается в том, что при сериализации java принимает во внимание имя класса, структуру пакета и другую информацию, поэтому на стороне потребителя нам нужно иметь ту же структуру пакетов. Я столкнулся с такой же проблемой при использовании jsonMessageConverter. Поэтому с моей точки зрения решение этой проблемы заключается в том, чтобы упаковать ваши объекты сообщений в банку и добавить эту банку в качестве зависимости в вашем проекте производителя и потребителя.

+0

был тот же случай. если вы используете на обеих сторонах ту же структуру, она будет работать. – DOUBL3P

Смежные вопросы