3

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

这是一个独立的应用程序,不与任何 Web 容器一起运行。该应用程序使用首选项文件,并且不涉及 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

1 回答 1

0

我认为您与 JNDI 名称混淆了。

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

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

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

于 2009-02-18T21:38:33.240 回答