我们的Web应用程序遇到了复杂的情况
它是STS /开发的Spring应用程序Tomcat 7。将应用程序与集成后Jasper report 4.6.0,它总是抛出`OutOfMemoryError:PermGen Space。然后,使其正常工作的唯一方法是重新启动应用程序。但是过了一会儿又发生了。这是例外之前的日志:
Tomcat 7
Jasper report 4.6.0
Oct 17, 2012 3:42:27 PM org.apache.jasper.compiler.TldLocationsCache tldScanJar INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. Oct 17, 2012 3:42:30 PM org.apache.catalina.core.ApplicationDispatcher invoke SEVERE: Servlet.service() for servlet jsp threw exception
这是例外中的一部分,我在其中找到了一些有关Jasper:
Jasper
at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:442) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:378) at org.apache.jaspercompiler.Compiler.compile(Compiler.java:353) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:340) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:646) at org.apache.jasper.servlet.JspServletWrapper.loadTagFile(JspServletWrapper.java:240) at org.apache.jasper.compiler.TagFileProcessor.loadTagFile(TagFileProcessor.java:578) at org.apache.jasper.compiler.TagFileProcessor.access$000(TagFileProcessor.java:49) at org.apache.jasper.compiler.TagFileProcessor$TagFileLoaderVisitor.visit(TagFileProcessor.java:655)
发生这种情况时,有一些发现:
没有任何Jasper Report组件的页面上可能会发生此问题。似乎Jasper Report bean一直在尝试查找标记lib a request is processed by the back end and responded to the front end。通常,从日志文件中可以看到,在所有后端操作(JPA管理)完成之前,不会引发上述异常
a request is processed by the back end and responded to the front end
在调试模式下运行log4J时,我看到大量信息,例如从Jasper模板(文本字段,钢笔,盒子…)解析/渲染所有组件,从巨大的日志中可以看到一个小片段:
2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester.sax -- startElement(http://jasperreports.sourceforge.net/jasperreports,textElement,textElement) 2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester -- Pushing body text '' 2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester -- New match='jasperReport/summary/band/textField/textElement' 2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester -- Fire begin() for FactoryCreateRule[className=net.sf.jasperreports.engine.xml.JRTextElementFactory, attributeName=null, creationFactory=net.sf.jasperreports.engine.xml.JRTextElementFactory@12dc6007] 2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester -- [FactoryCreateRule]{jasperReport/summary/band/textField/textElement} New net.sf.jasperreports.engine.design.JRDesignTextField 2012-10-17 15:29:12,025 -- DEBUG -- org.apache.commons.digester.Digester.sax -- ignorableWhitespace()
尽管如此,当对该页面的请求不包含任何Jasper组件时,仍会生成此日志。
我做了一些研究,但仍然找不到解决此问题的方法。
第一个问题是jasperreport bean应用程序中甚至存在一个问题,即使它没有与当前服务自动连线(为什么当前页面没有任何碧玉组件),为什么它总是运行。有这种情况的解决方案/答案吗?
jasperreport bean
同样从异常消息中,至少扫描了一个JAR来查找TLD,但其中不包含TLD。在org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:442)
应该来自Tomcat,然后Tomcat never contains any JSTL jar,我假设它找不到匹配的TLD来解析jasper报告,因此对所有jar进行完整扫描。如果是这样,那么为什么org.apache.commons.digester.Digester在解析jasper模板时似乎却忙于大量调试日志呢?
Tomcat never contains any JSTL jar
org.apache.commons.digester.Digester
通常,使该线程只是试图找出解决方案的方法,并找到一个答案,为什么Jasper如此活跃在不需要它的地方,以及如何让tomcat正确解析模板?
如果太冗长,表示歉意,并感谢您提供任何提示。
谢谢大家提供有关此问题的解决方案,我已经根据我的具体情况确定了问题,以下是解决方案:
使用.jasper而不是.jrxml作为模板!
我们知道这.jasper是一个已编译的模板以及.jrxml该模板的ASCII源代码,因此,如果在当前spring应用程序中使用原始源代码文件(jrxml)作为模板,则至少spring框架工作必须编译该源代码文件。这是Spring框架的效率问题,因为它是处理编译的jasper bean,并且不能保证编译仅执行一次并且仅在应用程序启动时发生。
.jasper
.jrxml
简而言之,将所有模板替换为.jasper文件后,日志大小已显着减小,并且不再出现内存不足的问题。我猜想Spring容器可能会在运行时消耗大量资源来将jrxml编译为jasper。因此,Jasper或Spring应该可以对它进行一些改进。