我在NetBeans 6.8和IReport插件3.7.4的基于struts的web应用程序中使用JasperReport。我在操作类中得到以下错误:
java.lang.NullPointerException
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2266)
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2279)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2750)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:780)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at net.sf.jasperreports.engine.util.JRLoader.loadObject(JRLoader.java:188)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:381)
at net.sf.jasperreports.engine.JasperRunManager.runReportToPdfStream(JasperRunManager.java:186)
at com.bspl.psys.ilp.action.ReportAppLinkAction.execute(ReportAppLinkAction.java:65)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:619)
我在action类中使用了以下代码:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
ServletOutputStream servletOutputStream = response.getOutputStream();
InputStream reportStream = getServlet().getServletConfig().getServletContext().getResourceAsStream("SampleReport.jasper");
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/SampleDB?user=common&password=common");
JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream,new HashMap());
connection.close();
response.setContentType("application/pdf");
response.reset();
reportStream.close();
servletOutputStream.flush();
servletOutputStream.close();
} catch (Exception ex) {
ex.printStackTrace(printWriter);
response.setContentType("text/plain");
response.getOutputStream().print(stringWriter.toString());
}
return null;
}
请告诉我哪里做错了。这是我第一次使用JasperReport,在我的智慧的尽头:(
我认为问题出在报告本身。即使是这样简单的代码也会出错:
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/SampleDB?user=common&password=common);
JasperFillManager.fillReportToFile("D:/dropbox/report/SampleReport.jasper",new HashMap(), connection);
System.out.println("Done!");
} catch (Exception ex) {
ex.printStackTrace(printWriter);
response.setContentType("text/plain");
response.getOutputStream().print(stringWriter.toString());
}
return null;
}
这次出现了一个不同的错误消息:
java.lang.NullPointerException
at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:63)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:402)
at net.sf.jasperreports.engine.JasperFillManager.fillReportToFile(JasperFillManager.java:188)
at net.sf.jasperreports.engine.JasperFillManager.fillReportToFile(JasperFillManager.java:94)
at com.bspl.psys.ilp.action.ReportAppLinkAction.execute(ReportAppLinkAction.java:84)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:619)
但是当我在IReport设计器中查看报告时,预览显示正确。请帮助。仅仅开始报告就花了太长时间。
警告:我不是struts开发人员(更多的是JSF 1.2/2.0):
JasperReports对错误非常挑剔,非常冗长,除非你特别将其配置为静默行为。空指针异常通常来自你不期望的地方(图像/简单的文本等…),不幸的是,有时你得到错误的"loadObject"或"fillReport"调用很少或没有信息。
尝试将其分解为一系列步骤,并在调试器中查看它,以查看它究竟在哪里失败。一旦你把它拆开,这可能是一个不需要动脑筋的问题。删除所有图像等…并运行一个空白报告(实际上是一个hello world),以确保NPE不在报告中,并且您的框架能够正常工作。一旦你把它分成几个部分,它将非常容易调试。
通常你可以检查每一步:
//load == classloader (I'm inside JBoss so I have to explicitly define it)
//This is pseudo code pulled from my test environment
JasperReport report = JasperCompileManager.compileReport(load.getResourceAsStream("yourpackage/report.jrxml"));
JasperPrint print = JasperFillManager.fillReport(report, new Map<String, Object>(), java.sql.Connection);
JasperExportManager.exportReportToPdfStream(print, outStream);
我真的不建议在生产环境中编译(使用打印是最好的方式),但是我遇到了一系列的类加载问题(与JBoss相关),由图像和其他细节引起的NPE以及报告中各种不良脚本引起的错误。
在框架内进行测试,您将很快发现问题。Jasper可以说是目前最好的Java报告软件(它非常详细),但是调试起来相当令人恼火。
通过将其分解为步骤,可以更容易地调试和查看NPE实际存在的位置。您使用的代码似乎很好:我会将我的钱放在空流或报告中未定位的资源(可能是图像)。