在 Tomcat 中为 Oracle 11g 安装 JNDI 数据源

Posted

技术标签:

【中文标题】在 Tomcat 中为 Oracle 11g 安装 JNDI 数据源【英文标题】:Installing a JNDI datasource for Oracle 11g in Tomcat 【发布时间】:2012-05-10 09:58:27 【问题描述】:

我在 Windows XP 上,使用 Tomcat 6(我要到月底才能升级到 7)。

我一直在尝试在 Oracle 11g 中实现 JNDI 数据库资源,但没有成功。

我计算机上的许多其他应用程序都可以使用相同的数据库凭据正常连接。我使用直接的 JDBC 制作了一个测试 JSP,并将其放入 Tomcat。连接也很好。

我像这样修改了我的 conf/server.xml 的一部分:

 <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
     <Resource name="jdbc/mydb"
               auth="Container"
               type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
               factory="oracle.jdbc.pool.OracleDataSourceFactory"
               url="jdbc:oracle:thin:@apollo.abc.acme.com:2222:mydatabase"
               user="joe"
               password="blow"
               maxActive="20"
               maxIdle="30"
               maxWait="-1"/>   

    <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"/>
  </GlobalNamingResources>

我的 conf/context.xml:

<Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <ResourceLink global="jdbc/mydb" name="jdbc/mydb" type="javax.sql.DataSource"/>


    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->

</Context>

我的 conf/web.xml:

 <resource-ref>
    <res-ref-name>jdbc/mydb</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

这是测试 JSP 的摘录,它在获取 JNDI 资源的地方出现了一个空指针异常:

Connection conn         = null;
ResultSet result        = null;
Statement stmt          = null;
String nsdtestcount     = null;
InitialContext ctx      = null;
Context envContext      = null;
javax.sql.DataSource ds = null;

try


    ctx        = new InitialContext();
    envContext = (Context)ctx.lookup("java:/comp/env");
    ds         = (DataSource)envContext.lookup("jdbc/mydb");
    conn       = ds.getConnection();      


catch (Exception e)

    System.out.println(nameJSP + "Failed to connect to the database: " +
    "\n ctx        =  " + ctx         +
    "\n envContext =  " + envContext  +
    "\n ds         =  " + ds          +
    "\n conn       =  " + conn          );

    e.printStackTrace();

摘自我的日志:

INFO: Server startup in 675 ms
testJNDI2.jsp: Failed to connect to the database:
 ctx        =  javax.naming.InitialContext@15356d5
 envContext =  org.apache.naming.NamingContext@69d02b
 ds         =  null
 conn       =  null
java.lang.NullPointerException
        at org.apache.jsp.testJNDI_jsp._jspService(testJNDI_jsp.java:114)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:877)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:594)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
        at java.lang.Thread.run(Thread.java:595)

堆栈跟踪中的代码:

 at org.apache.jsp.testJNDI_jsp._jspService(testJNDI_jsp.java:114)
   ctx        = new InitialContext();
    envContext = (Context)ctx.lookup("java:/comp/env");
    ds         = (DataSource)envContext.lookup("jdbc/mydb");
    conn       = ds.getConnection();     

conn = ds.getConnection();是第 114 行

来自我的 catalina 日志:

May 1, 2012 4:17:48 PM org.apache.tomcat.util.modeler.Registry registerComponent
SEVERE: Null component Catalina:type=DataSource,class=javax.sql.DataSource,name="jdbc/mydb"

我的 CATALINA_HOME/lib 的内容:

C:\tomcat\lib>ls -l

 annotations-api.jar
 catalina-ant.jar
 catalina-ha.jar
 catalina-tribes.jar
 catalina.jar
 ecj-3.3.1.jar
 el-api.jar
 jasper-el.jar
 jasper.jar
 jsp-api.jar
 log4j-1.2.16.jar
 ojdbc14.jar
 servlet-api.jar
 tomcat-coyote.jar
 tomcat-dbcp.jar
 tomcat-i18n-es.jar
 tomcat-i18n-fr.jar
 tomcat-i18n-ja.jar
 tomcat-juli-adapters.jar
 tomcat-juli.jar

C:\tomcat\lib>

我的JAVA/JDK jre/lib/ext的内容:

 C:\Program Files\Java\jdk1.5.0_22\jre\lib\ext>ls -l

 activation.jar
 dnsns.jar
 localedata.jar
 log4j-1.2.16.jar
 mail.jar
 nls_charset12.jar
 sunjce_provider.jar
 sunmscapi.jar
 sunpkcs11.jar

C:\Program Files\Java\jdk1.5.0_22\jre\lib\ext>

有什么我可以尝试的想法吗?我想让 Tomcat 中运行的所有东西都可以使用数据库资源(这是我的开发环境)

提前致谢。

【问题讨论】:

错误消息中的堆栈跟踪是什么?您将带有 JDBC 驱动程序的 JAR 文件放在哪里? 好点,我用所有这些信息更新了我的原始帖子。 您的代码正在吞噬堆栈跟踪。修改它以打印出来。此外,检查 Tomcat 日志以获取设置数据源的错误消息。 更新了 test.jsp 以打印堆栈跟踪,检查了我的 catalina 日志。我修改了我原来的帖子。感谢您的提示。 同时检查其他日志——只是为了确定。很明显,Tomcat 无法创建数据源。尚不清楚原因。 【参考方案1】:

可能存在多个问题,但首先是您在 $CATALINA_HOME/lib 和 $JAVA_HOME/jre/lib/ext 中有多个版本的 Oracle JDBC 驱动程序的多个副本。

第 1 步是删除除 $CATALINA_HOME/lib/ojdbc14.jar 之外的以下 JAR 的所有实例

ojdbc14.jar ojdbc14_g.jar ojdbc14dms.jar ojdbc14dms_g.jar classes12.jar classes12.zip classes12dms.jar

同时,删除 $JAVA_HOME/jre/lib/ext/servlet-api.jar。

第 2 步是 maxIdle > maxActive 没有任何意义。你想要 maxActive >= maxIdle。

【讨论】:

完成。仍然没有喜悦。我用更多错误信息和新目录列表更新了我的帖子。 不。您仍然有 ojdbc14.jar 的多个副本 我从我的 tomcat/lib 中拉出 ojdbc14.jar。错误消息没有变化。 这不是我建议你尝试的。它应该可以工作,但该 JAR 的标准位置是 $CATALINA_HOME/lib 中的单个副本。 我将 ojdbc14.jar 的位置切换到了 tomcat/lib。它没有帮助。我有另一个使用直接 jdbc 的 test.jsp,它可以很好地找到驱动程序、连接等。 Tomcat 需要额外的 JNDI jar 吗?【参考方案2】:

如tomcat site 上的示例所示,我相信“用户”应该是您资源定义中的“用户名”。

【讨论】:

以上是关于在 Tomcat 中为 Oracle 11g 安装 JNDI 数据源的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 7随系统自启动,并设置与Oracle 11G服务的依赖

suse enterprise Linux 11上配置 oracle11g和tomcat开机自启动

在窗口 10 中使用 oracle 11g 安装 informatica 8.6 时出错

webService 无法连接连接oracle 11g

oracle11g+tomcat 安装war包出错:IO 错误: The Network Adapter could not establish the connection

Worklight 6.1,Tomcat 7.0.42 上的 SQL 适配器 (Oracle 11g) JNDI 错误