Search code examples
javajasper-reports

Unresolved symbols when compiling jasper report


When I attempt to compile a jrxml file created in jasper studio v6.2.0, using the jasperreports 6.2.1 library, I get the following errors:

net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:
/home/david_clymer/Development/VistaShare/OutcomeTracker/HUD329902_1461778704578_563528.java:477: error: cannot find symbol
                value = CONCATENATE(((java.lang.String)field_ns058Agency_Physical_City.getValue()),",",((java.lang.String)field_ns058Agency_Physical_State.getValue()),"  ",((java.lang.String)field_ns058Agency_Ph
ysical_Zip.getValue())); //$JR_EXPR_ID=40$
                        ^
  symbol:   method CONCATENATE(String,String,String,String,String)
  location: class HUD329902_1461778704578_563528

...

9 errors
.
        at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:215)
        at net.sf.jasperreports.engine.JasperCompileManager.compile(JasperCompileManager.java:357)
        at net.sf.jasperreports.engine.JasperCompileManager.compileToFile(JasperCompileManager.java:273)
        at net.sf.jasperreports.engine.JasperCompileManager.compileToFile(JasperCompileManager.java:232)
        at net.sf.jasperreports.engine.JasperCompileManager.compileReportToFile(JasperCompileManager.java:542)
        at RunReport.compileReport(RunReport.java:80)
        at RunReport.main(RunReport.java:192)

How do I ensure that these functions are imported and available?

This is the debugging I've done so far:

According to my googling, this results from the absence of jasperreports-functions-6.2.1.jar in the java classpath. However, in my case it most definitely is in the classpath, and testing shows that its classes are accessible, but the methods are not:

// Imports without error
import net.sf.jasperreports.functions.standard.TextFunctions;

public class Foo {
    public static void main(String[] args) {
        // Cannot resolve symbol INTEGER_VALUE
        Object foo = TextFunctions.INTEGER_VALUE;
    }
}

Decompiling the relevant class shows that the method is indeed there:

david_clymer@zapazoid:~/Development/VistaShare/OutcomeTracker/jasperreports/lib/tmp$ jar -xf ../jasperreports-functions-6.2.1.jar 
david_clymer@zapazoid:~/Development/VistaShare/OutcomeTracker/jasperreports/lib/tmp$ java -jar ../../../procyon-decompiler-0.5.30.jar net/sf/jasperreports/functions/standard/TextFunctions.class |grep -A 7 INTEGER_VALUE
    @Function("INTEGER_VALUE")
    @FunctionParameters({ @FunctionParameter("textNumber") })
    public static Integer INTEGER_VALUE(final String textNumber) {
        if (textNumber == null) {
            logNullTextString();
            return null;
        }
        return Integer.parseInt(textNumber);
    }

david_clymer@zapazoid:~/Development/VistaShare/OutcomeTracker/jasperreports/lib/tmp$ grep TextFunctions jasperreports_extension.properties 
net.sf.jasperreports.extension.functions.text=net.sf.jasperreports.functions.standard.TextFunctions

I'm not really a java programmer, so maybe I'm doing something stupid. I just don't know how to reference the methods properly so that I can be sure that they should work.

Update: using a static import:

import static net.sf.jasperreports.functions.standard.TextFunctions.*

Allows those functions to be imported into the current namespace.

So, back to the original issue. If set net.sf.jasperreports.compiler.keep.java.file=true in jasperreports.properties and attempt to compile the report, I can examine the java file that jasper produces from the jrxml. I find that this file does not seem to import the necessary functions (INTEGER_VALUE, CONCATENATE, etc). The only imports it contains are:

/*
 * Generated by JasperReports - 4/27/16 2:27 PM
 */
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.fill.*;
import net.sf.jasperreports.functions.standard.TextFunctions.*;

import java.util.*;
import java.math.*;
import java.text.*;
import java.io.*;
import java.net.*;

Solution

  • symbol: method CONCATENATE(String,String,String,String,String)

    The problem seems to be that the Java compiler is not able to resolve varargs calls, the method is defined as CONCATENATE(String ...strings).

    Add an ecj jar to your application's classpath (for instance the one from http://repo1.maven.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.3.1/), that's usually safer than relying on the JDK compiler.