JMS

 
0
 
Java
ava
Kizja | 17.12.2009, 01:45
Привет, у меня возник вопрос про JMS: если например есть два приложения, одно из которых посылает сообщения через JMS, а другое их слушает, то всё ясно - в примерах обычно показывается, что в while (true) цикле проверяется не пришло ли новое сообщение и если пришло, то оно обрабатывается...

А что делать, если эти два приложения должны обмениваться сообщениями между собой, но так же и выполнять другие действия параллельно с ожиданием сообщений ?

Т.е. у меня есть два приложения и в них я хочу прилепить посылку и приём сообщений и не знаю как сделать, чтобы они работали как и раньше, но и плюс к этому ждали так же посылаемые им сообщения.

В таком случае надо использовать отдельный Thread для приёма сообщений или как надо сделать ? Было бы замечательно увидеть какой-нибудь пример... В нете искал, но там в основном именно так, что приёмник только занимается тем, что висит и слушает, ничего другого не делая...
Ответы (4)
ava
MisterCleric | 17.12.2009, 11:01 #
Привет. А что за архитектура такая?
Почему нельзя пойти стандартными путями, используя средства J2EE: EJB?
Тебе надо взять какой-нибудь сервер приложений и посмотреть примеры как посылку и прем сделать с помощью EJB.
Можно, конечно, еще посмотреть в сторону каких-нибудь сторонних реализаций MQ, например: ActiveMQ.

Я просто впервые с JMS столкнулся именно в сервере приложений. Это был JBOSS. И таких вопросов у меня не возникало.

А вообще представленная тобой логика реализуется с помощью ESB, но это совесем другая история, хоть она и базируется на JMS.
ava
AxNe0 | 17.12.2009, 12:57 #
согласен, что лучше использовать готовый сервер и ejb. Message-driven beans, кажется полностью удовлетворяют требованиям
ava
Kizja | 21.12.2009, 00:21 #
MisterCleric, AxNe0 спасибо за ответ!

Решил использовать spring + message-driven pojo на jboss сервере. Закинул war в JBOSS_HOME\server\default\deploy, сообщения стали приниматься, но возникла такая проблема, что принимаются лишь javax.jms.TextMessage и javax.jms.MapMessage, возможно ещё какие-то другие, но факт тот, что вылазит ошибка при приёме javax.jms.ObjectMessage:


22:59:48,891 INFO [STDOUT] 22:59:48,890 WARN [SimpleMessageListenerContainer]
Execution of JMS message listener failed
java.lang.RuntimeException: Person
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.jboss.classloader.spi.base.BaseClassLoaderDomain.loadClass(BaseCl
assLoaderDomain.java:292)
at org.jboss.classloader.spi.base.BaseClassLoaderDomain.loadClass(BaseCl
assLoaderDomain.java:1119)
at org.jboss.classloader.spi.base.BaseClassLoader.loadClassFromDomain(Ba
seClassLoader.java:798)
at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoa
der.java:441)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:604)
at org.jboss.messaging.util.ObjectInputStreamWithClassLoader.resolveClas
s(ObjectInputStreamWithClassLoader.java:78)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:157
5)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1
732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at org.jboss.messaging.util.StreamUtils.readObject(StreamUtils.java:154)

at org.jboss.messaging.core.impl.message.MessageSupport.readPayload(Mess
ageSupport.java:392)
at org.jboss.jms.message.JBossObjectMessage.getObject(JBossObjectMessage
.java:126)
at org.jboss.jms.message.ObjectMessageProxy.getObject(ObjectMessageProxy
.java:68)
at message.converter.CustomerMessageConverter.fromMessage(CustomerMessag
eConverter.java:27)
at message.converter.CustomerMessageConverter.fromMessage(CustomerMessag
eConverter.java:15)
at org.springframework.jms.listener.adapter.MessageListenerAdapter.extra
ctMessage(MessageListenerAdapter.java:396)
at org.springframework.jms.listener.adapter.MessageListenerAdapter.onMes
sage(MessageListenerAdapter.java:327)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doI
nvokeListener(AbstractMessageListenerContainer.java:485)
at org.springframework.jms.listener.AbstractMessageListenerContainer.inv
okeListener(AbstractMessageListenerContainer.java:442)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doE
xecuteListener(AbstractMessageListenerContainer.java:414)
at org.springframework.jms.listener.AbstractMessageListenerContainer.exe
cuteListener(AbstractMessageListenerContainer.java:386)
at org.springframework.jms.listener.SimpleMessageListenerContainer$2.onM
essage(SimpleMessageListenerContainer.java:204)
at org.jboss.jms.client.container.ClientConsumer.callOnMessage(ClientCon
sumer.java:229)
at org.jboss.jms.client.container.ClientConsumer$ListenerRunner.run(Clie
ntConsumer.java:1043)
at org.jboss.messaging.util.OrderedExecutorFactory$ChildExecutor.run(Ord
eredExecutorFactory.java:120)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec
utor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
.java:907)
at java.lang.Thread.run(Thread.java:619)



Изменения в коде между TextMessage и ObjectMessage лишь в том, что для TextMessage выполняется:


import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;

public class TextMessageConverter implements MessageConverter {
@Override
public String fromMessage(Message message) throws JMSException,
MessageConversionException {
if (!(message instanceof TextMessage)) {
throw new MessageConversionException(
"Message isn't a TextMessage");
}
return ((TextMessage) message).getText();
}

}


и посылка:


MessageProducer producer = session.createProducer(destination);

TextMessage message = session.createTextMessage("Hello world");

producer.send(message);


а для ObjectMessage:


import java.io.Serializable;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import message.bean.Person;

import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;

public class ObjectMessageConverter implements MessageConverter {

public Serializable fromMessage(Message message) throws JMSException,
MessageConversionException {
if (!(message instanceof ObjectMessage)) {
throw new MessageConversionException("Message isn't a ObjectMessage");
}
return ((ObjectMessage) message).getObject();
}

}


и посылка:


MessageProducer producer = session.createProducer(destination);

ObjectMessage message = session.createObjectMessage();
Person person = new Person();
person.setFirstName("FirstName");
person.setLastName("LastName");
person.setNickName("NickName");
message.setObject(person);

producer.send(message);


Класс Person:


import java.io.Serializable;

public class Person implements Serializable {
private Integer id;
private String firstName;
private String lastName;
private String nickName;

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
}


Судя по этой части ошибки:

at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)

он не может найти класс, который получает из сообщения, но он есть в war архиве, не понимаю, почему он его не видит ?
ava
Kizja | 22.12.2009, 00:00 #
С этой ошибкой трахаюсь уже вторые сутки, не могу понять как исправить...

Если я не ошибаюсь, то возможно у меня что-то не так в pom.xml и мавен пакует неправильно war файл, в результате чего вроде как jboss не видит при получении сообщения нужные классы.

Запускаю на jboss-5.1.0.GA.
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить