鍍金池/ 教程/ Linux/ JDBC 數(shù)據(jù)源
連接器
JSPs
重寫機制
CGI
Tomcat Manager
Windows 認證
代理支持
虛擬主機
安全性注意事項
如何在 Maven 中使用 Tomcat 庫
安裝
MBean 描述符
JNDI 資源
類加載機制
Tomcat Web 應(yīng)用部署
基于 APR 的原生庫
負載均衡器
安全管理
附加組件
監(jiān)控與管理
Windows 服務(wù)
集群化與會話復(fù)制
高級 IO 機制
SSI(服務(wù)器端嵌入)
WebSocket 支持
JDBC 數(shù)據(jù)源
日志機制
默認 Servlet
SSL/TLS 配置
Tomcat 的 JDBC 連接池
第一個應(yīng)用
簡介
Realm 配置

JDBC 數(shù)據(jù)源

概述

JNDI 數(shù)據(jù)源配置的相關(guān)內(nèi)容已經(jīng)在 JNDI 資源文檔中詳細介紹過。但從 Tomcat 用戶的反饋意見來看,有些配置的細節(jié)問題非常棘手。

針對常用的數(shù)據(jù)庫,我們已經(jīng)給 Tomcat 用戶提供了一些配置范例,以及關(guān)于數(shù)據(jù)庫使用的一些通用技巧。本章就將展示這些范例和技巧。

另外,雖然有些注意事項來自于用戶所提供的配置和反饋信息,但你可能也有不同的實踐。如果經(jīng)過試驗,你發(fā)現(xiàn)某些配置可能具有廣泛的助益作用,或者你覺得它們會使本章內(nèi)容更加完善,請務(wù)必不吝賜教。

請注意,對比 Tomcat 7.x 和 Tomcat 8.x,JNDI 資源配置多少有些不同,這是因為使用的 Apache Commons DBCP 庫的版本不同所致。所以,為了在 Tomcat 8 中使用,你最好修改老版本的 JNDI 資源配置,以便能夠匹配下文范例中的格式。詳情可參看Tomcat 遷移文檔。

另外還要提示的是,一般來說(特別是對于本教程而言),JNDI 數(shù)據(jù)源配置會假定你已經(jīng)理解了 ContextHost 的配置偏好,其中包括在后者配置偏好中的應(yīng)用自動部署的相關(guān)內(nèi)容。

DriverManager,服務(wù)提供者機制以及內(nèi)存泄露

java.sql.DriverManager 支持服務(wù)提供者機制。這項功能的實際作用在于:對于所有可用的 JDBC 驅(qū)動,只要它們聲明提供 META-INF/services/java.sql.Driver 文件,就會被自動發(fā)現(xiàn)、加載并注冊,從而減輕了我們在創(chuàng)建 JDBC 連接之前還需要顯式地加載數(shù)據(jù)庫驅(qū)動的負擔(dān)。但在 servlet 容器環(huán)境的所有 Java 版本中,卻根本沒法實現(xiàn)這種功能。問題在于 java.sql.DriverManager 只會掃描一次驅(qū)動。

Tomcat 自帶的阻止 JRE 內(nèi)存泄漏偵聽器可以在一定程度上解決這個問題,它會在 Tomcat 啟動時觸發(fā)驅(qū)動掃描。該偵聽器默認是啟用的。只有可見于該偵聽器的庫(比如 $CATALINA_BASE/lib 中的庫)才能被數(shù)據(jù)庫驅(qū)動所掃描。如果你想禁用該功能,那么一定要記?。菏紫仁褂?JDBC 的 Web 應(yīng)用會觸發(fā)掃描,從而當(dāng)該應(yīng)用重新加載時會出錯;對于其他依賴該功能的 Web 應(yīng)用來說也會導(dǎo)致出錯。

所以,假如應(yīng)用的 WEB-INF/lib 目錄中存在數(shù)據(jù)庫驅(qū)動,那么這些應(yīng)用就不能依賴服務(wù)提供者機制,而應(yīng)該顯式地注冊驅(qū)動。

