views:

265

answers:

3

This is a follow up question to my previous question.

I am trying to write test case for my ServiceLocator class but it gives me the following error:

com/iplanet/ias/admin/common/ASException
java.lang.NoClassDefFoundError: com/iplanet/ias/admin/common/ASException
        at java.lang.ClassLoader.defineClass1(Native Method)

My test case:

public void testServiceLocator () throws UivException, NamingException
{
    DataSource ds = ServiceLocator.getInstance().getDataSource("jdbc/RSRC/my/mydb");
    //I have not put any assert statements because i know above line is failing
}

The above code fails on getInstance() method which looks like this:

static public ServiceLocator getInstance() throws UivException {
    try {
        if (me == null) {
          synchronized(ServiceLocator.class) {
            me = new ServiceLocator();
          }
        }
        return me;
    }
    catch (UivException e) {
          throw new UivException(ErrorCode.SERVICE_LOCATOR_ERROR,
                                 ErrorCode.SERVICE_LOCATOR_LOOKUP_ERROR,
                                 e.getMessage());
    }
}

I know this ServiceLocator works fine because when I test my application from the front end there are no issues. Only reason I am writing this test case is because I want to test my DAO. And for me to test my DAO ServiceLocator has to work (from JUnit).

I don't have a clue what to make of the error message. Does anyone want to suggest something I can try that will hopefully work?

EDIT: ServiceLocator constructor

private ServiceLocator() throws UivException  {
    try {
        ic = new InitialContext();
        // System.out.println("Created the Initial Context");
        cache = Collections.synchronizedMap(new HashMap());
    }
    catch (NamingException ne) {
        throw new UivException(ErrorCode.SERVICE_LOCATOR_ERROR,
                               0, ne.getMessage());
    }
    catch (NullPointerException e) {
          throw new UivException(ErrorCode.SERVICE_LOCATOR_ERROR,
                                 0, e.getMessage());
    }
}
+1  A: 

Well, is com.iplanet.ias.admin.common.ASException on the classpath when you invoke your tests?

Are you relying on the app server to have the JDBC driver's libraries in it's classpath, or are you deploying it yourself?

matt b
I am relying on the app server. since appserver already has all the settings I just wanted to write the tests and get along with it.
Omnipresent
com.iplanet stuff seems to be Sun App server's admin properties. Thats probably needed to get the JDBC resource from the app server. ...but the Junit tests are not 'deployed' on the app server...
Omnipresent
but if your unit tests call code that tries to load the JDBC driver then the JDBC driver needs to be on the classpath when executing the unit tests.
matt b
+2  A: 

Actually, the error is pretty clear: java.lang.NoClassDefFoundError: com/iplanet/ias/admin/common/ASException indicates that the definition of ASException cannot be found at runtime.

When running in the application server, this class is provided by iPlanet Application Server and the code just runs fine. To run this code outside the application server context, you'll have to provide it "manually" by putting it to the classpath. So you have to add the right iPlanet JAR to the classpath (this is the tricky part, you'll have to find which one).

Additionally, I can see taht you're using the InitialContext non-arg constructor so you're using iPlanet's environment settings when running inside the application server. Outside iPlanet (e.g. for a unit test), you'll have to provide the right JNDI properties for iPlanet yourself. To do so, you'll have to put a jndi.properties file on the classpath with (at least) the initial context factory and the provider URL. Something like this:

java.naming.factory.initial=...
java.naming.provider.url=...

Check your iPlanet documentation for the values.

Pascal Thivent
A: 

I'm curious why you're writing a service locator. Is it part of an assignment? In the real world, Dependency Injection is the clearly superior choice, using either Guice or Spring.

Kevin Bourrillion
not it isnt an assignment. We have old legacy code that is still using JDBC (Compared to ORM). I'm trying to move this legacy code to be more 'real world worthy'. You have any links about spring injections that you would like to share?
Omnipresent