tomcat配置全局和私有JNDI数据源
本人CentOS上部署了tomcat,在配置JNDI数据源时,先后遇到了两种报错。
第一种,Cannot create JDBC driver of class '' for connect URL 'null',这个根据我个人理解是没有获取到数据源的任何信息,只要根据配置的方式(全局或私有)检查一下配置文件即可;
第二种,Cannot create PoolableConnectionFactory (IO Error: Got minus one from a read call),查下原因有多种:1:数据库连接满了,扩大数据库连接池;2:所登录的机子IP不在sqlnet.ora内,加入后重启listerner即可;3:数据库负载均衡时,指定了(SERVER=DEDICATED),去除这个即可;4:网管在Oracle配置上限制了该台机子访问Oracle的权限,这个问题基本和2类似,也是修改Oracle配置即可。在一堆复杂的操作前,可以先根据配置的方式的不同(全局、私有、以及项目目录下WEB-INF/classes/config.properties文件)检查一下配置文件中是否存在maxIdle和maxActive配置项,将其删除。
补充:第二个报错我发现了新的可能性,将环境改成两个docker容器后,tomcat容器连接oracle容器也会报这个错,但最后发现原因是JDBC连接的IP地址需要改成容器的虚拟IP,可能是防火墙或监听的问题。
(1).全局
目前找到的全局配置方法有两种。
1)主修改tomcat根目录下的conf/context.xml文件
在tomcat根目录下的conf/context.xml文件中<context>标签内添加如下内容:
<Resource name="[自定义数据源名称]"
auth="Container"
type="javax.sql.DataSource"
username="[数据库用户名]"
password="[数据库密码]"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@[数据库IP地址]:[数据库端口]/[服务名]" />
注意:driverClassName和url根据数据库类型和jar包而存在差异。首先看Mysql,如下:
driverClassName:
com.mysql.jdbc.Driver # mysql-connector-java 5.x及之前版本中的
com.mysql.cj.jdbc.Driver # mysql-connector-java 6.x及后续版本中的
url:
jdbc:mysql://[数据库IP地址]:[数据库端口]/[库名]
再看Orcale,如下:
driverclassName:
oracle.jdbc.driver.OracleDriver #ojdbc类型的jar包
com.mchange.v2.c3p0.ComboPooledDataSource #没用过,查到是c3p0类型的jar包
url:
jdbc:oracle:thin:@[数据库IP地址]:[数据库端口]:[SID]
jdbc:oracle:thin:@//[数据库IP地址]:[数据库端口]/[服务名] #Oracle 11g及以上版本,@后面的//可以省略
jdbc:oracle:thin:@[TNSName] #oracle 10.2.0.1及以上版本支持TNSName
其他常见数据库连接可以参考:https://blog.csdn.net/l13880647015/article/details/106571467/。
接着,在项目目录下WEB-INF/web.xml文件的<webapp>标签内添加如下内容:
<resource-ref>
<res-ref-name>[数据源名称]</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
注意:<res-ref-name>标签的值与<Resource>中name参数的值相同。
最后,重启tomcat程序。
2)主修改tomcat根目录下的conf/server.xml文件,辅修改tomcat根目录下的conf/context.xml文件
首先,在tomcat根目录下的conf/server.xml文件的<GlobalNamingResources>标签内添加如下内容:
<Resource name="[自定义资源名称]"
auth="Container"
type="javax.sql.DataSource"
username="[数据库用户名]"
password="[数据库密码]"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@[数据库IP地址]:[数据库端口]/[服务名]" />
其次,在tomcat根目录下的conf/context.xml文件的<Context>标签内添加如下内容:
<ResourceLink name="[自定义数据源名称]" global="[资源名称]" type="javax.sql.DataSource" />
接着,在项目目录下WEB-INF/web.xml文件的<webapp>标签内添加如下内容:
<resource-ref>
<res-ref-name>[数据源名称]</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
注意:<ResourceLink>中global参数的值与<Resource>中name参数的值相同,<res-ref-name>标签的值与<ResourceLink>中name参数的值相同。
最后,重启tomcat程序。
(2).私有
目前找到的私有配置方法也是两种。
1)主修改tomcat根目录下的conf/server.xml文件
首先,在tomcat根目录下的conf/server.xml文件的<Host>标签内添加如下内容:
<Context path="/ygfp" docBase="ygfp" reloadable="true">
<Resource name="[自定义数据源名称]"
auth="Container"
type="javax.sql.DataSource"
username="[数据库用户名]"
password="[数据库密码]"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@[数据库IP地址]:[数据库端口]/[服务名]"/>
</Context>
接着,在项目目录下WEB-INF/web.xml文件的<webapp>标签内添加如下内容:
<resource-ref>
<res-ref-name>[数据源名称]</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
注意:<res-ref-name>标签的值与<Resource>中name参数的值相同。
最后,重启重启tomcat程序。
2)创建项目目录的META-INF\context.xml文件
创建项目目录的META-INF\context.xml文件,并添加如下内容:
<?xml version="1.0" encoding="UTF-8"?>
<Context reloadable="true">
<Resource name="[自定义数据源名称]"
auth="Container"
type="javax.sql.DataSource"
username="[数据库用户名]"
password="[数据库密码]"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@[数据库IP地址]:[数据库端口]/[服务名]"/>
</Context>
通过tomcat web管理页面启动项目即可。
(3).补充
1)项目配置文件或程序中调用的JNDI要与自定义数据源名称保持一致;
2)补充Resource中参数说明:
maxIdle:数据库最大空闲连接的数量(待命),设 0 为没有限制。
maxWait:最大建立连接等待时间,单位为ms,设-1表示无限制。
maxActive:数据库最大连接数,设0为没有限制。
3)同时存在多种配置方式且同名,会获取哪一个:
首先,全局配置大于私有配置,也就是说若全局和私有同时存在,优先获取全局配置的数据源
全局:在context.xml中,<Resource>和<ResourceLink>(引用server.xml中<GlobalNamingResources> )同时存在,哪个标签在前获取到哪一个,即按顺序获取。
私有:1. 若只存在<Host>标签中的配置,不存在META-INF中的context.xml,则优先获取<Host>中配置的第一个数据源;2. 若两种私有配置方式都存在,会获取META-INF中context.xml配置的数据源。
4)为什么web.xml中的配置可有可无,却要加上呢?
详情见tomcat的docs:jndi-resources-howto.html
其中有这么一句话:
If a resource has been defined in a <Context> 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.
也就是说,在web.xml加入的那段代码仅起到说明作用,说明这个Web应用引用了哪些资源!详情请翻阅文档。
参考文档:JNDI学习总结(二):tomcat配置全局和私有JNDI数据源的几种方式 - 水狼一族 - 博客园 (cnblogs.com)
https://blog.csdn.net/digyso888/article/details/3671170
相关文章
- 并行类加载——让tomcat玩转双十一
- nginx+tomcat 架构 HttpServletRequest.getScheme()获取正确的协议
- tomcat 启动日志乱码,idea中运行Tomcat也出现中文乱码:“淇℃伅”
- 服务管理-tomcat
- Linux下安装和配置JDK与Tomcat(升级版)
- Tomcat下使用war包发布项目
- tomcat如何配置环境变量
- java:eclipse4.4 安装tomcat插件
- 【java】基于Tomcat的WebSocket转帖 + 自己理解
- Zabbix运维---使用jmx远程监控tomcat
- CVE-2020-1938 Tomcat任意文件读取漏洞复现
- 总结tomcat的核心组件以及根目录结构
- 通过EmbeddedServletContainerCustomizer接口调优Tomcat
- Tomcat卷四----Tomcat 服务器配置
- Tomcat server launch debug - OrderAnalytics
- Hybris Commerce里和Tomcat相关的一些配置信息
- Linux操作系统环境下jdk的配置和tomcat中web项目部署(从U盘中)
- Linux复习资料——一篇文章学会安装Java(免环境配置)以及tomcat服务
- Ubuntu 16.04安装Tomcat 8 图解
- Tomcat
- 优化tomcat配置(从内存、并发、缓存4个方面)优化
- 探秘Tomcat——一个简易的Servlet容器
- eclipse中配置tomcat
- 【手写Tomcat】9.实现游览器访问我们自定义的MyServlet
- Tomcat安装和配置
- tomcat Context容器(中):Tomcat如何隔离Web应用?
- Shell tomcat多实例部署