You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BIRT从4.4迁移至4.9时资源路径归一化至null报错求助

BIRT 4.4迁移至4.9后报表布局打开报错分析

问题描述

将BIRT从4.4版本迁移至4.9版本后,运行报表并打开布局时触发错误:The resource path [ /…/…]has been normalized to null which is not valid

相关代码片段

InputStream fileLayout = new ByteArrayInputStream(EntityUtils.toByteArray(methodLayoutReport.getEntity()));

String reportEnder = servlet.getRealPath("Report/include/glw/view/report") + "/" + reportName + ".rptdesign";

design = birtReportEngine.openReportDesign(reportEnder, fileLayout);// 报错行

完整错误堆栈

INFO: Server startup in [23135] milliseconds
java.lang.IllegalArgumentException: The resource path [/WEB-INF/classes/…/…/…/…/estrutura/est_report_library_base.rptlibrary] has been normalized to [null] which is not valid
at org.apache.catalina.webresources.StandardRoot.validate(StandardRoot.java:266)
at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:212)
at org.apache.catalina.webresources.StandardRoot.getClassLoaderResource(StandardRoot.java:225)
at org.apache.catalina.loader.WebappClassLoaderBase.findResource(WebappClassLoaderBase.java:954)
at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:1078)
at org.eclipse.birt.report.model.util.ResourceLocatorImplBase.tryFragmentSearch(ResourceLocatorImplBase.java:289)
at org.eclipse.birt.report.model.util.ResourceLocatorImplBase.getResource(ResourceLocatorImplBase.java:179)
at org.eclipse.birt.report.model.util.ResourceLocatorImplBase.findResource(ResourceLocatorImplBase.java:80)
at org.eclipse.birt.report.model.core.ModuleImpl.findResource(ModuleImpl.java:1181)
at org.eclipse.birt.report.model.parser.IncludedLibrariesStructureListState$IncludedLibraryStructureState.end(IncludedLibrariesStructureListState.java:99)
at org.eclipse.birt.report.model.util.XMLParserHandler.endElement(XMLParserHandler.java:177)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl.parse(Unknown Source)
at org.eclipse.birt.report.model.parser.ModuleReader.readModule(ModuleReader.java:94)
at org.eclipse.birt.report.model.parser.DesignReader.read(DesignReader.java:81)
at org.eclipse.birt.report.model.core.DesignSessionImpl.openDesign(DesignSessionImpl.java:293)
at org.eclipse.birt.report.model.api.SessionHandleImpl.openDesign(SessionHandleImpl.java:257)
at org.eclipse.birt.report.model.api.SessionHandle.openDesign(SessionHandle.java:1)
at org.eclipse.birt.report.engine.parser.ReportParser.getDesignHandle(ReportParser.java:136)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.getReportDesignHandle(ReportEngineHelper.java:211)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.openReportDesign(ReportEngineHelper.java:223)
at org.eclipse.birt.report.engine.api.impl.ReportEngineHelper.openReportDesign(ReportEngineHelper.java:156)
at org.eclipse.birt.report.engine.api.impl.ReportEngine.openReportDesign(ReportEngine.java:307)
at br.com.ipm.report.servlet.WebReport.doPost(WebReport.java:93)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:239)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:215)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:199)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)

问题原因分析

  • 路径校验严格性提升:BIRT 4.9依赖的Tomcat版本(通常为9+)对资源路径规范化的校验远严于旧版本。报错路径中包含过多../(显示为…),规范化后超出Web应用根目录范围,被Tomcat判定为无效路径返回null。
  • 报表库引用路径错误:.rptdesign文件中引用的est_report_library_base.rptlibrary使用了错误的相对路径层级,导致BIRT引擎查找资源时生成越界路径。
  • getRealPath不可靠:代码中使用servlet.getRealPath()获取物理路径,该方法在部分部署场景(如war包不解压、容器自定义配置)下会返回不准确的路径,进一步干扰资源定位。

解决方案建议

  • 修正报表库引用路径:打开.rptdesign文件,调整库引用为正确的相对路径(相对于报表设计文件),或使用类路径绝对路径(如/estrutura/est_report_library_base.rptlibrary,确保库文件放在WEB-INF/classes/estrutura目录下)。
  • 替换getRealPath:改用getServletContext().getResourceAsStream()通过类加载器获取资源,或自定义BIRT的ResourceLocator实现资源查找逻辑。
  • 规范化路径:确保传递给BIRT引擎的所有资源路径提前完成规范化处理,避免出现过多../导致路径越界。

内容的提问来源于stack exchange,提问作者Murilo Costa Bittencourt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 00:54:28