Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / WebService, EJB, JMS сообщение застревает в транзакции / 20 сообщений из 20, страница 1 из 1
25.06.2013, 13:28:13
    #38309465
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
Добрый день. Такая вот проблема. Есть веб сервис, один из методов которого должен отправлять сообщения в очередь JMS. На другом компьютере развернуто приложение смотрит на эту очередь и отвечает на сообщения.
Веб-сервис:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
@Stateless()
@WebService(serviceName = "Dev-test")
public class MessageSender {
    
    // BEGIN // JMS Block //
    
    @Resource(lookup = "ConnectionFactory")
    private ConnectionFactory connectionFactory;
    
    @Resource(lookup = "ServerQueue")
    private Destination serverQueue;
    
    Connection connection = null;
    
//    @PostConstruct
//    public void makeConnection() {
//        try {
//            connection = connectionFactory.createConnection();
//        } catch (Throwable t) {
//        }
//    }
//
//    @PreDestroy
//    public void endConnection() throws RuntimeException {
//        if (connection != null) {
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
//        }
//    }
    
    private String sendMessage(String message, String messageType) {
        String response = null;
        try {
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer requestProducer = (MessageProducer) session.createProducer(serverQueue);
            TemporaryQueue replyQueue = session.createTemporaryQueue();
            MessageConsumer replyConsumer = session.createConsumer(replyQueue);
            
            connection.start();
        
            // Create message for sending
            TextMessage textMessage = session.createTextMessage();
            textMessage.setJMSType(messageType);
            textMessage.setText(message);
            textMessage.setJMSReplyTo(replyQueue);
            
            requestProducer.send(textMessage);
            
            Message messageFromReplyQueue = replyConsumer.receive();
            TextMessage textMessageFromReplyQueue = (TextMessage) messageFromReplyQueue;
            response = textMessageFromReplyQueue.getText();
        } catch (JMSException ex) { 
            
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) {
            }
        }
        return response;
    }
}



Приложение на другой машине:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@MessageDriven(mappedName = "ServerQueue")
public class SAMMessageConsumer implements MessageListener {
    @Resource(name = "ConnectionFactory")
    private ConnectionFactory connectionFactory;

    @Override
    public void onMessage(Message message) {
        //....
    }
}



Все бы хорошо, но все сообщения, отправленные из веб-сервиса попадают в "Held in Transaction" если верить браузеру очередей под названием QBrowser_light_V2.5.2.8.1_forJDK1.6 (см. атач).

Попробовал проделать все тоже самое, только на месте веб-сервиса развернул страницу JSP и сервлет. Вот код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
@WebServlet(name = "MessageSender", urlPatterns = {"/MessageSender"})
public class MessageSender extends HttpServlet implements MessageListener {
    
    private Session session;
    private MessageProducer requestProducer;
    private MessageConsumer replyConsumer;
    
    @Resource(name = "ConnectionFactory")
    private ConnectionFactory connectionFactory;
    
    @Resource(name = "ServerQueue")
    private Destination serverQueue;
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String log = this.sendMessage(request.getParameter("message"));
        PrintWriter printWriter = response.getWriter();
        printWriter.print(log);
        printWriter.flush();
    }
    
    private String sendMessage (String message) {
        Connection connection = null;
        try {            
            connection = connectionFactory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            
            requestProducer = (MessageProducer) session.createProducer(serverQueue);
                        
            TemporaryQueue replyQueue = session.createTemporaryQueue();
            replyConsumer = session.createConsumer(replyQueue);
            
            connection.start();
            
            // Create message for sending
            TextMessage textMessage = session.createTextMessage();
            textMessage.setJMSType(MessageType.GET_KEYS.toString());
            textMessage.setText(message);
            textMessage.setJMSReplyTo(replyQueue);
            
            requestProducer.send(textMessage);
                        
            Message messageFromReplyQueue = replyConsumer.receive();
            TextMessage textMessageFromReplyQueue = (TextMessage) messageFromReplyQueue;
                        
        } catch (JMSException ex) {
            Logger.getLogger(MessageSender.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            
        }
        return textMessageFromReplyQueue.getText();        
    }

    @Override
    public void onMessage(Message message) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}



И все прекрасно работает! Сообщения складываются в "Actual" (если опять же смотреть в браузер) и сразу поступают на обработку в приложение обработчика и успешно получает ответ. Есть какие-нибудь мысли по этому поводу?
...
Рейтинг: 0 / 0
25.06.2013, 13:51:38
    #38309505
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgeny,

Конечно есть, jms в рамках транзакции работает, поэтому в одном методе отправить сообщение и получить ответ на него не получится.
...
Рейтинг: 0 / 0
25.06.2013, 13:55:55
    #38309516
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
забыл ник,

Дело в том, что "обработчик сообщений" работает нормально. Он вполне адекватно обрабатывает сообщения, которые к нему приходят из очереди (например случай с реализацией через сервлет). Даже если из этого браузера очереди послать сообщение - обработчик все делает как нужно. А когда все это добро начинаю возводить в рамках веб сервиса всплывают транзакции, а не просто сообщения. Я не могу понять, почему они являются транзакциям.
...
Рейтинг: 0 / 0
25.06.2013, 13:58:43
    #38309521
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgenyзабыл ник,

