Reputation: 372
I am trying to use ActiveMQ in my two spring boot applications, where I want to enqueue an Object in the first app and dequeue it from the second app.
but I have this error
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.javasampleapproach.activemq.jms.consumer.JmsReplyConsumer.receive(com.javasampleapproach.activemq.model.PlaceForm)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Failed to resolve type id [org.sc.oauth2.resource.server.model.PlaceForm]; nested exception is java.lang.ClassNotFoundException: org.sc.oauth2.resource.server.model.PlaceForm
my model PlaceForm (Object which I want to enqueue) is same in the two apps :
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id", scope = PlaceForm.class)
public class PlaceForm implements Serializable{
private Long id;
private String Name;
private double X;
private double Y;
private String Description;
private Long place_type_id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public double getX() {
return X;
}
public void setX(double x) {
X = x;
}
public double getY() {
return Y;
}
public void setY(double y) {
Y = y;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
public Long getPlace_type_id() {
return place_type_id;
}
public void setPlace_type_id(Long place_type_id) {
this.place_type_id = place_type_id;
}
}
and the configuration is the same in tow apps too:
@Configuration
public class ActiveMqConnectionFactoryConfig {
@Value("${jsa.activemq.broker.url}")
String brokerUrl;
@Value("${jsa.activemq.borker.username}")
String userName;
@Value("${jsa.activemq.borker.password}")
String password;
/*
* Initial ConnectionFactory
*/
@Bean
public ConnectionFactory connectionFactory(){
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(brokerUrl);
connectionFactory.setUserName(userName);
connectionFactory.setPassword(password);
return connectionFactory;
}
@Bean // Serialize message content to json using TextMessage
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
/*
* Used for Receiving Message
*/
@Bean
public JmsListenerContainerFactory<?> jsaFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setMessageConverter(jacksonJmsMessageConverter());
configurer.configure(factory, connectionFactory);
return factory;
}
/*
* Used for Sending Messages.
*/
@Bean
public JmsTemplate jmsTemplate(){
JmsTemplate template = new JmsTemplate();
template.setMessageConverter(jacksonJmsMessageConverter());
template.setConnectionFactory(connectionFactory());
return template;
}
}
In the sender app I used:
@Component
public class JmsProducer {
@Autowired
JmsTemplate jmsTemplate;
@Value("${jsa.activemq.queue.producer}")
String queue;
public void send(PlaceForm product) {
jmsTemplate.convertAndSend(queue, product);
}
}
where Application.properties is
jsa.activemq.broker.url=tcp://localhost:61616
jsa.activemq.borker.username=admin
jsa.activemq.borker.password=admin
jsa.activemq.queue.producer=jsa-queue-1
jsa.activemq.queue.consumer=jsa-queue-2
and the dependencies are
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
</dependencies>
and in the reciver app I used:
@Component
public class JmsReplyConsumer {
@Autowired
PlaceService placeservice;
@Autowired
JmsProducer jms;
@JmsListener(destination = "${jsa.activemq.queue.listen}", containerFactory = "jsaFactory")
@SendTo("${jsa.activemq.queue.sendto}")
public void receive(PlaceForm s) {
System.out.println("Done");
}
}
where Application.properties is
jsa.activemq.broker.url=tcp://localhost:61616
jsa.activemq.borker.username=admin
jsa.activemq.borker.password=admin
jsa.activemq.queue.listen=jsa-queue-1
jsa.activemq.queue.sendto=jsa-queue-2
jsa.activemq.queue.send2=jsa-queue-3
and the dependencies are
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
</dependencies>
the "Done" is not printed and the full error is :
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.javasampleapproach.activemq.jms.consumer.JmsReplyConsumer.receive(com.javasampleapproach.activemq.model.PlaceForm)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Failed to resolve type id [org.sc.oauth2.resource.server.model.PlaceForm]; nested exception is java.lang.ClassNotFoundException: org.sc.oauth2.resource.server.model.PlaceForm
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:112) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:69) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:719) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:649) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317) [spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255) [spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1166) [spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1158) [spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1055) [spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_73]
Caused by: org.springframework.jms.support.converter.MessageConversionException: Failed to resolve type id [org.sc.oauth2.resource.server.model.PlaceForm]; nested exception is java.lang.ClassNotFoundException: org.sc.oauth2.resource.server.model.PlaceForm
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:507) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.fromMessage(MappingJackson2MessageConverter.java:228) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:222) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter.extractPayload(AbstractAdaptableMessageListener.java:442) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage.unwrapPayload(AbstractAdaptableMessageListener.java:506) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage.getPayload(AbstractAdaptableMessageListener.java:489) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:113) ~[spring-messaging-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:112) ~[spring-messaging-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:135) ~[spring-messaging-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:107) ~[spring-messaging-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:104) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 10 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.sc.oauth2.resource.server.model.PlaceForm
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_73]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_73]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_73]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_73]
at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:151) ~[spring-boot-devtools-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_73]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:250) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:503) ~[spring-jms-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 20 common frames omitted
can any body help me please???
Upvotes: 4
Views: 4661
Reputation: 723
I also had that same problem, two different applications communicating with ActiveMQ. I solved it by setting the typeIdMappings
property of the converter in both applications.
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
Map<String, Class<?>> typeIdMappings = new HashMap<String, Class<?>>();
typeIdMappings.put("JMS_TYPE", MyObject.class);
converter.setTypeIdMappings(typeIdMappings);
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("JMS_TYPE");
return converter;
}
Upvotes: 4
Reputation: 372
thanks for @justin for his answer, but I want to explain the problem.
the problem is that the two projects use the same model "PlaceForm"
but each of the applications has been declaration the model in its project(first_app has a model "PlaceForm", and the second_app has a model "PlaceForm")
I fixed the problem by deleting "PlaceForm" from the second_app, and making the second_app use first_app as dependency(and use first-app's "PlaceForm").
Upvotes: 0
Reputation: 35038
The root caused-by is this:
Caused by: java.lang.ClassNotFoundException: org.sc.oauth2.resource.server.model.PlaceForm
The class org.sc.oauth2.resource.server.model.PlaceForm
should be available on the classpath on both the sending and receiving application.
Upvotes: 3