JNDI出现NameNotFoundException错误

3
我正在为一个内部库编写回归测试(其创建者已经离开很久了),并尝试验证环境。其中几个测试在JNDI名称为“complex”时失败,并显示NameNotFoundException。
该应用程序是独立的,没有运行在任何Web容器中。该应用程序使用偏好文件,没有涉及LDAP。环境为Java v1.4,并且安装了所有必要的本地库(包括jndi.jar、jms.jar等)。
由于库的复杂性以及它如何与许多对象交互,我先进行简单测试,然后逐步增加复杂度,将每个部分作为单独的测试添加进去。
设置: 文件:c:\data\eclipse\workspace\APP\testfiles\jndi\jms\label\.bindings
文件中有以下条目:QReply/FactoryName=com.ibm.mq.jms.MQQueueFactory
单元测试类: “simple”测试包含以下内容:
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());
}

这个测试通过了。因为我在使用库的过程中遇到了很多问题,所以我创建了另一个测试,匹配传入的实际数据;提供者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上运行它,那个库会出问题,但这是一个次要问题。


1
为了让我的生活更加痛苦,这个库有四层间接引用,一个指向服务定位器文件的首选项文件,一个指向JNDI文件的服务定位器文件,最终指向实际的服务队列。 - jim
1个回答

0

我觉得你可能把JNDI名称搞混了。

"QReply"是JNDI名称。你自己也这么说了:

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

如果这个条目是:"jms/label/QReply",那么你的第二个测试就可以通过了。


不知道问题出在哪里。库代码与“split” URL 的高级测试完全相同。它没有使用 createSubContext 调用,这是有意义的。 - jim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接