javax.naming.NameNotFoundException
is the most thrown exception I've seen in J2EE and JavaEE applications. In this series, I will explain some common causes and how to solve it.Incorrect lookup names can take many forms. One of them is missing the standard prefix
java:comp/env/
when looking up resources or EJB in components' environment.public class HelloServlet extends HttpServlet {And the web.xml is as follows:
protected void processRequest(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = null;
try {
out = response.getWriter();
Context ic = new InitialContext();
//this line is wrong!
DataSource dataSource = (DataSource) ic.lookup("jdbc/default-datasource");
Connection connection = dataSource.getConnection();
out.println("Successfully looked up the default datasource: " + dataSource +
", and got the connection: " + connection);
} catch (NamingException e) {
throw new ServletException(e);
} catch (SQLException e) {
throw new ServletException(e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.foo.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
<resource-ref>
<res-ref-name>jdbc/default-datasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<mapped-name>jdbc/__default</mapped-name>
</resource-ref>
</web-app>
mapped-name
subelement maps the local resource reference name jdbc/default-datasource
used in Servlet code to the global JNDI name jdbc/__default
configured in application server. mapped-name
is a new way for mapping resource and EJB references in Java EE 5. jdbc/__default
is the default datasource pre-configured in JavaEE SDK 5, Glassfish, and Sun Java System Application Server. Nothing is wrong with this configuration.But when I deploy and run the above web app to JavaEE SDK 5, I get the following error:
javax.naming.NameNotFoundExceptionThe root cause is the wrong lookup name is used in HelloServlet. To fix this bug, just change the lookup code to use absolute name:
at com.sun.enterprise.naming.TransientContext.resolveContext(TransientContext.java:255)
at com.sun.enterprise.naming.TransientContext.lookup(TransientContext.java:178)
at com.sun.enterprise.naming.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:61)
at com.sun.enterprise.naming.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:98)
at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:309)
at com.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:885)
at com.sun.enterprise.naming.java.javaURLContext.lookup(javaURLContext.java:156)
at com.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:307)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.foo.servlet.HelloServlet.processRequest(HelloServlet.java:29)
DataSource dataSource = (DataSource)Alternatively, you can also lookup the subcontext first, and then lookup the short resource reference name:
ic.lookup("java:comp/env/jdbc/default-datasource");
Context subcontext =
(Context) ic.lookup("java:comp/env");
DataSource dataSource = (DataSource)
subcontext.lookup("jdbc/default-datasource");
All posts in this series for NameNotFoundException:
Fix NameNotFoundException: Incorrect Lookup Name
Fix NameNotFoundException: Reference Not Declared
Fix NameNotFoundException: Wrong Mapping in Deployment Plan
Tags: