You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat 8.5中JNDI DataSource查找失败问题求助

问题原因及正确配置方式

问题根源

你当前的配置存在冲突:Tomcat中,当在server.xml的<Host>节点下直接定义了指定path="/app1"的<Context>时,Tomcat会忽略conf/Catalina/localhost/app1.xml这个独立上下文配置文件。这就导致app1.xml里定义的jdbc/APP1OS数据源根本没被加载,自然会出现JNDI查找失败的报错。

简单来说:同一上下文路径的配置,server.xml中的硬编码配置优先级高于localhost目录下的XML文件,后者直接被跳过,数据源也就没注册到JNDI容器中。

正确配置方案

有两种规范配置方式,任选其一即可:

方案一:仅使用独立上下文配置文件(推荐)

删掉server.xml中<Host>下的<Context>节点,只保留conf/Catalina/localhost/app1.xml的配置:

  • 修改后的server.xml Host部分:
<Host appBase="webapps" deployOnStartup="false" autoDeploy="false" name="localhost" unpackWARs="true">
    <!-- 移除原有的<Context>节点 -->
</Host>
  • 保留app1.xml的完整配置(包含数据源Resource):
<Context displayName="Application One" path="/app1" swallowOutput="true">
    <Resource name="jdbc/APP1OS" auth="Container" type="javax.sql.DataSource" 
            driverClassName="com.mysql.cj.jdbc.Driver" 
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            maxActive="100"
            maxIdle="10"
            maxWait="5000"
            maxAge="60000"
            username="username"
            password="password"
            url="jdbc:mysql://dbname:port/appint?useUnicode=true&amp;characterEncoding=UTF-8&amp;rewriteBatchedStatements=true&amp;characterSetResults=utf8&amp;serverTimezone=UTC&amp;socketTimeout=300000&amp;useSSL=false&amp;requireSSL=false&amp;allowPublicKeyRetrieval=true"
            testOnBorrow="true"
            validationQuery="Select '1'"/>      
</Context>

这种方式是Tomcat官方推荐的配置方式,避免直接修改server.xml(server.xml修改后需重启整个Tomcat,而独立上下文文件支持热加载)。

方案二:在server.xml中统一配置(适合全局共享资源场景)

如果一定要保留server.xml中的<Context>节点,可将数据源Resource直接定义在该<Context>内部(即你已经验证有效的方式),或者通过<ResourceLink>引用全局数据源:

  • 先在server.xml的<GlobalNamingResources>下定义全局数据源:
<GlobalNamingResources>
    <Resource name="jdbc/APP1OSGlobal" auth="Container" type="javax.sql.DataSource" 
            driverClassName="com.mysql.cj.jdbc.Driver" 
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            maxActive="100"
            maxIdle="10"
            maxWait="5000"
            maxAge="60000"
            username="username"
            password="password"
            url="jdbc:mysql://dbname:port/appint?useUnicode=true&amp;characterEncoding=UTF-8&amp;rewriteBatchedStatements=true&amp;characterSetResults=utf8&amp;serverTimezone=UTC&amp;socketTimeout=300000&amp;useSSL=false&amp;requireSSL=false&amp;allowPublicKeyRetrieval=true"
            testOnBorrow="true"
            validationQuery="Select '1'"/>
</GlobalNamingResources>
  • 再在server.xml的<Context>中添加ResourceLink:
<Host appBase="webapps" deployOnStartup="false" autoDeploy="false" name="localhost" unpackWARs="true">
    <Context displayName="Application One" path="/app1" reloadable="true">
        <ResourceLink name="jdbc/APP1OS" global="jdbc/APP1OSGlobal" type="javax.sql.DataSource"/>
    </Context>
</Host>

这种方式适合多个应用共享同一数据源的场景,但修改server.xml需要重启Tomcat,灵活性较差。

额外注意事项

  • 确保MySQL驱动jar包放在Tomcat/lib目录下,不要放在应用的WEB-INF/lib中,否则容器级数据源会加载失败。
  • 确认deployOnStartup="false"和autoDeploy="false"的配置,避免Tomcat自动部署webapps下的应用,与手动配置的上下文产生冲突。

内容的提问来源于stack exchange,提问作者arunK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:37:11