java.sql.DriverManager 中的驅(qū)動已經(jīng)被認為是內(nèi)存泄露之源。當(dāng) Web 應(yīng)用停止運行時,它所注冊的任何驅(qū)動都必須重新注冊。當(dāng) Web 應(yīng)用停止運行時,Tomcat 會嘗試自動尋找并重新注冊任何由 Web 應(yīng)用類加載器所加載的 JDBC 驅(qū)動。但最好是由應(yīng)用通過 ServletContextListener 來實現(xiàn)這一點。

數(shù)據(jù)庫連接池(DBCP 2)配置

Apache Tomcat 的默認數(shù)據(jù)庫連接池實現(xiàn)基于的是 Apache Commons 項目的庫,具體來說是這兩個庫:

  • Commons DBCP
  • Commons Pool

這兩個庫都位于一個 JAR 文件中:$CATALINA_HOME/lib/tomcat-dbcp.jar。但該文件只包括連接池所需要的類,包名也已經(jīng)改變了,以避免與應(yīng)用沖突。

DBCP 2.0 支持 JDBC 4.1。

安裝

可參閱 DBCP 文檔了解完整的配置參數(shù)。

防止數(shù)據(jù)庫連接池泄露

數(shù)據(jù)庫連接池創(chuàng)建并管理著一些與數(shù)據(jù)庫的連接。與打開新的連接相比,回收或重用現(xiàn)有的數(shù)據(jù)庫連接要更為高效一些。

連接池化還存在一個問題。Web 應(yīng)用必須明確地關(guān)閉 ResultSet、Statement,以及 Connection。假如 Web 應(yīng)用無法關(guān)閉這些資源時,會導(dǎo)致這些資源再也無法被重用,從而造成了數(shù)據(jù)庫連接池“泄露”。如果再也沒有可用連接時,最終這將導(dǎo)致 Web 應(yīng)用數(shù)據(jù)庫連接失敗。

針對該問題,有一個解決辦法:通過配置 Apache Commons DBCP,記錄并恢復(fù)這些廢棄的數(shù)據(jù)庫連接。它不僅能恢復(fù)這些連接,而且還能針對打開這些連接而又永遠不關(guān)閉它們的代碼生成堆棧跟蹤。

為了配置 DBCP 數(shù)據(jù)源來移除并回收廢棄的數(shù)據(jù)庫連接,將下列屬性(一個或全部)添加到你的 DBCP 數(shù)據(jù)源中的 Resource 配置中:

removeAbandonedOnBorrow=true

removeAbandonedOnMaintenance=true

以上屬性默認都為 false。注意,只有當(dāng) timeBetweenEvictionRunsMillis 為正值,從而啟用池維護時,removeAbandonedOnMaintenance 才能生效。關(guān)于這些屬性的詳情,可查看 DBCP 文檔 。

使用 removeAbandonedTimeout 屬性設(shè)置某個數(shù)據(jù)庫連接閑置的秒數(shù),超過此時段,即被認為是廢棄連接。

removeAbandonedTimeout="60"

默認的去除廢棄連接的超時為 300 秒。

logAbandoned 設(shè)為 true,可以讓 DBCP 針對那些拋棄數(shù)據(jù)庫連接資源的代碼,記錄堆棧跟蹤信息。

logAbandoned="true"

默認為 false。

MySQL DBCP 范例

0. 簡介

已報告的能夠正常運作的 MySQL 與 JDBC 驅(qū)動的版本號為:

  • MySQL 3.23.47、使用 InnoDB 的 MySQL 3.23.47、MySQL 3.23.58 以及 MySQL 4.0.1 alpha
  • Connector/J 3.0.11-stable (JDBC 官方驅(qū)動)
  • mm.mysql 2.0.14 (一個較老的 JDBC 第三方驅(qū)動)

在繼續(xù)下一步的操作之前,千萬不要忘了將 JDBC 驅(qū)動的 JAR 文件復(fù)制到 $CATALINA_HOME/lib 中。

