Ошибка JasperReport в веб-приложении Struts

Я использую JasperReport в веб-приложении на основе Struts с NetBeans 6.8 и подключаемым модулем IReport 3.7.4. Я получаю следующую ошибку в классе действий:

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)

Я использовал следующий код в классе действий:

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, предварительный просмотр отображается правильно. Пожалуйста помоги. Слишком много времени уходит только на то, чтобы начать репортаж.


person Derek    schedule 04.04.2011    source источник
comment
Если у вас есть дополнительные примечания или подробности, предоставьте их, отредактировав исходный вопрос. Сообщения ниже должны быть только ответами.   -  person Sampson    schedule 05.04.2011


Ответы (1)


Предостережение: я не разработчик Struts (больше JSF 1.2/2.0):

JasperReports довольно привередлив и очень многословен в отношении ошибок, если только вы специально не настроите его так, чтобы он вел себя тихо. Исключения нулевого указателя часто возникают из мест, которых вы не ожидаете (изображения/простой текст и т. д.), и, к сожалению, иногда вы получаете ошибку в вызовах «loadObject» или «fillReport» с небольшой информацией или без нее.

Попробуйте разбить его на несколько шагов и посмотреть в отладчике, чтобы увидеть, где именно он терпит неудачу. Это, вероятно, не составит труда, если вы разобьете его на части. Удалите все изображения и т. д. и запустите пустой отчет (буквально привет, мир), чтобы убедиться, что 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. Код, который вы используете, выглядит нормально: я бы поставил свои деньги на нулевой поток или ресурс в отчете, который не находится (скорее всего, изображение).

person Daniel B. Chapman    schedule 04.04.2011