Дело в том, что "обработчик сообщений" работает нормально. Он вполне адекватно обрабатывает сообщения, которые к нему приходят из очереди (например случай с реализацией через сервлет). Даже если из этого браузера очереди послать сообщение - обработчик все делает как нужно. А когда все это добро начинаю возводить в рамках веб сервиса всплывают транзакции, а не просто сообщения. Я не могу понять, почему они являются транзакциям.
Сообщение, которое я отправляю через веб сервис даже не поступает в "обработчик сообщений". Я немного плаваю в этой теме. Может подскажете правильную реализацию такого взаимодействия WebService <-> JMS.
...
Рейтинг: 0 / 0
25.06.2013, 15:09:23
    #38309624
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgenyVorobyevEvgenyзабыл ник,

Дело в том, что "обработчик сообщений" работает нормально. Он вполне адекватно обрабатывает сообщения, которые к нему приходят из очереди (например случай с реализацией через сервлет). Даже если из этого браузера очереди послать сообщение - обработчик все делает как нужно. А когда все это добро начинаю возводить в рамках веб сервиса всплывают транзакции, а не просто сообщения. Я не могу понять, почему они являются транзакциям.
Сообщение, которое я отправляю через веб сервис даже не поступает в "обработчик сообщений". Я немного плаваю в этой теме. Может подскажете правильную реализацию такого взаимодействия WebService <-> JMS.

Дело в том что сообщение не отправляеться потому что в EJB контэйнере при менеджед транзакция - это декларативная транзакция, по умолчанию она Requared и соответственно ее границы - начало предидущей если была и выход из метода. У тебя транзакция завершаеться после выхода из метода sendMessage(), этот метод в свою очередь ждет сообщения на replyConsumer.receive(); (а сообщение которое ожидает replyConsumer.receive() может быть только после выхода из мтода sendMessage() ) в общем замкнутый круг :)
...
Рейтинг: 0 / 0
25.06.2013, 15:13:36
    #38309632
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
OOsalivanVorobyevEvgenyпропущено...

Сообщение, которое я отправляю через веб сервис даже не поступает в "обработчик сообщений". Я немного плаваю в этой теме. Может подскажете правильную реализацию такого взаимодействия WebService <-> JMS.

Дело в том что сообщение не отправляеться потому что в EJB контэйнере при менеджед транзакция - это декларативная транзакция, по умолчанию она Requared и соответственно ее границы - начало предидущей если была и выход из метода. У тебя транзакция завершаеться после выхода из метода sendMessage(), этот метод в свою очередь ждет сообщения на replyConsumer.receive(); (а сообщение которое ожидает replyConsumer.receive() может быть только после выхода из мтода sendMessage() ) в общем замкнутый круг :)

Интересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?
...
Рейтинг: 0 / 0
25.06.2013, 15:20:47
    #38309652
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgeny,

Разбить на два метода.
Послыаете сообщение в очередь, у сообщения устанавливаете атрибут что-то вроде destination. Метод заканчивается сообщение попадает в очередь. На втором конце вы получаете сообщение обрабатываете его и посылаете ответ в destination. Третья фаза - вы слушаете destination и получаете там ответ. Как-то так.
...
Рейтинг: 0 / 0
25.06.2013, 15:24:39
    #38309658
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgeny } catch (JMSException ex) {

}
} catch (Exception e) {
}

Так и пишете? Правда?
...
Рейтинг: 0 / 0
25.06.2013, 15:28:10
    #38309668
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
забыл ник,

Ну это я понимаю :)
Вопрос в том, что когда я отправляю сообщение "обработчику" я в сообщении указываю временную очередь - TemporaryQueue replyQueue = session.createTemporaryQueue() и textMessage.setJMSReplyTo(replyQueue). А в обработчике достаю эту временную очередь и отправляю ответ а нее. Другими словами, каждый клиент веб сервиса при обращении к методу создает свою временную очередь и ждет ответ в нее... То есть на третьей фазе нужно как то знать ту очередь, которую прилепили к сообщению.

Ладно, сейчас буду пробовать ;-)
...
Рейтинг: 0 / 0
25.06.2013, 15:30:34
    #38309676
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
BlazkowiczVorobyevEvgeny } catch (JMSException ex) {

}
} catch (Exception e) {
}

Так и пишете? Правда?
Да что всех одно и то же цепляет-то? А
Код: java
1.
2.
3.
4.
@Override
    public void onMessage(Message message) {
        //....
    }


В обработчике сообщений вас не смущает? :-) Я постарался удалить все линии кода, которые не относятся к сути проблемы (на мой взгляд не относятся).
...
Рейтинг: 0 / 0
25.06.2013, 15:33:57
    #38309682
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgenyИнтересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?
Для начала вам нужно определится как должен вести себя Web Service в случае. Он будет держать входящий запрос не важно как долго, пока не получит ответ? Тогда нужно что-то с Future заюзать.
http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html
...
Рейтинг: 0 / 0
25.06.2013, 16:11:06
    #38309777
OOsalivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
BlazkowiczVorobyevEvgenyИнтересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?
Для начала вам нужно определится как должен вести себя Web Service в случае. Он будет держать входящий запрос не важно как долго, пока не получит ответ? Тогда нужно что-то с Future заюзать.
http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html

Вообще с появлением в J2ee6 асинхронных методов необходимость в JMS при асинхронном в заимодействии уже не так критична. Многие задачи решаються через колбэки.

VorobyevEvgenyИнтересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?

Можно убрать тразакцию - поставив над методом другой атрибут (например NOT_SUPPORTED), можно использовать бин-менеджет транзакцию и указать ее границы самостоятельно, можно как уже было сказанно выше сделать два бина или (селфпрокси) один отсылает, другой ожидает ответа
...
Рейтинг: 0 / 0
25.06.2013, 16:13:02
    #38309783
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
Всем спасибо! Взлетело вот так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
...
            //requestProducer.send(textMessage);
            this.send(requestProducer, textMessage);
...

    private void send (MessageProducer mp, TextMessage tm) {
        try {
            mp.send(tm);
        } catch (JMSException ex) {
            Logger.getLogger(Authorization.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
...


Blazkowicz, да, будет просто ждать. Предполагается, что обработчик сообщений будет отвечать моментально.
...
Рейтинг: 0 / 0
25.06.2013, 16:20:41
    #38309816
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgenyBlazkowicz, да, будет просто ждать. Предполагается, что обработчик сообщений будет отвечать моментально.
Ну, и кому нужна такая асинхронность, если один ждет другого? :)
...
Рейтинг: 0 / 0
25.06.2013, 16:23:24
    #38309823
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
OOsalivanВообще с появлением в J2ee6 асинхронных методов необходимость в JMS при асинхронном в заимодействии уже не так критична. Многие задачи решаються через колбэки.

С каким ещё "появлением"? Всегда было:
http://docs.oracle.com/javaee/1.4/api/javax/resource/spi/work/WorkManager.html
...
Рейтинг: 0 / 0
25.06.2013, 16:27:18
    #38309836
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgeny,

По-моему, у вас показательный пример как простые вещи делать сложно. Я бы вынес логику в Session Bean и использовал бы его как напрямую, так и через MDB, когда нужна асинхронность.
...
Рейтинг: 0 / 0
25.06.2013, 16:41:40
    #38309887
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
Мужики, я не претендую на лучшее решение. Была задача реализовать такое взаимодействие, с вашими подсказками я с ней справился. Спасибо.
...
Рейтинг: 0 / 0
25.06.2013, 16:48:49
    #38309905
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
VorobyevEvgenyМужики, я не претендую на лучшее решение. Была задача реализовать такое взаимодействие, с вашими подсказками я с ней справился. Спасибо.
"...а то так и будешь всю жизнь ключи подавать" :)
...
Рейтинг: 0 / 0
26.06.2013, 11:02:22
    #38310798
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
Blazkowicz,

Да, я понимаю о чем вы. Мы с коллегой немного ошиблись выбирая эту технологию, она нам не совсем подходит. Но хочется уже довести дело до конца... Ну или, если поймем, что совсем гиблое дело, то придется свернуть с этого пути.

У меня еще вопросы возникли по этой теме. Когда мы тестили этот пример с использованием сервлета, то у нас на стороне обработчика сообщений получалась аналогия очереди. То есть, каждое следующие сообщение попадало на обработку (в метод onMessage) только после того, как закончится обработка предыдущего (предыдущие сообщение покинет метод onMessage). Это было то, что нам нужно и мы решили прикрутить это решение в наш проект. Сейчас эти транзакции попадают в onMessage напрямую (поступило в очередь - onMessage сразу его подхватывает не зависимо от предыдущего сообщения). Наверное это связанно, с особенностью развертывания, в общем с этим:
OOsalivanДело в том что сообщение не отправляеться потому что в EJB контэйнере при менеджед транзакция - это декларативная транзакция, по умолчанию она Requared
Я в этом не силен. В общем, вы наверное уже поняли к чему я клоню...
Вопрос один, можно ли путем каких либо настроек добиться организации реальной очереди на стороне обработчика? Или проще (я подчеркиваю проще, а не лучше) будет отказаться от JMS и построить на втором сервере очередь используя другие технологии?
...
Рейтинг: 0 / 0
26.06.2013, 13:04:17
    #38311104
VorobyevEvgeny
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WebService, EJB, JMS сообщение застревает в транзакции
В общем разобрался чуть-чуть. Тот эффект очереди возникал из-за неправильного открытия/закрытия соединения и сессий или чего то еще. В итоге, спустя некоторое время приложение крешится с невозможностью открывать новые соединения...
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / WebService, EJB, JMS сообщение застревает в транзакции / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]