Tomcat 8.5.30+Jersey环境数据库连接失败:找不到合适驱动
解决Tomcat 8.5.30 + Jersey环境下数据库连接失败的问题
嘿,这个问题我之前碰到过好几个类似的场景,直接跑程序正常但一部署到Tomcat里就卡壳,大概率是类加载、驱动注册或者环境权限的问题,咱们一步步来排查解决:
1. 先排查JDBC驱动的类加载冲突
Tomcat有自己的类加载隔离机制,如果你把MySQL驱动jar(比如mysql-connector-java.jar)同时放在了项目的WEB-INF/lib和Tomcat的全局lib目录下,或者只放在项目里但Tomcat的类加载优先级导致驱动找不到,就会出现这种情况。
解决办法二选一:
- 把项目
WEB-INF/lib里的MySQL驱动jar删掉,放到Tomcat安装目录下的lib文件夹里,让Tomcat全局加载驱动; - 要是不想动Tomcat的全局配置,就在项目的
WEB-INF/web.xml里给Jersey添加类加载配置,让它优先加载项目内的驱动:
<servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.servlet.filter.classpath</param-name> <param-value>WEB-INF/lib</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
2. 手动注册JDBC驱动试试
在Tomcat的类加载隔离环境下,DriverManager有时候不会自动加载驱动类,直接调用getConnection()可能找不到驱动。你可以在连接数据库前手动加载驱动类:
修改你的connectToDatabase方法:
public static void connectToDatabase() { try { // 注意:MySQL 8.x用com.mysql.cj.jdbc.Driver,5.x用com.mysql.jdbc.Driver Class.forName("com.mysql.cj.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://141.41.121.76:3306/database", "user", "pass"); // 记得用完后关闭连接哦 } catch (Exception ex) { ex.printStackTrace(); } }
如果想更规范,推荐用Tomcat的JNDI数据源方式,不仅能避免类加载问题,还能实现连接池管理:
配置JNDI数据源步骤:
- 在Tomcat的
conf/context.xml里添加数据源配置:
<Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="user" password="pass" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://141.41.121.76:3306/database?useSSL=false&serverTimezone=UTC"/>
- 在项目的
WEB-INF/web.xml里添加资源引用:
<resource-ref> <description>Database Connection</description> <res-ref-name>jdbc/MyDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
- 修改代码获取连接:
public static void connectToDatabase() { try { Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); DataSource ds = (DataSource) envContext.lookup("jdbc/MyDB"); Connection conn = ds.getConnection(); // 业务操作... conn.close(); } catch (Exception ex) { ex.printStackTrace(); } }
3. 检查Tomcat的网络访问权限
有时候直接跑程序用的是当前用户的网络权限,但Tomcat作为服务运行时,可能没有访问数据库3306端口的权限:
- 先在Tomcat所在机器上用命令测试端口连通性:
telnet 141.41.121.76 3306或者nc -zv 141.41.121.76 3306; - 确认数据库服务器的防火墙是否允许Tomcat所在IP访问3306端口;
- 检查Tomcat运行的用户是否有访问外部网络的权限(比如Windows下的服务用户、Linux下的tomcat用户)。
4. 排查Jersey和Tomcat的依赖冲突
旧版本的Jersey可能和Tomcat 8.5的Servlet API版本不兼容,导致类加载异常。你可以:
- 确保Jersey版本和Tomcat 8.5兼容,比如使用Jersey 2.26及以上版本;
- 如果用Maven管理依赖,排除掉冲突的Servlet API依赖:
<dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.35</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </exclusion> </exclusions> </dependency>
最后提醒一下:你可以仔细看看ex.printStackTrace()输出的具体异常信息,比如是ClassNotFoundException(找不到驱动类)还是SQLException(连接超时/权限错误),这能帮你更快定位到具体问题哦!
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