1. MySQL 配置

一定要按照下面的說明去操作,否則會出現(xiàn)問題。

創(chuàng)建一個新的測試用戶、一個新的數(shù)據(jù)庫,以及一張新的測試表。必須為 MySQL 用戶指定一個密碼。如果密碼為空,那么在連接時,就會無法正常驅(qū)動。

mysql> GRANT ALL PRIVILEGES ON *.* TO javauser@localhost
    ->   IDENTIFIED BY 'javadude' WITH GRANT OPTION;
mysql> create database javatest;
mysql> use javatest;
mysql> create table testdata (
    ->   id int not null auto_increment primary key,
    ->   foo varchar(25),
    ->   bar int);

注意:一旦測試結(jié)束,就該把上例中的這個用戶刪除!

下面在 testdata 表中插入一些測試數(shù)據(jù):

mysql> insert into testdata values(null, 'hello', 12345);
Query OK, 1 row affected (0.00 sec)

mysql> select * from testdata;
+----+-------+-------+
| ID | FOO   | BAR   |
+----+-------+-------+
|  1 | hello | 12345 |
+----+-------+-------+
1 row in set (0.00 sec)

mysql>

2. 上下文配置

Context 中添加資源聲明,以便在 Tomcat 中配置 JNDI 數(shù)據(jù)源。

范例如下:

<Context>

    <!-- maxTotal: Maximum number of database connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to -1 for no limit.
         -->

    <!-- maxIdle: Maximum number of idle database connections to retain in pool.
         Set to -1 for no limit.  See also the DBCP documentation on this
         and the minEvictableIdleTimeMillis configuration parameter.
         -->

    <!-- maxWaitMillis: Maximum time to wait for a database connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->

    <!-- username and password: MySQL username and password for database connections  -->

    <!-- driverClassName: Class name for the old mm.mysql JDBC driver is
         org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
         Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
         -->

    <!-- url: The JDBC connection url for connecting to your MySQL database.
         -->

  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
               username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/javatest"/>

</Context>

3. web.xml 配置

為該測試應(yīng)用創(chuàng)建一個 WEB-INF/web.xml 文件:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

4. 測試代碼

創(chuàng)建一個簡單的 test.jsp 頁面,稍后將用到它。

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<sql:query var="rs" dataSource="jdbc/TestDB">
select id, foo, bar from testdata
</sql:query>

<html>
  <head>
    <title>DB Test</title>
  </head>
  <body>

  <h2>Results</h2>

<c:forEach var="row" items="${rs.rows}">
    Foo ${row.foo}<br/>
    Bar ${row.bar}<br/>
</c:forEach>

  </body>
</html>

JSP 頁面用到了 JSTL 的 SQL 和 Core taglibs。你可以從 Apache Tomcat Taglibs - Standard Tag Library 項目中獲取它,不過要注意應(yīng)該是 1.1.x 或之后的版本。下載 JSTL 后,將 jstl.jarstandard.jar 復(fù)制到 Web 應(yīng)用的 WEB-INF/lib 目錄中。

最后,將你的應(yīng)用部署到 $CATALINA_BASE/webapps,可以采用兩種方式:或者將應(yīng)用以名叫 DBTest.war 的 WAR 文件形式部署;或者把應(yīng)用放入一個叫 DBTest 的子目錄中。

部署完畢后,就可以在瀏覽器輸入 http://localhost:8080/DBTest/test.jsp,查看你的第一個勞動成果了。

Oracle 8i、9i 與 10g

0. 簡介

Oracle 需要的配置和 MySQL 差不多,只不過也存在一些常見問題。

針對過去版本的 Oracle 的驅(qū)動可能以 .zip 格式(而不是 .jar 格式)進行分發(fā)的。Tomcat 只使用 *.jar 文件,而且它們還必須安裝在 $CATALINA_HOME/lib 中。因此,classes111.zipclasses12.zip 這樣的文件后綴應(yīng)該改成 .jar。因為 jar 文件本來就是一種 zip 文件,因此不需要將原 zip 文件解壓縮然后創(chuàng)建相應(yīng)的 jar 文件,只需改換后綴名即可。

