GlassFish 7.0+IntelliJ数据库访问报IncompatibleClassChangeError求助
解决GlassFish 7.0部署时Jackcess的IncompatibleClassChangeError问题
错误本质分析
报错java.lang.IncompatibleClassChangeError: class com.healthmarketscience.jackcess.impl.DatabaseImpl can not implement com.healthmarketscience.jackcess.Database, because it is not an interface的核心原因是类加载冲突:
GlassFish服务器的类加载器加载了与项目依赖版本不一致的Jackcess类,导致原本应为接口的com.healthmarketscience.jackcess.Database被加载成普通类,子类DatabaseImpl自然无法实现它。
另外你提到本地运行正常、部署到服务器出错,也验证了是服务器环境的依赖冲突问题——本地只有项目自带的依赖,而服务器中存在旧版本或不兼容的Jackcess类。
排查与解决步骤
1. 清理GlassFish中的冲突依赖
- 检查GlassFish安装目录下的
glassfish/lib,以及当前域目录domains/[你的域名]/lib,查找是否存在jackcess*.jar或包含Jackcess类的其他jar包。 - 如果发现旧版本Jackcess(比如1.x版本,该版本中
Database是类而非接口),直接删除该jar包,替换为项目使用的jackcess-2.1.6.jar。
2. 强制Web应用优先加载自身依赖
在项目的WEB-INF目录下创建或修改glassfish-web.xml,添加类加载优先级配置,让Web应用优先使用自身WEB-INF/lib中的依赖,而非服务器全局依赖:
<glassfish-web-app> <class-loader delegate="false"/> </glassfish-web-app>
3. 确保项目依赖正确打包
检查Maven依赖配置,确保Jackcess和UCanAccess的scope为默认的compile(无需手动指定),这样打包时会自动将这些jar包放入WAR的WEB-INF/lib目录:
<dependency> <groupId>com.healthmarketscience.jackcess</groupId> <artifactId>jackcess</artifactId> <version>2.1.6</version> </dependency> <dependency> <groupId>net.sf.ucanaccess</groupId> <artifactId>ucanaccess</artifactId> <version>4.0.0</version> </dependency>
4. 清理缓存并重新部署
- 清理IntelliJ缓存:
File -> Invalidate Caches...,重启IDE后执行mvn clean package重新构建WAR包。 - 清理GlassFish缓存:删除
domains/[你的域名]/cache和domains/[你的域名]/applications下的项目相关文件,再重新部署WAR包。
5. 尝试升级兼容版本(可选)
如果以上步骤无效,可以尝试升级到更稳定的版本组合:
- UCanAccess 5.0.1 + Jackcess 3.0.1,该组合适配Java 8+,与GlassFish 7兼容性更好。
代码优化建议
另外你的代码存在两个可优化点:
- 用
PreparedStatement替代Statement,避免SQL注入风险:
String sql = "select CustID, CustPassword from Customers where CustID = ?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, id); ResultSet rs = pstmt.executeQuery();
- 使用try-with-resources自动关闭资源,避免泄漏:
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C:/Users/Josh/IdeaProjects/Java3Lab2/ChattBankMDB.mdb"); PreparedStatement pstmt = con.prepareStatement(sql)) { // 执行查询与结果处理逻辑 } catch (Exception e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Joshua Conklin
相关产品推荐
相关产品推荐

