尝试使用不同的远程数据源。失败-JNDI解决异常

时间:2019-01-15 14:14:50

标签: java jms weblogic jndi initial-context

我在tomcat上部署了一个应用程序,该应用程序尝试与外部系统A和B的远程JMS队列一起使用。外部系统部署在Weblogic上,因此为了与它们进行通信,我还提供了wlthint3client。

那是我的代码:

public void myMethod () {
   // Sending message to first ext system
   // jndi queue name - topic1.extsys1.tosend.messages
   magicMethod(Params of External system A);

   // Sending message to second ext system
   // jndi queue name - topic1.extsys2.tosend.messages
   magicMethod(Params of External system B);

   // AGAIN Sending message to FIRST ext system
   // jndi queue name - topic1.extsys1.tosend.messages
   magicMethod(Params of External system A);  
}

private void magicMethod(String factoryName, String url, String connectionFactoryJNDI, String queueName) throws Exception {

    javax.jms.QueueConnectionFactory queueConnectionFactory = null;
    javax.jms.QueueSession queueSession = null;
    javax.jms.Queue queue = null;
    javax.jms.QueueSender queueSender = null;
    javax.jms.QueueConnection queueConnection = null;
    InitialContext ic = null;

    try {
        final Properties initialContextProperties = new Properties();
        initialContextProperties.put(Context.INITIAL_CONTEXT_FACTORY, factoryName);
        initialContextProperties.put(Context.PROVIDER_URL, url);
        initialContextProperties.put(Context.SECURITY_PRINCIPAL, "");
        initialContextProperties.put(Context.SECURITY_CREDENTIALS, "");
        ic = new InitialContext(initialContextProperties);
        queueConnectionFactory = (QueueConnectionFactory) ic.lookup(connectionFactoryJNDI);
        queue = (javax.jms.Queue) ic.lookup(queueName);
    } catch (NamingException e) {
        System.out.println("Could not create JNDI context: " + e.getMessage());
    }

    try {
        queueConnection = queueConnectionFactory.createQueueConnection();
        queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        queueSender = queueSession.createSender(queue);
        ObjectMessage objectMessage = queueSession.createObjectMessage("message");
        queueSender.send(objectMessage);
    } catch (JMSException e) {
        System.out.println(e.getMessage());
    } finally {
        ic.close();
        queueConnection.close();
        queueSession.close();
        queueSender.close();
    }
}

当我向分机系统A发送消息时,一切正常。 向内线系统B发送消息-仍然发送消息,一切正常。

再次尝试向分机系统A发送消息时-我失败了。

  

无法创建JNDI上下文:尝试查找'topic1.extsys1.tosend.messages'时未找到子上下文'extsys1'。已解决的“ topic1”

所以我想了解:

  1. 我做错了什么?
  2. 在成功发送到分机B之后,为什么它不向系统A发送消息?
  3. 这些内部Java对象(InitialContext,JNDI对象等)是否在某处具有某些状态?也许我需要清洁一些东西?
  4. 我觉得JNDI名称有些混乱...
  5. 也许我需要更改名称? (实际上,我已经尝试过使用完全不同的jndi队列名称,但是它没有任何作用,但是我没有重新启动外部系统,不确定是否需要重新启动它。)

任何想法,移动方向???请

ps-jms服务器和jms模块在A和B外部系统中具有相同的名称。提供者URL为-ext1.xxx.corp.comext2.xxx.corp.com

2 个答案:

答案 0 :(得分:0)

我不确定JNDI查找失败的原因。 JNDI对象没有任何状态,至少没有按照规范,但是您的特定实现可能具有某些非规范的行为。这也可能只是您的JNDI实现中的错误。

但是,我可以说您的代码在这里使用了重要的反模式,因为它对您发送的条消息执行以下操作:

  • JNDI查找(可能需要网络往返)
  • 创建JMS连接(肯定需要网络往返)
  • 创建JMS会话(几乎肯定需要网络往返)
  • 创建JMS生产者

这是对资源的极大浪费。至少,您应该缓存JNDI查找的结果(这可能会解决您的问题)以及JMS连接工厂。理想情况下,您将对JMS连接使用池。

答案 1 :(得分:0)

这是伪代码,仅用于描述情况。

答案在这里-JMSTemplate with multiple brokers. Destination resolving exception