對于 Oracle 9i 之后的版本,應(yīng)該使用 oracle.jdbc.OracleDriver 而不是 oracle.jdbc.driver.OracleDriver,因為 Oracle 規(guī)定開始棄用 oracle.jdbc.driver.OracleDriver,下一個重大版本將不再支持這一驅(qū)動類。

1. 上下文配置

跟前文 MySql 的配置一樣,你也需要在 Context 中定義數(shù)據(jù)源。下面定義一個叫做 myoracle 的數(shù)據(jù)源,使用上文說的短驅(qū)動來連接(用戶名為 scott,密碼為 tiger)到名為 mysid 的SID(Oracle 系統(tǒng)ID,標(biāo)識一個數(shù)據(jù)庫的唯一標(biāo)示符)。 用戶 scott 使用的 Schema 就是默認的 schema。

使用 OCI 驅(qū)動,只需在 URL 字符串中將 thin 變?yōu)?oci 即可。

<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:mysid"
              username="scott" password="tiger" maxTotal="20" maxIdle="10"
              maxWaitMillis="-1"/>

2. web.xml 配置

在創(chuàng)建 Web 應(yīng)用的 web.xml 文件時,一定要遵從 Web 應(yīng)用部署描述符文件中 DTD 所需要的元素順序。

<resource-ref>
 <description>Oracle Datasource example</description>
 <res-ref-name>jdbc/myoracle</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>

3. 代碼范例

可以使用上文所列的范例應(yīng)用(假如你創(chuàng)建了所需的 DB 實例和表,等等),將數(shù)據(jù)源代碼用下面的代碼替換:

Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();
//etc.

PostgreSQL

0. 簡介

PostgreSQL 配置與 Oracle 基本相似。

1. 所需文件

將 Postgres 的 JDBC jar 文件復(fù)制到 $CATALINA_HOME/lib 中。和 Oracle 配置一樣,jar 文件必須放在這個目錄中,DBCP 類加載器才能找到它們。不管接下來如何配置,這是首先必須要做的。

2. 資源配置

目前有兩種選擇:定義一個能夠被 Tomcat 所有應(yīng)用所共享的數(shù)據(jù)源,或者定義只能被單個應(yīng)用所使用的數(shù)據(jù)源。

2a. 共享數(shù)據(jù)源配置

如果想定義能夠被多個 Tomcat 應(yīng)用所共享的數(shù)據(jù)源,或者只想在文件中定義自己的數(shù)據(jù)源,則采用如下配置:

盡管有些用戶反饋說這樣可行,但本文檔作者卻沒有成功,希望有人能闡述清楚。

<Resource name="jdbc/postgres" auth="Container"
          type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://127.0.0.1:5432/mydb"
          username="myuser" password="mypasswd" maxTotal="20" maxIdle="10" maxWaitMillis="-1"/>
2b. 應(yīng)用專屬的資源配置

如果希望專門為某一應(yīng)用定義數(shù)據(jù)源,其他 Tomcat 應(yīng)用無法使用,可以使用如下配置。這種方法對 Tomcat 安裝的損害性要小一些。

在你的應(yīng)用的 Context 中創(chuàng)建一個資源定義,如下所示:

<Context>

<Resource name="jdbc/postgres" auth="Container"
          type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
          url="jdbc:postgresql://127.0.0.1:5432/mydb"
          username="myuser" password="mypasswd" maxTotal="20" maxIdle="10"
maxWaitMillis="-1"/>
</Context>

3. web.xml 配置

<resource-ref>
 <description>postgreSQL Datasource example</description>
 <res-ref-name>jdbc/postgres</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>

4. 訪問數(shù)據(jù)庫

在利用程序訪問數(shù)據(jù)庫時,記住把 java:/comp/env 放在你的 JNDI lookup 方法參數(shù)的前部,如下面這段代碼所示。另外,可以用任何你想用的值來替換 jdbc/postgres,不過記得也要用同樣的值來修改上面的資源定義文件。

