For example, HelloServlet looks up the default DataSource in JavaEE SDK 5, whose global JNDI name is jdbc/__default:
public class HelloServlet extends HttpServlet {Any portable applications must also declare a resource-ref in web.xml:
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();
DataSource dataSource = (DataSource) ic.lookup("java:comp/env/jdbc/__default");
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);
}
}
<?xml version="1.0" encoding="UTF-8"?>Without this resource-ref element in web.xml, the app fails with this error in JavaEE SDK 5/Glassfish/Sun Java System Application Server:
<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</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
javax.naming.NameNotFoundException: No object bound to name java:comp/env/jdbc/__defaultWe are not done yet. We also need to map the resource reference name (jdbc/__default) to the global JNDI name of the target resource (jdbc/__default). This step is appserver-dependent, usually editing an appserver-specific deployment plan file. For example, sun-ejb-jar.xml, sun-web.xml, sun-application-client.xml, or jboss.xml. The following shows how this is mapped in sun-web.xml:
at com.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:751)
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:30)
<?xml version="1.0" encoding="UTF-8"?>When the local reference name and the global JNDI name are the same, some application servers may also have some default mapping rules to eliminate this step. For instance, in JavaEE SDK 5 and Sun Java System Application Server 9, this step is not needed when the two names are the same.
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app error-url="">
<context-root>/webapp14</context-root>
<resource-ref>
<res-ref-name>jdbc/__default</res-ref-name>
<jndi-name>jdbc/__default</jndi-name>
</resource-ref>
<class-loader delegate="true"/>
</sun-web-app>
JavaEE 5 has introduced a series of annotations to greatly simplify configurations, such as @EJB, @EJBs, @Resource and @Resources. Using resource injections, applications no longer need to use ejb-ref, ejb-local-ref, nor resource-ref, and they may get rid of standard deployment descriptors altogether. But some sort of mapping mechanisms (default mapping rules, or appserver-specific deployment plans) are still needed.
More info on how to inject/lookup resources in JavaEE 5 and EJB 3, please refer to 5 Ways to Get Resources in EJB 3
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: