1
votes

I'm trying to integrate JasperReports in a web application that runs on Struts2.
I'm using the struts2-jasperreports-plugin (2.3.15).

To do so I added in my struts2.xml the the mapping for the action method and to the image servlet, and I wrote an action that simply takes in input a jrxml source file and compiles the report.

Here is the configuration lines i added in struts2.xml

<package name="jasperreport" namespace="/jasperreports" extends="jasperreports-default">
    <action name="getJasperReport" class="....JasperReportAction" method="getJasperReport">
      <result name="success" type="jasper" >
        <param name="location">jasper/tmp/${outFile}</param>
        <param name="format">${format}</param>
        <param name="imageServletUrl">/servlets/image?image=</param>
      </result>
    </action>
</package>

<constant name="struts.action.excludePattern" value="/servlets/image*" />

And added in my web.xml the mapping for the servlet image:

<servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/servlets/image</url-pattern>
</servlet-mapping>

The action method is reported here:

public class JasperReportAction  extends ActionSupport {

    private java.sql.Connection sqlConnection;
    private String sourceFile;
    private String outFile;
    private String format;
    private String reportName;
    private String outputName;


    public JasperReportAction() {
        //initialize the connection...
    }

    //getters and setters..


    public String getJasperReport() {   
        try {
            String reportPath = "jasper/" + reportName;
            JasperCompileManager.compileReportToFile(reportPath,"jasper/tmp/" + outputName + ".jasper");
        }
        catch(Exception e) {
            logger.log("getJasperReport", e);
            return ERROR;
        }

        return SUCCESS;
    }
}

And I call the action with a JQuery load:

$("#jasperReport").load("url/getJasperReport.action",
    {
        "sourceFile": "source.jrxml", 
        "outFile"   : "outFile", 
        "format"    : "HTML",           
 });

I'm editing my reports with iReports 5.1.0 and if I create a report where the charts uses one of the default themes, the report is correctly compiled and it is displayed in my web application.

I tried to use a custom template, I've created it and exported the jar using iReport and finally put the theme jar under my WEB-INF/lib folder.

When I try to retrieve the report from my application the Struts dispatcher gives me the following error:

org.apache.struts2.dispatcher.Dispatcher - Exception occurred during processing request: null java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) .......

I get this error even if i try to open a report that doesn't use the custom theme. Unless I remove the theme jar.

It seems that no JasperReports Exception is thrown during the report compilation, since the logger in the catch block doesn't log anything, But the jasper file isn't created.

I've put in my WEB-INF/lib the jasperreports-chart-themes jar, I've tried versions 4.0.0 and 5.1.0 but I always get the same error.

When I show the report preview in iReport everything works fine.

Can someone tell me if I am missing something to do before using custom chart themes?

1
Can you post relevant parts of code and configuration ? (action, web.xml, struts.xml) - Andrea Ligios
I edited the post and added some info - giocarmine
I don't know why the exception is raising, but the runtime compilation is heavily discouraged in the documentation: "Again, don't use this in production code. You should of course either provide compiled templates, or do some sort of checking to avoid compiling the template on every request." My 2 cents: try to adjust your code to make it similar to the one in the tutorial, and once it works, start customizing, if necessary. - Andrea Ligios
Yes I've read the advice in the documentation, but my intention is to allow the user to upload and change the jrxml source later inside the webapp, so i need to recompile. But I will try to follow your advice, thanks :) - giocarmine

1 Answers

0
votes

In the end I have found what the problem is.
It was not systematic, but sometimes instead of an InvocationTargetException I was having a ClassNotFoundException.

I simply needed to add some jars in my webapp lib folder. What I needed was:

  • the custom theme jar (obviously)
  • jasperreports-chart-themes-5.1.0.jar (instead of the 4.0.0)
  • castor-1.2.jar

There are newer version of the castor libraries, but some other libraries (maybe jasperreports-chart-themes?) are not compatible with versions newer than 1.2. It seems that the class CastorException is searched in the package org.exolab.castor.core.exceptions that in the newer versions has been moved to the package org.exolab.castor.xml.