InitialContext cxt = new InitialContext();
if ( cxt == null ) {
   throw new Exception("Uh oh -- no context!");
}

DataSource ds = (DataSource) cxt.lookup( "java:/comp/env/jdbc/postgres" );

if ( ds == null ) {
   throw new Exception("Data source not found!");
}

非 DBCP 的解決方案

這些方案或者使用一個單獨的數(shù)據(jù)庫連接(建議僅作測試用?。?,或者使用其他一些池化技術(shù)。

Oracle 8i 與 OCI 客戶端

簡介

雖然并不能嚴格地解決如何使用 OCI 客戶端來創(chuàng)建 JNDI 數(shù)據(jù)源的問題,但這些注意事項卻能和上文提到的 Oracle 與 DBCP 解決方案結(jié)合起來使用。

為了使用 OCI 驅(qū)動,應(yīng)該先安裝一個 Oracle 客戶。你應(yīng)該已經(jīng)通過光盤安裝好了 Oracle 8i(8.1.7)客戶端,并從 otn.oracle.com 下載了適用的 JDBC/OCI 驅(qū)動(Oracle8i 8.1.7.1 JDBC/OCI 驅(qū)動)。

classes12.zip 重命名為 classes12.jar 后,將其復(fù)制到 $CATALINA_HOME/lib 中。根據(jù) Tomcat 的版本以及你所使用的 JDK,你可能還必須該文件中的刪除 javax.sql.* 類。

連接起來

確保在 $PATHLD_LIBRARY_PATH(可能在 $ORAHOME\bin)目錄下存在 ocijdbc8.dll.so 文件,另外還要確認能否使用 System.loadLibrary("ocijdbc8"); 這樣的簡單測試程序加載本地庫。

下面你應(yīng)該創(chuàng)建一個簡單測試用 servlet 或 jsp,其中應(yīng)該包含以下關(guān)鍵代碼:

DriverManager.registerDriver(new
oracle.jdbc.driver.OracleDriver());
conn =
DriverManager.getConnection("jdbc:oracle:oci8:@database","username","password");

目前數(shù)據(jù)庫是 host:port:SID 形式,如果你試圖訪問測試用servlet/jsp,那么你會得到一個 ServletException 異常,造成異常的根本原因在于 java.lang.UnsatisfiedLinkError:get_env_handle。

分析一下,首先 UnsatisfiedLinkError 表明:

  • JDBC 類文件和 Oracle 客戶端版本不匹配。消息中透露出的意思是沒有找到需要的庫文件。比如,你可能使用 Oracle 8.1.6 的 class12.zip 文件,而 Oracle 客戶端版本則是 8.1.5。classeXXXs.zip 文件必須與 Oracle 客戶端文件版本相一致。

  • 出現(xiàn)了一個 $PATH, LD_LIBRARY_PATH 問題。

  • 有報告稱,忽略從 otn 網(wǎng)站下載的驅(qū)動,使用 $ORAHOME\jdbc\lib 目錄中的 class12.zip 文件,同樣能夠正常運作。

接下來,你可能還會遇到另一個錯誤消息:ORA-06401 NETCMN: invalid driver designator。

Oracle 文檔是這么說的:“異常原因:登錄(連接)字符串包含一個不合法的驅(qū)動標(biāo)識符。解決方法:修改字符串,重新提交。”所以,如下面這樣來修改數(shù)據(jù)庫(host:port:SID)連接字符串:

(description=(address=(host=myhost)(protocol=tcp)(port=1521))(connect_data=(sid=orcl)))

常見問題

下面是一些 Web 應(yīng)用在使用數(shù)據(jù)庫時經(jīng)常會遇到的問題,以及一些應(yīng)對技巧。

數(shù)據(jù)庫連接間歇性失敗

Tomcat 運行在 JVM 中。JVM 周期性地會執(zhí)行垃圾回收(GC),清除不再使用的 Java 對象。當(dāng) JVM 執(zhí)行 GC 時,Tomcat 中的代碼執(zhí)行就會終止。如果配置好的數(shù)據(jù)庫連接建立的最長時間小于垃圾回收的時間,數(shù)據(jù)庫連接就會失敗。

在啟動 Tomcat 時,將 -verbose:gc 參數(shù)添加到 CATALINA_OPTS 環(huán)境變量中,就能知道垃圾回收所占用的時間了。在啟用 verbose:gc 后, $CATALINA_BASE/logs/catalina.out 日志文件就能包含每次垃圾回收的數(shù)據(jù),其中也包括它所占用的時間。

正確調(diào)整 JVM 后,垃圾回收可以做到在 99% 的情況下占用時間不超過 1 秒。剩余的情況則只占用幾秒鐘的時間,只有極少數(shù)情況下 GC 會占用超過 10 秒鐘的時間。

保證讓數(shù)據(jù)庫連接超時設(shè)定在 10~15 秒。對于 DBCP,可以使用 maxWaitMillis 參數(shù)來設(shè)置。

隨機性的連接關(guān)閉異常

當(dāng)某一請求從連接池中獲取了一個數(shù)據(jù)庫連接,然后關(guān)閉了它兩次時,往往會出現(xiàn)這樣的異常消息。使用連接池時,關(guān)閉連接,就會把它歸還給連接池,以便之后其他的請求能夠重用該連接,而并不會關(guān)閉連接。Tomcat 使用多個線程來處理并發(fā)請求。下面這個范例就演示了,在 Tomcat 中,一系列事件導(dǎo)致了這種錯誤。

運行在線程 1 中的請求 1 獲取了一個連接。

請求 1 關(guān)閉了數(shù)據(jù)庫連接。

JVM 將運行的線程切換為線程 2。

線程 2 中運行的請求 2 獲取了一個數(shù)據(jù)庫連接。
(同一個數(shù)據(jù)庫連接剛被請求 1 關(guān)閉)

JVM 又將運行的線程切換回為線程 1

請求 1 第二次關(guān)閉了數(shù)據(jù)庫連接。

JVM 將運行的線程切換回線程 2。

請求 2線程 2 試圖使用數(shù)據(jù)庫連接,但卻失敗了。因為請求 1 已經(jīng)關(guān)閉了它。

  Connection conn = null;
  Statement stmt = null;  // Or PreparedStatement if needed
  ResultSet rs = null;
  try {
    conn = ... get connection from connection pool ...
    stmt = conn.createStatement("select ...");
    rs = stmt.executeQuery();
    ... iterate through the result set ...
    rs.close();
    rs = null;
    stmt.close();
    stmt = null;
    conn.close(); // Return to connection pool
    conn = null;  // Make sure we don't close it twice
  } catch (SQLException e) {
    ... deal with errors ...
  } finally {
    // Always make sure result sets and statements are closed,
    // and the connection is returned to the pool
    if (rs != null) {
      try { rs.close(); } catch (SQLException e) { ; }
      rs = null;
    }
    if (stmt != null) {
      try { stmt.close(); } catch (SQLException e) { ; }
      stmt = null;
    }
    if (conn != null) {
      try { conn.close(); } catch (SQLException e) { ; }
      conn = null;
    }
  }

上下文與全局命名資源

注意,雖然在上面的說明中,把 JNDI 聲明放在一個 Context 元素里面,但還是有可能(而且有時更需要)把這些聲明放在服務(wù)器配置文件的 GlobalNamingResources 區(qū)域。被放置在 GlobalNamingResources 區(qū)域的資源將會被服務(wù)器的各個上下文所共享。

JNDI 資源命名和 Realm 交互

為了讓 Realm 能運作,realm 必須指向定義在 <GlobalNamingResources><Context> 區(qū)域中的數(shù)據(jù)源,而不是<ResourceLink> 重新命名的數(shù)據(jù)源。

上一篇:安裝下一篇:類加載機制