본문 바로가기

Lecture & Tip/Web[웹]

Tomcat 5.X 에서 JNDI Resources를 사용하기~

Tomcat 5.x에서 JNDI Resources를 사용하는 방법이 바꼈더군용~

삽질사마를 피하기 위해~ 적어 놓습니당~

예제는 oracle과 tomcat 이지욤~ 퍼왔습니당~
--------------------------------------------------------
[CODE]How to use JNDI for Oracle JDBC Connection Pooling with Tomcat 5.0 - 5.5 by Gregg Lagnese, MicroDeveloper, Inc. Jan. 21, 2005 Preface This document outlines the step necessary to setup JNDI resources on Tomcat for accessing Oracle databases, versions 8i through 10g. There are two possible ways to perform JNDI mapping; one uses a fixed logon, the other a dynamic one. In the later case you will be required to add the necessary code to collect the proper username and password. However, in doing this, configuration files may be used that can contain encrypted passwords thereby securing the database in the event that the Tomcat server is compromised. Nomenclature: <name> = where you substitute the necessary value [name] = an optional element or parameter Section Index Configuration Testing the changes Troubleshooting Making a User Dependent Connection Configuration Pre-requisite setup: Copy ojdbc14.jar (not 'ojdbc14.zip') to the <CATALINA_HOME>/common/lib directory. Steps to Implement: 1) Modify the server.xml file In <CATALINA_HOME>/conf/server.xml between <GlobalNamingResources> and </GlobalNamingResources> add the following <Resource name="jdbc/<alias>" auth="Container" type="oracle.jdbc.pool.OracleDataSource" driverClassName="oracle.jdbc.driver.OracleDriver" factory="oracle.jdbc.pool.OracleDataSourceFactory" url="jdbc:oracle:thin:@<host>:<port>:<sid>" [user=<user>] [password=<password>] maxActive="20" maxIdle="10" maxWait="-1" /> Example <!-- Global JNDI resources --> <GlobalNamingResources> <!-- Test entry for demonstration purposes --> <Environment name="simpleValue" type="java.lang.Integer" value="30"/> <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users --> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> <!-- Every connection to 'db1' uses the same user --> <Resource name="jdbc/db1" auth="Container" type="oracle.jdbc.pool.OracleDataSource" driverClassName="oracle.jdbc.driver.OracleDriver" factory="oracle.jdbc.pool.OracleDataSourceFactory" url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db1" user="scott" password="tiger" maxActive="20" maxIdle="10" maxWait="-1" /> <!-- Every connection to 'db2' must provide a username and password --> <Resource name="jdbc/db2" auth="Container" type="oracle.jdbc.pool.OracleDataSource" driverClassName="oracle.jdbc.driver.OracleDriver" factory="oracle.jdbc.pool.OracleDataSourceFactory" url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db2" maxActive="20" maxIdle="10" maxWait="-1" /> </GlobalNamingResources> 2) Modify the context.xml file In <CATALINA_HOME>/conf/context.xml between <Context> and </Context> add the following for each entry in the JNDI resource list: <ResourceLink global="jdbc/<alias>" name="jdbc/<alias>" type="oracle.jdbc.pool.OracleDataSource"/> Example <!-- The contents of this file will be loaded for each web application --> <Context> <!-- Default set of monitored resources --> <WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>META-INF/context.xml</WatchedResource> <!-- Uncomment this to disable session persistence across Tomcat restarts --> <!-- <Manager pathname="" /> --> <ResourceLink global="jdbc/db1" name="jdbc/db1" type="oracle.jdbc.pool.OracleDataSource"/> <ResourceLink global="jdbc/db2" name="jdbc/db2" type="oracle.jdbc.pool.OracleDataSource"/> </Context> 3) Modify the context's web.xml file In the <CONTEXT>/WEB-INF/web.xml between <web-app> and </web-app> add the following: <resource-ref> <description><Your Description></description> <res-ref-name>jdbc/<alias></res-ref-name> <res-type>oracle.jdbc.pool.OracleDataSource</res-type> <res-auth>Container</res-auth> </resource-ref> Example <resource-ref> <description>Oracle Development Datasource</description> <res-ref-name>jdbc/db1</res-ref-name> <res-type>oracle.jdbc.pool.OracleDataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <resource-ref> <description>Oracle Development Datasource</description> <res-ref-name>jdbc/db2</res-ref-name> <res-type>oracle.jdbc.pool.OracleDataSource</res-type> <res-auth>Container</res-auth> </resource-ref> 4) Restart Tomcat Testing the Changes 5) Create a connection class (in the example it will be called ConnectionPool.java) package com.microdeveloper.db.jndi; import oracle.jdbc.pool.OracleDataSource; import javax.naming.Context; import javax.naming.InitialContext; import java.io.Serializable; import java.sql.Connection;import java.sql.SQLException;import java.sql.ResultSet;import java.sql.Statement; import java.util.Properties; public class ConnectionPool implements Serializable { String message = "Not Connected"; public void init() { Connection conn = null; ResultSet rst = null; Statement stmt = null; try { Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); OracleDataSource ds = (OracleDataSource) envContext.lookup("jdbc/db1"); if (envContext == null) throw new Exception("Error: No Context"); if (ds == null) throw new Exception("Error: No DataSource"); if (ds != null) conn = ds.getConnection(); if (conn != null) { message = "Got Connection " + conn.toString() + ", "; stmt = conn.createStatement(); rst = stmt.executeQuery("SELECT 'Success obtaining connection' FROM DUAL"); } if (rst.next()) message = rst.getString(1); rst.close(); rst = null; stmt.close(); stmt = null; conn.close(); // Return to connection pool conn = null; // Make sure we don't close it twice } catch (Exception e) { e.printStackTrace(); } finally { // Always make sure result sets and statements are closed, // and the connection is returned to the pool if (rst != null) { try { rst.close(); } catch (SQLException e) {;} rst = null; } if (stmt != null) { try { stmt.close(); } catch (SQLException e) {;} stmt = null; } if (conn != null) { try { conn.close(); } catch (SQLException e) {;} conn = null; } } } public String getMessage() {return message;} } 6) Create a JSP page to test with: <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <html> <head><title>JSP Page</title></head> <body> <% com.microdeveloper.db.jndi.ConnectionPool ocp = new com.microdeveloper.db.jndi.ConnectionPool(); ocp.init(); %> <h2>Results</h2> Message: <%= ocp.getMessage() %> </body> </html> 7) Compile the class and deploy the context Either manually or through your IDE, compile the class, then deploy the context to Tomcat. Now run the JSP page created in step 6. You should see the following:: Results Message: Success obtaining connection Troubleshooting 8) Check the database first Verify database connectivity a) TNSPing the database b) Connect using the username and password in step 1 c) Verify the server, sid, and port 9) Driver error messages Driver errors usually look like (Cannot create JDBC driver of class '' for connect URL 'null'): Place the ojdbc14.jar file in the <CATALINA_HOME>\common\lib directory Do NOT place the JAR in your <CONTEXT>/WEB-INF/lib directory (this can cause problems) If used with an IDE that auto-deploys, exclude the JAR from the deployment Check that the factory and driver in the server.xml file is correct: driverClassName="oracle.jdbc.driver.OracleDriver" factory="oracle.jdbc.pool.OracleDataSourceFactory" Ensure that the resource link (step 2) is in either: the <CONTEXT>/META-INF>context.xml file - or - the <CATALINA_HOME>/META-INF>context.xml (for global deployment) Error messages that 'jdbc' is an unknown context: Verify that step (3) is complete and accurate Making a User Dependent Connection 10) Setup the server.xml file without the username and password Setup the server.xml file with an entry without the username and password specified as shown in the example below: <Resource name="jdbc/db2" auth="Container" type="oracle.jdbc.pool.OracleDataSource" driverClassName="oracle.jdbc.driver.OracleDriver" factory="oracle.jdbc.pool.OracleDataSourceFactory" url="jdbc:oracle:thin:@oracle.microdeveloper.com:1521:db2" maxActive="20" maxIdle="10" maxWait="-1" /> 11) Add code to the class to set the username and password In the class, before the connection is formed, add a call to the datasource to set the username and password. This can be done in one of two ways as shown below: try { Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); OracleDataSource ds = (OracleDataSource) envContext.lookup("jdbc/db2"); if (envContext == null) throw new Exception("Error: No Context"); if (ds == null) throw new Exception("Error: No DataSource"); if (ds != null){ ds.setUser("scott"); ds.setPassword("tiger"); conn = ds.getConnection(); } catch (Exception e) { e.printStackTrace(); } - or - try { Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); OracleDataSource ds = (OracleDataSource) envContext.lookup("jdbc/db2"); if (envContext == null) throw new Exception("Error: No Context"); if (ds == null) throw new Exception("Error: No DataSource"); if (ds != null){ conn = ds.getConnection("scott","tiger"); } catch (Exception e) { e.printStackTrace(); }[/CODE]