旧Jasper发票模板编译修改后报ReportExpressionEvaluationData类找不到错误
问题描述
现有一个用于生成发票的旧Jasper模板,由Java应用程序调用。对模板做新修改并编译时,出现以下ClassNotFoundException错误:
Caused by: java.sql.SQLException: net.sf.jasperreports.engine.JRException: Class not found when loading object from file : C:\... at org.hibernate.impl.SessionImpl.doWork(SessionImpl.java:1987) ... 16 more Caused by: net.sf.jasperreports.engine.JRException: Class not found when loading object from file : C:\.... at net.sf.jasperreports.engine.util.JRLoader.loadObject(JRLoader.java:105) Caused by: java.lang.ClassNotFoundException: net.sf.jasperreports.compilers.ReportExpressionEvaluationData at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at java.io.ObjectInputStream.resolveClass(Unknown Source) at net.sf.jasperreports.engine.util.ContextClassLoaderObjectInputStream.resolveClass(ContextClassLoaderObjectInputStream.java:75) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at java.util.HashMap.readObject(Unknown Source) at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeReadObject(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at net.sf.jasperreports.engine.util.JRLoader.loadObject(JRLoader.java:97) ... 19 more
同时发现编译时会修改旧模板中的表达式,即便在编译选项中选择项目旧版本,该问题依旧存在。已尝试修改模板版本,但未解决问题。
解决方案
1. 严格对齐JasperReports版本
编译模板使用的JasperReports版本,必须和Java应用程序运行时依赖的版本完全一致(包括主版本、次版本、补丁版本)。ReportExpressionEvaluationData是特定版本新增的类,若编译版本高于运行时版本,必然出现找不到类的错误。
- 检查Maven/Gradle依赖中的JasperReports版本,同时确认编译模板的JasperStudio或编译插件版本与依赖版本完全匹配。
2. 开启编译兼容模式
- 若用JasperStudio编译:
- 打开模板属性的
Compile配置页 - 勾选
Compile for compatibility with older JasperReports versions - 指定与应用程序匹配的目标版本
- 打开模板属性的
- 若用代码编译,通过参数指定兼容版本:
JasperCompileManager.compileReportToFile( "template.jrxml", "template.jasper", new HashMap<>(), new HashMap<>(), "5.6.0" // 替换为应用程序使用的版本 );
3. 清理编译残留
- 删除所有已生成的
.jasper文件,从.jrxml重新编译,避免旧编译文件干扰。 - 清理应用程序构建缓存(如Maven的
target、Gradle的build目录),确保运行时加载的是版本匹配的类文件。
4. 回退表达式语法
新修改的表达式可能使用了高版本专属语法,导致编译时自动转换为新版本结构。回退修改的表达式,使用旧版本支持的语法重新编写,避免引入新版本特性。
5. 使用旧版本编译工具
若上述方法无效,下载与应用程序依赖完全一致的旧版本JasperStudio,用该版本打开并编译模板,彻底避免新版本编译逻辑的干扰。
内容的提问来源于stack exchange,提问作者Sergio
相关产品推荐
相关产品推荐

