Tomcat/JNDI Question


Web tier: servlets, JSP, Web frameworks: Tomcat/JNDI Question

  1. Tomcat/JNDI Question (1 messages)

    I have a jar file in $CATALINA_HOME/common/lib that contains .class files representing an interface and a concrete class that implements it. I've created an ObjectFactory so that I can look up the interface in JNDI. I want to be able to look up the class by name from my servlet, get it back from JNDI, cast it to the interface, and use it as such - avoiding any knowledge of the concrete class, etc.

    In my servlet's .war file, I have the .class file for the interface. Unless I also have the .class file for the concrete class, I get ClassCastExceptions when I try to retrieve the interface from JNDI:

      SecurityService securityService = (SecurityService) context.lookup("moo/SecurityService");

    I'm pretty sure my server.xml and web.xml files are correct, because I can see my ObjectFactory being created and used to create an instance of the concrete class in catalina.out. I'm also sure that JNDI has the binding for the class because I printed out the bindings and I can see it in java:comp/env/moo/SecurityService. Finally, I know that the class coming back is the concrete class that implements SecurityService, because I see the class name in the exception.

    Do I misunderstand interfaces? Shouldn't I be able to cast a class to any interface that it implements? Should I quit messing with this stuff and go back to being a lowly Unix admin?

    Thanks for any help.
  2. Tomcat/JNDI Question[ Go to top ]


    I think you're suffering from a classloader problem here: Classes loaded by different classloaders are not compatible, even if you're dealing with one and the same class.

    In your configuration, the web application will pick up the interface from the WAR (due to the Servlet spec classloader hierarchy), and the implementation class from common/lib. Thus, the 2 class files are loaded by different classloaders, so you cannot cast the implementation class to the interface.

    You can either put both the interface and implementation class in your WAR file, or put both in your common/lib, without additional copies of any of the class files in the WAR.