Right Outer Join

19 June 2009

Groovy Reports

Filed under: iReport — Tags: , , , — mdahlman @ 16:45

Java is Hard.

iReport is written in Java. This has lots of advantages to the end user: it handles internationalization extremely well, there are lots of external libraries to take advantage of, it’s cross-platform compatible, etc. But as a report developer I’m not all that keen to learn Java.

Here is an example of the pain of Java. I want my report to highlight in red any values that are larger than some threshold, so I create a parameter called “Threshold”. It gets a datatype of java.lang.Integer and a default value of 7. The choice of “java.lang.Integer” isn’t completely intuitive to me… but it’s listed right there in a dropdown list, so that’s fine. The default value, however, is a killer. If I leave it as “7” then I’ll get the following error when I try to run the report:

Errors compiling C:\temp\iReportBackups\report15.jasper!
Compilation exceptions: com.jaspersoft.ireport.designer.compiler.ErrorsCollector@172fedb
net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:
1. Cannot cast from int to Integer
value = (java.lang.Integer)(7); //$JR_EXPR_ID=0$
<-------------------->
2. Cannot cast from int to Integer
value = (java.lang.Integer)(7); //$JR_EXPR_ID=0$
<-------------------->
3. Cannot cast from int to Integer
value = (java.lang.Integer)(7); //$JR_EXPR_ID=0$
<-------------------->
3 errors
at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:195)
at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:525)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:561)
at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:986)
Compilation running time: 2,235!

On behalf of report developers everywhere who don’t know how to code Java, allow me to say, “What?!

It turns out that I need to set the default value of my parameter to “new java.lang.Integer(7)” (without the quotes). Now a Java developer will quibble that I don’t really need the java.lang prefix, and it’s not all that hard to understand. I disagree.

Next, let’s try a basic calculation. I want to divide Field1 by Field2. The unsuspecting report developer might try “$F{Field1} / $F{Field2}”. But this isn’t good Java. You’ll need to come up with this:

new java.lang.Integer( $F{Field1}.intValue() / $F{Field2}.intValue() )

Once you’ve got the hang of it, it’s easy enough to get what you need. But more complex calculations get even tougher to keep track of. Shouldn’t it be easier?

Groovy is Easy.

Fortunately, things can be much easier. Use Groovy. “What’s Groovy?” you ask? Lava lamps. (Sorry, I couldn’t help myself.) Actually, according to the Groovy website, “Groovy is like a super version of Java. It can leverage Java’s enterprise capabilities but also has cool productivity features like closures, builders and dynamic typing.” On behalf of report developers everywhere who don’t know how to code Java, allow me to say, “What?!

In more practical terms, Groovy is a scripting language based on Java. It’s like Java but easy. It means that I can set my default value for $P{Threshold} as “7” (without the quotes). It means I can calculate Field1 divided by Field2 as “$F{Field1} / $F{Field2}”.

You may have noticed that iReport has these menu choices:
File -> New… -> Empty Report
File -> New… -> Empty Report (using Groovy for expressions)
So for new reports you can choose the second option.

But what about existing reports? How can they be groovy too? In the Report Inspector panel click on the root report object. In the Properties panel you’ll find “Language” near the bottom. Change from the default value of “Java” to “Groovy”.

But what about the report wizard? You can create new report templates that default to Groovy. Refer to my older posts on finding and creating report templates for details on that.

Finally, here’s an additional tidbit: While a Java report will choke on “7”, a Groovy report will happily accept both “7” and “new java.lang.Integer(7)”. Totally groovy.

Advertisements

5 Comments »

  1. Excellent stuff. A required bookmark for anyone using iReport

    Comment by Baggypants — 13 July 2009 @ 03:28

  2. HOW TO SET THE SERIAL NO IN THE JASPER REPORT

    Hi friends,
    I am using jasper report in my application. In the table has 4 fields like code,name,address,phone number. If i generate the report i need to display the serial number like1,2,3…. for each record. I don’t know how to set. So please help me.

    Comment by Ranjan Prasad — 24 July 2009 @ 02:09

    • Ranjan,
      Since your question is not related to my article, please post your query to the jasperforge.org forums.

      Comment by mdahlman — 24 July 2009 @ 17:03

  3. I suspect the iReport just isn’t that good as a Java developer of about 15 years experience.

    I’m getting similar class cast exceptions in a dirt simple report ( a simple select with an AVG call in it).

    I’m averaging integers but of course the result might be a decimal or float. Problem is, iReport still thinks the datatype for the AVG aggregate is an integer.

    Worse, it fails on my server but works in the designer!

    Maybe we ought to use BiRT….

    Oh and the formusm at iReport and Jaspersoft were of no help…NO ONE has given any advice…

    Comment by Mike — 12 August 2009 @ 08:17

    • Mike,

      I’m sorry to hear that iReport isn’t working well for you. It’s hard to know from your post what is going wrong.

      It’s likely related to the data type of the field in the query. When you run a query in iReport, iReport uses the JDBC metadata returned with the result set to determine the field data type. This data type is frequently not the desired choice (details vary depending on the JDBC driver, but I seem to get BigDecimal when long or float would be more convenient). iReport is at the mercy of the JDBC driver here, but fortunately you can modify this data type to a value that you want. I would start by looking at that.

      If you post your .jrxml to the forum it may be easier for someone to help. It will be easier for others if you include a place holder SQL query so they can run the report without having your data. Something like this:
      SELECT ‘Type1’ as type, 1.1 as avgmetric

      I believe Mike is referring to this thread on the iReport forums:
      http://jasperforge.org/plugins/espforum/view.php?group_id=83&forumid=101&topicid=60458

      Comment by mdahlman — 9 September 2009 @ 15:05


RSS feed for comments on this post. TrackBack URI

Go on... leave a reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: