net.sf.jasperreports.engine.JRRuntimeException:找不到函数MONTH

时间:2017-08-18 23:21:17

标签: java groovy jasper-reports

我正在使用桌面应用程序,使用Java Swing和Jasper Reports生成报告。几天前,由于我的代码无法找到的Groovy函数,我遇到了一个问题。我发现this answer并且问题已经解决了(请注意我留下了评论)但是当我打包我的应用程序并尝试从控制台运行它时,我遇到了同样的问题。这是堆栈跟踪:

net.sf.jasperreports.engine.JRRuntimeException: Function MONTH not found.
    at net.sf.jasperreports.compilers.GroovyEvaluator.functionCall(GroovyEvaluator.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:59)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
    at subReporteSummary_1502405767221_591326.methodMissing(calculator_subReporteSummary_1502405767221_591326:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:939)
    at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1262)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1215)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at subReporteSummary_1502405767221_591326.evaluateEstimated(calculator_subReporteSummary_1502405767221_591326:336)
    at net.sf.jasperreports.engine.fill.JREvaluator.evaluateEstimated(JREvaluator.java:342)
    ... 14 more

但是当我检查jar时,我能够找到MONTH类中的net.sf.jasperreports.functions.standard.DateTimeFunctions函数

@Function("MONTH")
@FunctionParameters({
    @FunctionParameter("dateObject")})
public static Integer MONTH(Object dateObject){
    return getCalendarFieldFromDate(dateObject,Calendar.MONTH)+1;
}

来自我的类​​路径中的jasperreports-functions包并添加到包中,您可以通过我的maven配置注意到

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <repositories>
        <!-- Jasper Reports repository to get japerreports-functions -->
        <repository>
            <id>jr-ce-releases</id>
            <url>http://jaspersoft.artifactoryonline.com/jaspersoft/jr-ce-releases</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.4.0</version>
            <!-- Exclusions to avoid some JasperReports certificates problems -->
            <exclusions>
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bcmail-jdk14</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>bouncycastle</groupId>
                    <artifactId>bcmail-jdk14</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bctsp-jdk14</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>bouncycastle</groupId>
                    <artifactId>bcprov-jdk14</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Groovy functions for Jasper Reports-->
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports-functions</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.12</version>
        </dependency>

        <!-- Driver needed to connect to the DB -->
        <dependency>
            <groupId>com.ibm.informix</groupId>
            <artifactId>jdbc</artifactId>
            <version>4.10.8.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- This is to include all my dependencies in my package (it works fine) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>ar.edu.unt.gui.MainFrame</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>

        <resources>
            <resource>
                <!-- I don't want to package the reports' source file -->
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>*.jrxml</exclude>
                </excludes>
            </resource>
        </resources>
    </build>
</project>

从子报表调用MONTH函数。我在Jaspersoft社区中找到this post但我的报告没有<returnValue>标记。这是声明子报表的主报表中的片段:

<summary>
    <band height="239" splitType="Stretch">
        <subreport>
            <reportElement x="0" y="0" width="469" height="200" uuid="2da4b923-ee34-4a6d-9a04-8d050a2feb0f"/>
            <subreportParameter name="NRO_PAGINAS_PADRE">
                <subreportParameterExpression><![CDATA[$V{PAGE_NUMBER}]]></subreportParameterExpression>
            </subreportParameter>
            <connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
            <subreportExpression><![CDATA["subReporteSummary.jasper"]]></subreportExpression>
        </subreport>
        <textField evaluationTime="Auto">
            <reportElement x="175" y="219" width="126" height="20" uuid="28a4ff7e-d6dd-47f5-a655-5e0ea7bec50b"/>
            <textElement textAlignment="Center" verticalAlignment="Middle"/>
            <textFieldExpression><![CDATA["- Página " + $V{NRO_PAGINA_ACTUAL} + " de " + $V{PAGE_NUMBER} + " -"]]></textFieldExpression>
        </textField>
    </band>
</summary>

这是调用MONTH函数的subReporteSummary.jrxml(西班牙语的summarySubreport)片段:

<variable name="NOMBRE_MES" class="java.lang.String" resetType="None">
    <variableExpression><![CDATA[MONTH($F{fechacancelacion}) == 1? "Enero" :
    MONTH($F{fechacancelacion}) == 2? "Febrero" :
    MONTH($F{fechacancelacion}) == 3? "Marzo" :
    MONTH($F{fechacancelacion}) == 4? "Abril" :
    MONTH($F{fechacancelacion}) == 5? "Mayo" :
    MONTH($F{fechacancelacion}) == 6? "Junio" :
    MONTH($F{fechacancelacion}) == 7? "Julio" :
    MONTH($F{fechacancelacion}) == 8? "Agosto" :
    MONTH($F{fechacancelacion}) == 9? "Septiembre" :
    MONTH($F{fechacancelacion}) == 10? "Octubre" :
    MONTH($F{fechacancelacion}) == 11? "Noviembre" : "Diciembre"]]></variableExpression>
    <initialValueExpression><![CDATA[MONTH($F{fechacancelacion}) == 1? "Enero" :
    MONTH($F{fechacancelacion}) == 2? "Febrero" :
    MONTH($F{fechacancelacion}) == 3? "Marzo" :
    MONTH($F{fechacancelacion}) == 4? "Abril" :
    MONTH($F{fechacancelacion}) == 5? "Mayo" :
    MONTH($F{fechacancelacion}) == 6? "Junio" :
    MONTH($F{fechacancelacion}) == 7? "Julio" :
    MONTH($F{fechacancelacion}) == 8? "Agosto" :
    MONTH($F{fechacancelacion}) == 9? "Septiembre" :
    MONTH($F{fechacancelacion}) == 10? "Octubre" :
    MONTH($F{fechacancelacion}) == 11? "Noviembre" : "Diciembre"]]></initialValueExpression>
</variable>

简要说明:fechacancelacion是一个java.util.Date变量,表达式用于以大写形式获取月份名称(是一项要求),这是DATEFORMAT函数无法获得的因为它只给我一些小写的名字。

但回到这个问题并总结一下,我的JAR中有MONTH函数,当我从IDE(Netbeans)运行我的应用程序时,报告编译并正确显示但是我得到了一个从java -jar myapp-1.0.jar文件夹中使用target从控制台运行的错误。

如果您需要任何其他证据,请将其评论出来。任何帮助将不胜感激。提前感谢您的回答

1 个答案:

答案 0 :(得分:1)

如果您正在使用maven shade插件打包jar,则必须合并所有jar中的jasperreports_extension.properties,如here所述,以便注册JasperReports扩展(例如函数)正常。