Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

[dúvida] Uso do QueueBrowser para checar mensagens sem consumí-las

Fiz a implementação do QueueBrowser porém mesmo alimentando o ActiveMQ com mensagens, ele retorna que não há mensagens para exibir. Segue código abaixo:

Classe TesteProdutor:

public class TesteProdutor {
    public static void main(final String[] args) throws Exception {
        final Properties properties = new Properties();
        properties.setProperty("java.naming.factory.initial", "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
        properties.setProperty("java.naming.provider.url", "tcp://127.0.0.1:61616");
        properties.setProperty("queue.financeiro", "fila.financeiro");

        final InitialContext context = new InitialContext(properties);

        final ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");
        final Connection connection = factory.createConnection();
        connection.start();

        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        final Destination fila = (Destination) context.lookup("financeiro");
        final MessageProducer producer = session.createProducer(fila);

        for (int i = 0; i < 1000; i++) {
            final TextMessage message = session.createTextMessage("Iteração " + i);
            producer.send(message);
        }

        session.close();
        connection.close();
        context.close();
    }
}

Classe TesteConsumidor:

public class TesteConsumidor {
    @SuppressWarnings("resource")
    public static void main(final String[] args) throws Exception {
        final InitialContext context = new InitialContext();

        final ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");
        final Connection connection = factory.createConnection();
        connection.start();

        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        final Destination fila = (Destination) context.lookup("financeiro");
        final MessageConsumer consumer = session.createConsumer(fila);

        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(final Message message) {
                final TextMessage textMessage = TextMessage.class.cast(message);
                try {
                    System.out.println("Recebendo msg: " + textMessage.getText());
                } catch (final JMSException e) {
                    e.printStackTrace();
                }
            }
        });

        new Scanner(System.in).nextLine();

        connection.close();
        context.close();
    }
}

Classe TesteQueueBrowser:

public class TesteQueueBrowser {
    @SuppressWarnings("rawtypes")
    public static void main(final String[] args) throws NamingException, JMSException {
        final Properties properties = new Properties();
        properties.setProperty("java.naming.factory.initial", "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
        properties.setProperty("java.naming.provider.url", "tcp://127.0.0.1:61616");
        properties.setProperty("queue.financeiro", "fila.financeiro");

        final InitialContext context = new InitialContext(properties);
        final ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");
        final Connection connection = factory.createConnection();
        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        final Destination destination = (Destination) context.lookup("financeiro");
        final QueueBrowser browser = session.createBrowser((Queue) destination);
        final Enumeration msgs = browser.getEnumeration();
        if (!msgs.hasMoreElements()) {
            System.out.println("Não há mensagens na fila");
        } else {
            while (msgs.hasMoreElements()) {
                final TextMessage msg = (TextMessage) msgs.nextElement();
                System.out.println("Mensagem: " + msg.getText());
            }
        }
    }
}

O que estou fazendo de errado? O uso do QueueBrowser tem de ser feita na mesma classe do produtor ao invés de usar em outra classe?

4 respostas
solução!

Vou determinar que esse tópico esteja resolvido, visto que não deram retorno.

Porém, não há problema de não ter ocorrido o retorno, vou verificar o que está errado, pois o código em si está correto. Fiz a mesma implementação em outra situação e funcionou.

O importante é considerar que para visualizar a mensagem sem consumir, devemos utilizar o BrowserQueue, e converter o Element utilizando o casting para o respectivo objeto, onde no meu caso o Element é um objeto que implementa TextMessage, ficando:

final Destination destination = (Destination) context.lookup("financeiro");
final QueueBrowser browser = session.createBrowser((Queue) destination);
final Enumeration msgs = browser.getEnumeration();
if (!msgs.hasMoreElements()) {
    System.out.println("Não há mensagens na fila");
} else {
    while (msgs.hasMoreElements()) {
    final TextMessage msg = (TextMessage) msgs.nextElement();
    System.out.println("Mensagem: " + msg.getText());
}

Olá daniel chiuratto seabra. Só uma pergunta, vc está executando as classes nessa ordem, como vc postou? Caso sim, o problema é que vc não pode executar a classe TesteConsumidor, pois ela retira (consome) as mensagens da fila. Para ficar com as mensagens presas no ActiveMQ, vc não pode consumi-las, ai que entra o QueueBrowser, que apenas lê a fila sem consumir as mensagens que foram postadas.

daniel, seu código está correto mas faltou declarar o nome da Factory na properties: properties.setProperty("connectionFactoryNames","connectionFactory");

Ao que verifiquei o código está correto, me parece que o Rafael pode ter matado o mistério, pois se você consume as mensagens da fila antes de executar o browser, quando o browser é executado já não tem mais mensagens para ele visualizar, lembrando que o QueueBrowser lê apenas as mensagens ainda enfileiradas e não as já entregues.