JDBC-Ressource über JNDI referenzieren und mit Tomcat verwenden

Nachdem ich in [post id=4681]JNDI Ressourcen anlegen und benutzen[/post] gezeigt habe, wie man eine Zeichenkette über das JNDI verfügbar machen kann, ist es an der Zeit, sich etwas interessanteren Dingen zu widmen.

Ich hatte bereits erwähnt, dass man Datenbankverbindungen über JDBC ebenfalls mit JNDI referenzieren kann. Wie das geht, möchte ich eben am Beispiel einer MySQL-Datenbank zeigen, welche über einen Apache Tomcat 7 Application-Server angesprochen werden soll.

1. MySQL-Treiber zum Tomcat AS hinzufügen

Zuerst muss man einen MySQL-kompatiblen JDBC-Treiber dem Apache Tomcat-Server bekannt machen. Dazu kopiert man einen geeigneten Treiber (z.B. mysql-connector-java-5.1.9.jar) in das Library-Verzeichnis von Tomcat (z.B. E:\dev\env\java\tomcat\apache-tomcat-7.0.29\lib).

2. JDBC-Ressource in ../META-INF/context.xml definieren

src/main/webapp/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/my-webapp">
  <Resource name="jdbc/foo4"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/foo4"
            username="root"
            password="root"
            maxActive="8" 
            maxIdle="4" 
            maxWait="10000"
            auth="Container"
          />
</Context>

3. Datenbankverbindung mit JNDI-Ressource testen

src/main/webapp/index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import="javax.naming.Context" %>
<%@page import="javax.naming.InitialContext" %>
<%@page import="java.sql.Connection"%>
<%@page import="javax.sql.DataSource"%>
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>JNDI & JDBC in JSP</title>
  </head>
  <body>
    <h1>JDBC Test</h1>
    <%
      try {
        Context initialContext = new InitialContext();
        Context componentBindings = (Context) initialContext.lookup("java:comp/env");
        DataSource dataSource = (DataSource) componentBindings.lookup("jdbc/foo4");
        Connection connection = dataSource.getConnection();
        String connectionUrl = connection.getMetaData().getURL();
        out.println(connectionUrl); // should be "jdbc:mysql://localhost:3306/foo4"
        connection.close();
      } catch (Exception ex) {
        out.println("<h2>Exception:</h2>" + ex);
      }
    %>
  </body>
</html>

Hinweis:
Im offiziellen Apache Tomcat 7 JNDI Resources HOW-TO steht im Abschnitt JDBC Data Sources geschrieben, dass man die Ressource im Standard Deployment Descriptor (web.xml) referenzieren sollte:

src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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_3_0.xsd">
  <resource-ref>
    <res-ref-name>jdbc/foo4</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

Ich habe das nicht getan und es hat im Apache Tomcat 7.0.29 trotzdem funktioniert!

2 Gedanken zu „JDBC-Ressource über JNDI referenzieren und mit Tomcat verwenden“

  1. Hi Benny,
    sehr schönes Beispiel!
    (JDBC-Ressource über JNDI referenzieren und mit Tomcat verwenden)
    Eine echte Perle: kurz, knackig und läuft!
    Im Web findet man leider oft so viel unglaublichen stümerhaften Müll!
    VG
    Alex

  2. Aus der Doku: „If a resource has been defined in a element it is not necessary for that resource to be defined in /WEB-INF/web.xml. However, it is recommended to keep the entry in /WEB-INF/web.xml to document the resource requirements for the web application.“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.