【信创问题】解决东方通(TongWeb)报错 java.lang.NoClassDefFoundError: javax/persistence/spi/PersistenceProvider

写在前边

今天帮现场同事定位问题,情况是项目同事使用东方通(TongWeb7.0)部署公司项目时,出现以下报错导致服务启动失败。

简单排查了下发现:war包内WEB-INF/lib/javax.persistence-api-2.2.jar中包含javax.persistence.spi.PersistenceProvider这个接口,不应该报这个错误呀。

Caused by: java.lang.NoClassDefFoundError: javax/persistence/spi/PersistenceProvider
	at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_371]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:756) ~[?:1.8.0_371]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_371]
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:473) ~[?:1.8.0_371]
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74) ~[?:1.8.0_371]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369) ~[?:1.8.0_371]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363) ~[?:1.8.0_371]
	at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_371]
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362) ~[?:1.8.0_371]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_371]
	at com.tongweb.server.TWServerURLClassLoader.loadClass0(TWServerURLClassLoader.java:46) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.access$000(TWServerURLClassLoader.java:11) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader$1.loadClass(TWServerURLClassLoader.java:40) ~[bootstrap.jar:?]
	at com.tongweb.common.LoadClassCache.cacheLoadClass(LoadClassCache.java:63) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.loadClass(TWServerURLClassLoader.java:37) ~[bootstrap.jar:?]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:405) ~[?:1.8.0_371]
	at com.tongweb.server.TWServerURLClassLoader.loadClass0(TWServerURLClassLoader.java:46) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.access$000(TWServerURLClassLoader.java:11) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader$1.loadClass(TWServerURLClassLoader.java:40) ~[bootstrap.jar:?]
	at com.tongweb.common.LoadClassCache.cacheLoadClass(LoadClassCache.java:63) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.loadClass(TWServerURLClassLoader.java:37) ~[bootstrap.jar:?]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_371]
	at com.tongweb.tongejb.core.ConnectorClassLoader.loadClass(ConnectorClassLoader.java:133) ~[tongweb.jar:?]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_371]
	at java.lang.Class.forName0(Native Method) ~[?:1.8.0_371]
	at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_371]
	at com.tongweb.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1286) ~[tongweb.jar:?]
	...省略无用信息
Caused by: java.lang.ClassNotFoundException: javax.persistence.spi.PersistenceProvider
	at java.net.URLClassLoader.findClass(URLClassLoader.java:387) ~[?:1.8.0_371]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_371]
	at com.tongweb.server.TWServerURLClassLoader.loadClass0(TWServerURLClassLoader.java:46) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.access$000(TWServerURLClassLoader.java:11) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader$1.loadClass(TWServerURLClassLoader.java:40) ~[bootstrap.jar:?]
	at com.tongweb.common.LoadClassCache.cacheLoadClass(LoadClassCache.java:63) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.loadClass(TWServerURLClassLoader.java:37) ~[bootstrap.jar:?]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_371]
	at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_371]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:756) ~[?:1.8.0_371]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_371]
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:473) ~[?:1.8.0_371]
	at java.net.URLClassLoader.access$100(URLClassLoader.java:74) ~[?:1.8.0_371]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:369) ~[?:1.8.0_371]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:363) ~[?:1.8.0_371]
	at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_371]
	at java.net.URLClassLoader.findClass(URLClassLoader.java:362) ~[?:1.8.0_371]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_371]
	at com.tongweb.server.TWServerURLClassLoader.loadClass0(TWServerURLClassLoader.java:46) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.access$000(TWServerURLClassLoader.java:11) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader$1.loadClass(TWServerURLClassLoader.java:40) ~[bootstrap.jar:?]
	at com.tongweb.common.LoadClassCache.cacheLoadClass(LoadClassCache.java:63) ~[bootstrap.jar:?]
	at com.tongweb.server.TWServerURLClassLoader.loadClass(TWServerURLClassLoader.java:37) ~[bootstrap.jar:?]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:405) ~[?:1.8.0_371]
	...省略无用信息

解决方法

先说解决方法:

  • 如果你的应用中包含javax.persistence-api-2.2.jar,则删除 东方通/lib/persistence-api.jar 即可。
  • 如果你的应用中不包含那个包,则把javax.persistence-api-2.2.jar下载下来放到 东方通/lib 目录下即可。

问题成因

javax.persistence-api是JavaEE的持久化API接口定义包,从2007年发布到Maven中央仓库开始,Maven坐标变更过好多次,每次变更的兼容性也一言难尽。

  • javax.persistence:persistence-api 2007年最古老的版本,1.0~1.0.2 版本是最常用的版本。
  • javax.persistence:javax.persistence-api 2017迁移Maven坐标,只发布了2.2版本,是目前最流行的版本。
  • jakarta.persistence:jakarta.persistence-api 2018年迁移Maven坐标,发布了2.2.x、3.0.x、3.1.x、3.2.x版本,3.2.0是2024年5月21日发布的截止发文前的最新版本。

东方通7.0版本自带的是最早期的版本(没标识是1.0还是1.0.2),只有2.2以上版本才有javax.persistence.spi.PersistenceProvider这个类的。

最后

信创环境资料少,如果本文对你有所帮助,请不吝点赞评论,你的支持就是我写作的鼓励!