2009-08-26 32 views
7

Tôi đang cố tra cứu một số QueueConnectionFactoryQueue qua JNDI của Geronimo. Các Queue được trả lại tốt, nhưng tra cứu QueueConnectionFactory luôn trả về giá trị rỗng. Nó không ném một NamingException, đó là những gì tôi mong đợi nếu tên JNDI là không chính xác.Tại sao tra cứu JNDI của tôi cho một QueueConnectionFactory trả về null?

Có ai có thể xem tôi đang làm gì sai không? Các mã kiểm tra dưới đây kết quả đầu ra:

 
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);  
    } 

} 

Trong trường hợp nó làm cho một sự khác biệt: Tôi đã thêm OpenEJB-client-3.0.1.jar, geronimo-ejb_3.0_spec-1.0.1.jar và ActiveMQ -core-4.1.2-G20090207.jar đến đường dẫn lớp của tôi, và tập tin jndi.properties tôi có các thuộc tính:

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

Trả lời

12

Lý do tại sao nó không ném ngoại lệ là - có một ClassLoadException xuất hiện khi tài nguyên được truy cập.

Và lý do tại sao điều đó xảy ra vì lớp: com.sun.jndi.url.jca.jcaURLContextFactory đang được tìm kiếm bởi ClassLoader được gọi từ ResourceManager.

Nếu bạn thay đổi tên nhà máy thành một tên khác thì bạn sẽ thấy cách đặt tên là ngoại lệ - nhưng trong trường hợp tra cứu, đối với trường hợp ngoại lệ như ClassNotFound/IllegalState - không có ngoại lệ nào được nêu ra.

Các phụ thuộc của ActiveMQ do đó cần được phân tích. Update1: Một trong những lý do có thể là đối tượng nhà máy chỉ có thể được khởi tạo trong môi trường được quản lý. Bạn có đang chạy mã của mình với tư cách là ứng dụng khách không ?.

Update2: Một số gợi ý khác được tìm thấy cho nguyên nhân của hành vi này:

các OpenEJB thực hiện jndi chỉ lộ ejb, không bất kỳ nguồn lực khác. Nếu bạn có ứng dụng khách ứng dụng j2ee và bạn muốn sử dụng jms, bạn cần phải triển khai bản sao của bộ chuyển đổi activemq trên máy khách. Sau đó, bạn có thể sử dụng ngữ cảnh java: comp/env j2ee để tìm kiếm nội dung của bạn.

Các mặt hàng này trên trang web của ActiveMQ: Thực hiện JNDI

của ActiveMQ KHÔNG nói chuyện với các máy chủ đặt tên. Đó là phiên bản rút gọn của ứng dụng khách JNDI chỉ cho phép nhận Chủ đề và Hàng đợi trực tiếp từ một phiên bản JMS.Vì vậy, thay vì cung cấp địa chỉ máy chủ đặt tên, bạn phải cung cấp địa chỉ máy chủ JMS. Các triển khai JNDI đầu tiên sử dụng thuộc tính java.naming.provider.url để chỉ định địa chỉ của máy chủ định danh. ActiveMQ sử dụng số điện thoại brokerURL. Sử dụng java.naming.provider.url thay vào đó sẽ dẫn đến ActiveMQ cố gắng tải toàn bộ Nhà môi giới.

Xem thêm về làm thế nào để Connect using JNDI:

Nhà máy bối cảnh ban đầu được sử dụng trong lời giải thích là: org.apache.activemq.jndi.ActiveMQInitialContextFactory đang

Một số mẫu để thử nghiệm với JNDI thể được tìm thấy here

Tôi đã viết một máy khách java đơn giản - lưu ý bên dưới url của nhà cung cấp là brokerURL đang được sử dụng.

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()); 

Chương trình này cung cấp cho các đầu ra:

conn là: org.apache.activemq.ActiveMQConnectionFactory đợi là: org.apache.geronimo.configs/ActiveMQ-ra/JCAAdminObject/SendReceiveQueue

+0

Rất tiếc. Cảm ơn câu trả lời chu đáo, chu đáo. –

0

có hai người tham gia ở đây, bạn đang tìm kiếm trong JNDI cho một cái gì đó. Có người khác phải đặt nó ở đó. Tôi không biết chi tiết về môi trường của bạn nhưng cách tiếp cận của tôi đối với các vấn đề đó là

  • khám phá không gian tên - có gì? Bạn có bất kỳ công cụ phát triển JNDI nào không?
  • trông bất cẩn trong nhật ký cho dịch vụ được cho là đăng ký với JNDI, có báo cáo bất kỳ lỗi nào không?
+0

Geronimo cung cấp một công cụ duyệt JNDI, và cả hai tên JNDI đều xuất hiện ở đó. Thay đổi tên trong công cụ kiểm tra của tôi tạo ra một NamingException, vì vậy nó phải được tìm thấy * cái gì đó *. –

+0

Đúng, nhưng nó là gì và ai đặt nó ở đó? Với tôi tất cả những điều này chỉ ra vấn đề đang ở trong nhà cung cấp JMS thay vì mã của bạn. – djna

1

Tôi có một cấu hình tương đương Tomcat/Geronimo J2EE jar/Geronimo JMS Jar/ActiveMQ 4 Và tôi hơi bối rối về tệp jndi.propertie của bạn. Mine trông như thế này:

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory

java.naming.provider.url = tcp://localhost:61616

connectionFactoryNames = connectionFactory , TopicConnectionFactory

Sự khác biệt lớn là obviousely rằng bối cảnh ban đầu của bạn là điều khiển từ xa. Bên cạnh đó, tôi phải cung cấp một connectionFactoryNames, hoặc tôi nhận được một NamingException.

1

Tôi không biết tại sao, nhưng đối với tôi, việc sử dụng ngữ cảnh không hiệu quả. Có vẻ như tin nhắn được gửi đi, nhưng onMessage của người tiêu dùng của tôi không được gọi.

Sử dụng một bối cảnh không ném ngoại lệ nhưng không có tác dụng:

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); 

} 

} 

Sử dụng mã dưới đây (không có ngữ cảnh) hoạt động tốt:

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); 

    } 

} 
Các vấn đề liên quan