简体   繁体   English

JNDI失败,出现NameNotFoundException

[英]JNDI failing with NameNotFoundException

I'm writing regression tests for a in-house library (where the creators are looong gone) and I'm trying to validate the environment. 我正在为内部库(其中几乎没有创建者)编写回归测试,并且正在尝试验证环境。 A couple of the tests keep failing with that NameNotFoundException only when the jndi name is "complex". 仅当jndi名称为“ complex”时,一些测试才会因NameNotFoundException失败。

This is a stand alone app and is not running with any web containers. 这是一个独立的应用程序,未与任何Web容器一起运行。 The app uses a preference file and there is no LDAP involved. 该应用程序使用首选项文件,并且不涉及LDAP。 The environment is Java v1.4, and the app is installed with all the necessary libraries local to it. 该环境是Java v1.4,并且该应用程序安装有本地所有必需的库。 (lib dir with jndi.jar, jms.jar ... etc). (带有jndi.jar,jms.jar ...等的lib目录)。 Simple, right ? 简单吧?

Due to the complexity of the library and how it futzes around with lots of objects, I have a simple test and then ramp up the complexity adding in each piece as a separate test. 由于该库的复杂性以及它如何与许多对象融合在一起,我进行了一个简单的测试,然后增加了复杂性,并将其添加为单独的测试。

Setup: File: c:\\data\\eclipse\\workspace\\APP\\testfiles\\jndi\\jms\\label\\.bindings 设置:文件:c:\\ data \\ eclipse \\ workspace \\ APP \\ testfiles \\ jndi \\ jms \\ label \\ .bindings
In file there is this entry: QReply/FactoryName=com.ibm.mq.jms.MQQueueFactory 在文件中有此条目:QRep​​ly / FactoryName = com.ibm.mq.jms.MQQueueFactory

UnitTest Class: "simple" test has 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());
}

This passes. 这样过去了。 Because I was having so much trouble with the library I created another test that matches the actual data passed in; 因为我在使用库时遇到了很多麻烦,所以我创建了另一个测试,该测试与传入的实际数据相匹配。 the Provider URL is shortened and the jndi name picks up a "path". 提供商URL会缩短,并且jndi名称会选择一个“路径”。

"Actual" data unit test: “实际”数据单元测试:

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

Which fails with 哪个失败

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)

where UnitTestServiceLocator.java:85 is the line of ctx.lookup(jndiname); 其中UnitTestServiceLocator.java:85是ctx.lookup(jndiname);

Why would the simple test pass but the more complex test fail ? 为什么简单的测试通过但更复杂的测试失败? Both use a classpath that points to the lib directory which is populated with the jms and mq jars (among other things). 两者都使用指向lib目录的类路径,该目录由jms和mq jar填充(除其他外)。

The complex test matches what the library will fill in but using magic as the passed in values. 复杂测试与库将填充的内容匹配,但使用魔术作为传入的值。 The library code has a "few" more lines that extract the magic values from the preferences file(s). 库代码多了几行,从首选项文件中提取魔术值。 What am I missing? 我想念什么? The library code will work on the server but fail on my laptop (when developing). 库代码将在服务器上运行,但在笔记本电脑上(开发时)将失败。

I even created another jndi path - just in case the first test was mucking up the second. 我什至还创建了另一条jndi路径-以防万一第一个测试弄糟了第二个。 Still fails. 仍然失败。

Since I don't have any desire (or permission to change the library code), the call to InitialContext(X); 由于我没有任何愿望(或更改库代码的权限),因此调用InitialContext(X); is that way BECAUSE that's the way the library does it. 那样是因为库就是这样做的。 I've seen the other examples with nothing passed with InitialContext and I'm confused why that is better. 我看过其他示例,但InitialContext没有传递任何内容,我感到困惑,为什么这样做更好。

UPDATE: I've created a jndi_test project on linux java1.5 and that successfully runs the failing test. 更新:我已经在linux java1.5上创建了一个jndi_test项目,该项目成功运行了失败的测试。 Taking the same source and moving it to the windows environment - the test fails. 使用相同的源并将其移至Windows环境-测试失败。 There are a few changes to the classpath due to the fact that there is no C drive on linux but the data files are the same. 由于在Linux上没有C驱动器,但数据文件相同,因此对类路径进行了一些更改。 (hmm delimiter issue ?) (嗯,定界符问题?)

I've also found out that I've got problems with that library IF i'm going to run it on 1.5, but that's a side issue. 我还发现如果我要在1.5上运行该库,我会遇到问题,但这是附带问题。

I think you're getting mixed up with JNDI names. 我认为您与JNDI名称混为一谈。

"QReply" is the JNDI name. “ QReply”是JNDI名称。 You even say so: 您甚至可以这样说:

In file there is this entry: QReply/FactoryName=com.ibm.mq.jms.MQQueueFactory 在文件中有此条目:QRep​​ly / FactoryName = com.ibm.mq.jms.MQQueueFactory

If the entry was: "jms/label/QReply" then your second test would work. 如果输入是:“ jms / label / QReply”,则您的第二个测试将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM