编译jasper报告时未解析的符号

时间:2016-04-27 18:47:28

标签: java jasper-reports

当我尝试使用jasperreports 6.2.1库编译在jasper studio v6.2.0中创建的jrxml文件时,出现以下错误:

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)

如何确保导入这些功能并使其可用?

这是我到目前为止所做的调试:

根据我的谷歌搜索,这是因为java类路径中缺少jasperreports-functions-6.2.1.jar。但是,在我的情况下,它绝对是类路径中的 ,测试表明它的类是可访问的,但方法不是:

// 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;
    }
}

反编译相关类表明该方法确实存在:

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

我不是一个真正的java程序员,所以也许我做的事情很愚蠢。我只是不知道如何正确引用这些方法,以便我确定他们应该工作。

更新:使用静态导入:

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

允许将这些功能导入当前命名空间。

所以,回到原来的问题。如果在net.sf.jasperreports.compiler.keep.java.file=true中设置jasperreports.properties并尝试编译报告,我可以检查jasper从jrxml生成的java文件。我发现这个文件似乎没有导入必要的函数(INTEGER_VALUECONCATENATE等)。它包含的唯一导入是:

/*
 * 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.*;

3 个答案:

答案 0 :(得分:0)

得到与使用jasperreports-6.2.1.jarjasperreports-functions-6.2.1.jar相同的结果,使用jre 1.8.0_77进行编译(也使用jre1.7)

我的报告 java 文件中包含此方法:

public java.lang.String CONCATENATE(java.lang.String...  arg0)
{
    return getFunctionSupport(net.sf.jasperreports.functions.standard.TextFunctions.class).CONCATENATE(arg0);
}

并且函数调用正常工作(请注意,我没有在jrxml文件中添加任何导入,也没有以任何方式修改jasperreports_extension.properties

因此,您需要再次检查类路径中的库以及未与jasperreports_extension.properties

混淆的库

答案 1 :(得分:0)

为了在编译jasper报告时使这些函数可用,请将jrxml加载到DesignObject并显式添加必要的导入:

JRXmlLoader loader = new JRXmlLoader(new SimpleJasperReportsContext(), new Digester());
JasperDesign designFile = loader.load(fileName + ".jrxml");
String destinationFile = fileName + ".jasper";

// 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.DateTimeFunctions.*");
designFile.addImport("static net.sf.jasperreports.functions.standard.LogicalFunctions.*");

JasperCompileManager.compileReportToFile(designFile, destinationFile);

使用静态导入很重要。如果static关键字,则根据生成的java代码的要求,方法直接导入当前命名空间。

使用这种方法,不需要修改jasper报告本身。

答案 2 :(得分:0)

  

symbol:方法CONCATENATE(String,String,String,String,String)

问题似乎是Java编译器无法解析varargs调用,该方法被定义为CONCATENATE(String ... strings)。

将ecj jar添加到应用程序的类路径中(例如来自http://repo1.maven.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.3.1/的路径),这通常比依赖JDK编译器更安全。