Jay
Jay

Reputation: 193

jasperreports cannot compile with datetime functions - symbol not found

Jasperreports 6.5.1. In Studio I can run a report that has a textExpression of "TODAY()". In my web server app though, with the jasperreports jar embedded, I get this error:

error: cannot find symbol\r\n                value = TODAY( );

I have the DateTimeFunctions imported, and the function is on the java classpath, but I guess not for the compiler. This is what I have for code, with an attempt to import the required functions statically:

def c = new DateTimeFunctions()
def x = c.TODAY()

JRXmlLoader loader = new JRXmlLoader(new SimpleJasperReportsContext(), new Digester())
JasperDesign designFile = loader.load(sourceFilePath)

// Ensure that custom functions are available when compiling reports.
designFile.addImport("static net.sf.jasperreports.functions.standard.TextFunctions.*")
designFile.addImport("static net.sf.jasperreports.functions.standard.MathFunctions.*")
designFile.addImport("static net.sf.jasperreports.functions.standard.LogicalFunctions.*")
designFile.addImport("static net.sf.jasperreports.functions.standard.DateTimeFunctions.*")

JasperReport jasperReport = JasperCompileManager.compileReport(designFile)

I can compile other jrxml files but the one that has TODAY() in it throws the exception. I suspect this is the case for all the static imports but I can't even get beyond the TODAY() problem. Note that the datetime jar is there in the java classpath because I can call TODAY() as a test.

The source file is groovy; not sure whether that messes with the static imports, or what the problem is. Any help?

Thanks for Alex K's response confirming that nothing mysterious should be going on. I don't think I need groovy-all since I'm not scripting in groovy, it's just that the source file is in groovy. I looked at the generated java code for the JasperCompileManager and see

import static net.sf.jasperreports.functions.standard.DateTimeFunctions.*;

and in the evaluate() method I see

case 9 : 
{
    value = TODAY( ); //$JR_EXPR_ID=9$
    break;
}

However, still the TODAY() method cannot be found. I will rewrite the groovy file as a java file to see if groovy is messing things up. For instance, maybe the method name in all caps is a problem. Or the compiler version - running under 1.8. Anyway, grasping at straws, but will try to stay afloat.

=====================

Ok, I created a java test file to see why I couldn't resolve "TODAY()". Here it is, using a static import as generated in the java code from the jrxml file:

import java.util.Date;
import static net.sf.jasperreports.functions.standard.DateTimeFunctions.*;

class Test {
  Date dtest() {
    return TODAY();
  }

  public static void main(String[] args) {
    Test t = new Test();
    Date d = t.dtest();
    System.out.println(d);
  }
}

And compiling it gives:

javac -cp ./jasperreports-6.5.1.jar;./jasperreports-functions-6.5.1.jar Test.java
Test.java:6: error: cannot find symbol
            return TODAY();
                   ^
symbol:   method TODAY()
location: class Test
1 error

Ok, my java skills aren't the best, so what am I missing here? I am compiling with java version "1.8.0_171".

The only way I can make this work is if the statically imported method is declared "public static". That is,

public static Date TODAY() { ...

but that is not what is in the DateTimeFunctions.java source.

=========================

So, if I read the 6.6.0 documentation here: http://jasperreports.sourceforge.net/sample.reference/functions/index.html, the sample DateTimeFunctions are all declared static, which seems to me to be correct. So, have I downloaded bogus functions jars for 6.5.1, and 6.6.0, and are the "real" ones somewhere yet-to-be-discovered?

Upvotes: 1

Views: 2041

Answers (1)

Alex K
Alex K

Reputation: 22867

You don't need to add import in case using groovy language at template and having org.codehaus.groovy:groovy-all and net.sf.jasperreports:jasperreports-functions libraries at classpath.

This jrxml working fine:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="TODAY using" whenNoDataType="AllSectionsNoDetail" language="groovy">
    <title>
        <band height="60">
            <textField>
                <reportElement x="0" y="30" width="100" height="30"/>
                <textFieldExpression><![CDATA[TODAY()]]></textFieldExpression>
            </textField>
        </band>
    </title>
</jasperReport>

Dependencies:

<dependencies>
    <!-- some dependencies -->

    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>6.5.1</version>
    </dependency>

    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.0.1</version>
    </dependency>

    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports-functions</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

The same is working for default java language.


The static imports is also working at JasperReports.

The example of using some method from Guava library:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Static import" whenNoDataType="AllSectionsNoDetail">
    <import value="static com.google.common.base.Strings.repeat"/>
    <title>
        <band height="60">
            <textField>
                <reportElement x="0" y="30" width="200" height="30"/>
                <textFieldExpression><![CDATA[repeat("a", 3)]]></textFieldExpression>
            </textField>
        </band>
    </title>
</jasperReport>

The generated result will be:

PDF output

Upvotes: 2

Related Questions