tags:

views:

826

answers:

1

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".

This is a stand alone app and is not running with any web containers. The app uses a preference file and there is no LDAP involved. The environment is Java v1.4, and the app is installed with all the necessary libraries local to it. (lib dir with jndi.jar, jms.jar ... etc). 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
In file there is this entry: QReply/FactoryName=com.ibm.mq.jms.MQQueueFactory

UnitTest Class: "simple" test has

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".

"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);

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).

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. Still fails.

Since I don't have any desire (or permission to change the library code), the call to 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.

UPDATE: I've created a jndi_test project on linux java1.5 and that successfully runs the failing test. Taking the same source and moving it to the windows environment - the test fails. 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. (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.

A: 

I think you're getting mixed up with JNDI names.

"QReply" is the JNDI name. You even say so:

In file there is this entry: QReply/FactoryName=com.ibm.mq.jms.MQQueueFactory

If the entry was: "jms/label/QReply" then your second test would work.

Michael Sharek
Don't know that's the issue. The library code does exactly like the advanced test does with the "split" url. It doesn't do anything with a createSubContext call, which would make sense.
jim