【问题标题】:JNDI failing with NameNotFoundExceptionJNDI 失败并出现 NameNotFoundException
【发布时间】:2009-02-18 19:58:44
【问题描述】:

我正在为一个内部库(创建者早已不在)编写回归测试,并且我正在尝试验证环境。仅当 jndi 名称为“复杂”时,一些测试才因 NameNotFoundException 而失败。

这是一个独立的应用程序,不与任何网络容器一起运行。该应用程序使用首选项文件,并且不涉及 LDAP。环境是 Java v1.4,应用程序安装了所有必要的本地库。 (带有 jndi.jar、jms.jar 等的 lib 目录)。很简单吧?

由于库的复杂性以及它如何处理大量对象,我进行了一个简单的测试,然后在每个部分中增加复杂性作为单独的测试。

设置: 文件:c:\data\eclipse\workspace\APP\testfiles\jndi\jms\label\.bindings
在文件中有这个条目:QRep​​ly/FactoryName=com.ibm.mq.jms.MQQueueFactory

UnitTest 类: “简单”测试有

Hashtable ht = new Hashtable();
ht.put(Context.PROVIDER_URL, 
    "file:/data/eclipse/workspace/APP/testFiles/jndi/jms/label/");
ht.put(Context.INITIAL_CONTEXT_FACTORY, 
    "com.sun.jndi.fscontext.RefFSContextFactory");
ht.put(Context.SECURITY_AUTHENTICATION, "none");
Context ctx;
try {
  ctx = new InitialContext(ht);
  String jndiName = "QReply";
  logger.debug("testFindRemoteObject_Simple", 
       "Invoking InitialContext.lookup(\"" + jndiName + "\")");
  Object remoteObject = ctx.lookup(jndiName);
  assertTrue(remoteObject != null);
} catch (NamingException e) {
  e.printStackTrace();
  fail(e.getMessage());
}

这通过了。因为我在使用库时遇到了很多麻烦,所以我创建了另一个与传入的实际数据匹配的测试; Provider URL 被缩短,jndi 名称选择一个“路径”。

“实际”数据单元测试:

final Hashtable ht = new Hashtable();
ht.put(Context.PROVIDER_URL, 
   "file:/data/eclipse/workspace/APP/testFiles/jndi/");
ht.put(Context.INITIAL_CONTEXT_FACTORY, 
   "com.sun.jndi.fscontext.RefFSContextFactory");
ht.put(Context.SECURITY_AUTHENTICATION, "none");
Context ctx;
try {
  ctx = new InitialContext(ht);
  String jndiName = "jms/label/QReply";
  logger.debug("testFindRemoteObject_Actual", 
           "Invoking InitialContext.lookup(\"" + jndiName + "\")");
  Object remoteObject = ctx.lookup(jndiName);
  assertTrue(remoteObject != null);
} catch (NamingException e) {
  e.printStackTrace();
  fail(e.getMessage());
}

失败了

javax.naming.NameNotFoundException: jms/label/QReply
at com.sun.jndi.fscontext.RefFSContext.getObjectFromBindings(
      RefFSContext.java:400)
at com.sun.jndi.fscontext.RefFSContext.lookupObject(RefFSContext.java:327)
at com.sun.jndi.fscontext.RefFSContext.lookup(RefFSContext.java:146)
at com.sun.jndi.fscontext.FSContext.lookup(FSContext.java:127)
at javax.naming.InitialContext.lookup(InitialContext.java:347)
at com.advo.tests.services.UnitTestServiceLocator.testFindRemoteObject_Actual(
           UnitTestServiceLocator.java:85)

其中 UnitTestServiceLocator.java:85 是 ctx.lookup(jndiname) 的行;

为什么简单的测试会通过,而复杂的测试会失败?两者都使用指向 lib 目录的类路径,该目录填充有 jms 和 mq jar(以及其他内容)。

复杂的测试匹配库将填充的内容,但使用魔法作为传入的值。库代码还有“几行”可以从首选项文件中提取魔法值。 我错过了什么?库代码将在服务器上运行,但在我的笔记本电脑上失败(开发时)。

我什至创建了另一个 jndi 路径 - 以防第一个测试搞砸了第二个。仍然失败。

由于我没有任何愿望(或更改库代码的权限),因此调用 InitialContext(X);就是这样,因为图书馆就是这样做的。我已经看到其他示例没有通过 InitialContext 传递,我很困惑为什么这样更好。

更新: 我在 linux java1.5 上创建了一个 jndi_test 项目,并且成功运行了失败的测试。采用相同的源并将其移动到 Windows 环境 - 测试失败。由于 linux 上没有 C 盘但数据文件相同,因此类路径有一些更改。 (嗯分隔符问题?)

如果我要在 1.5 上运行它,我还发现该库存在问题,但这是一个附带问题。

【问题讨论】:

  • 为了让我的生活更痛苦,库有 4 层间接,一个首选项文件指向一个服务定位器文件,该文件指向一个指向实际服务队列的 jndi 文件。

标签: java jndi


【解决方案1】:

我认为您在混淆 JNDI 名称。

“QReply”是 JNDI 名称。你甚至这么说:

在文件中有这个条目:QRep​​ly/FactoryName=com.ibm.mq.jms.MQQueueFactory

如果条目是:“jms/label/QReply”,那么您的第二个测试将起作用。

【讨论】:

  • 不知道这是问题所在。库代码的作用与高级测试对“拆分” url 所做的完全一样。它不会对 createSubContext 调用做任何事情,这是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 2015-12-19
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多