Почему мой поиск JNDI для QueueConnectionFactory возвращает ноль? - PullRequest
7 голосов
/ 26 августа 2009

Я пытаюсь найти QueueConnectionFactory и Queue через JNDI Джеронимо. Queue возвращается нормально, но поиск QueueConnectionFactory всегда возвращает ноль. Он не выдает NamingException, чего я и ожидал бы, если бы имя JNDI было неверным.

Кто-нибудь может увидеть, что я делаю не так? Тестовый код ниже выводит:

true
false

import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class JndiTest
{
    private final static String QUEUE_NAME = "jca:/org.apache.geronimo.configs/activemq-ra/JCAAdminObject/SendReceiveQueue";
    private final static String FACTORY_NAME = "jca:/org.apache.geronimo.configs/activemq-ra/JCAManagedConnectionFactory/DefaultActiveMQConnectionFactory";

    public static void main(String[] args) throws NamingException
    {
        InitialContext ctx = new InitialContext();
        QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup(FACTORY_NAME);
        Queue queue = (Queue)ctx.lookup(QUEUE_NAME);
        System.out.println(factory == null);
        System.out.println(queue == null);      
    }

}

В случае, если это имеет значение: я добавил openejb-client-3.0.1.jar, geronimo-ejb_3.0_spec-1.0.1.jar и activemq-core-4.1.2-G20090207.jar в мой класс путь, и мой файл jndi.properties имеет свойства:

java.naming.factory.initial = org.apache.openejb.client.RemoteInitialContextFactory
java.naming.provider.url = ejbd://127.0.0.1:4201

Ответы [ 4 ]

13 голосов
/ 30 августа 2009

Причина, по которой он не генерирует исключение, заключается в том, что существует исключение ClassLoadException, возникающее при обращении к ресурсу.

И причина, по которой это происходит, потому что класс: com.sun.jndi.url.jca.jcaURLContextFactory ищется ClassLoader, вызываемым из ResourceManager.

Если вы измените имя фабрики на какое-то другое имя, вы увидите исключение NamingException, но в случае поиска исключений, таких как ClassNotFound / IllegalState, исключений не возникает.

Таким образом, необходимо проанализировать зависимости ActiveMQ. Обновление 1. Одна из возможных причин заключается в том, что объект фабрики может быть создан только в управляемой среде. Вы запускаете свой код как клиент приложения?.

Update2: некоторые другие указатели, найденные для причины этого поведения:

только реализация openejb jndi выставляет ejbs, а не любые другие ресурсы. Если у вас есть клиент приложения j2ee, и Вы хотите использовать JMS, вам нужно развернуть копию адаптера activemq на клиенте. Затем вы можете использовать j2ee java: контекст comp / env для поиска ваши вещи.

Найдено на сайте ActiveMQ:

Реализация ActiveMQ JNDI НЕ взаимодействует с сервером имен. Это урезанная версия клиента JNDI, которая просто позволяет получить темы и Очереди напрямую из экземпляра JMS. Таким образом, вместо предоставления адреса сервера имен, вы должны указать адрес сервера JMS. Большинство реализаций JNDI используют свойство java.naming.provider.url для указания адреса сервера имен. ActiveMQ использует brokerURL . Использование вместо этого java.naming.provider.url приведет к тому, что ActiveMQ попытается загрузить весь брокер.

Подробнее о том, как подключиться с помощью JNDI :

Исходная фабрика контекста, использованная в объяснении: org.apache.activemq.jndi.ActiveMQInitialContextFactory

Некоторые примеры кода для тестирования с JNDI можно найти здесь

Я написал простой Java-клиент - примечание под URL-адресом провайдера - это brokerURL, который используется.

    Properties props = new Properties();            
props.put(Context.INITIAL_CONTEXT_FACTORY,
             "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
    //props.put(Context.PROVIDER_URL,"vm://localhost");//Either this or below
    props.put(Context.PROVIDER_URL,"tcp://localhost:65432"); 
    props.put("queue.SendReceiveQueue",
         "org.apache.geronimo.configs/activemq-ra/JCAAdminObject/SendReceiveQueue");

    InitialContext context = new InitialContext(props);   
    QueueConnectionFactory connectionFactory = (QueueConnectionFactory)context.lookup
                                                               ("ConnectionFactory");
    Queue q = (Queue) context.lookup("SendReceiveQueue");
    System.out.println("conn is : "  + connectionFactory.getClass().getName());
    System.out.println("queue is : " + q.getQueueName());

Эта программа выдает:

conn is: org.apache.activemq.ActiveMQConnectionFactory очередь: org.apache.geronimo.configs / activemq-ra / JCAAdminObject / SendReceiveQueue

1 голос
/ 29 апреля 2011

Не знаю почему, но для меня использование контекста не сработало. Кажется, что сообщение отправлено, но onMessage моего потребителя не вызывается.

Использование контекста не вызывает исключения, но не работает:

import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;

public class HelloClient {

public static void main(String[] args) throws Exception {
    Properties ppt2 = new Properties();
    ppt2.put(Context.INITIAL_CONTEXT_FACTORY,
            "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
    ppt2.put(Context.PROVIDER_URL, "tcp://localhost:61616");
    ppt2.put("topic.MessageDestinationTopic", "console.jms/TopicQueue/JCAAdminObject/MessageDestinationTopic");
    Context ctx2 = new InitialContext(ppt2);

    TopicConnectionFactory factory = (TopicConnectionFactory) ctx2.lookup("ConnectionFactory");
    TopicConnection connection = factory.createTopicConnection();
    TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    Topic topic = (Topic) ctx2.lookup("MessageDestinationTopic");

    MessageProducer producer = session.createProducer(topic);

    TextMessage msg = session.createTextMessage();
    msg.setText("this is a test message");
    producer.send(msg);
    producer.close();
    session.close();
    System.out.println("Message published. Please check application server's console to see the response from MDB");
    ctx2.close();
    System.exit(0);

}

}

Использование кода ниже (без контекста) работает хорошо:

import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;

public class HelloClient {

    public static void main(String[] args) throws Exception {

        TopicConnectionFactory factory = new org.apache.activemq.ActiveMQConnectionFactory("tcp://localhost:61616");
        TopicConnection connection = factory.createTopicConnection();
        TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic("MessageDestinationTopic");

        MessageProducer producer = session.createProducer(topic);

        TextMessage msg = session.createTextMessage();
        msg.setText("this is a test message");
        producer.send(msg);
        producer.close();
        session.close();
        System.out.println("Message published. Please check application server's console to see the response from MDB");
        System.exit(0);

    }

}
1 голос
/ 02 сентября 2009

У меня есть несколько эквивалентная конфигурация Tomcat / Geronimo J2EE jar / Geronimo JMS Jar / ActiveMQ 4 И я немного запутался в вашем файле jndi.propertie. Моя выглядит так:

</p> <p>java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory</p> <p>java.naming.provider.url = tcp://localhost:61616 </p> <p>connectionFactoryNames = connectionFactory , TopicConnectionFactory</p> <p>

Большая разница заключается в том, что ваш начальный контекст удален. Кроме того, я должен предоставить connectionFactoryNames или получить исключение NamingException.

0 голосов
/ 26 августа 2009

Здесь два участника, вы ищете что-то в JNDI. Кто-то еще должен был положить его туда. Я не знаю специфику вашей среды, но мой подход к таким проблемам

  • исследовать пространство имен - что там? У вас есть какие-нибудь инструменты просмотра JNDI?
  • осторожно ищите в журналах службу, которая должна регистрироваться в JNDI, сообщает ли она об ошибках?
...