Reputation: 193
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
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:
Upvotes: 2