I'm working in a desktop application for generating reports with Java Swing and Jasper Reports. Some days ago I ran into a problem because of a Groovy function that my code was not able to find. I found this answer and the problem was solved (note I left a comment) but when I packaged my application and tried to run it from the console I got the same issue. This is the stacktrace:
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
But when I inspect the jar I'm able to find the MONTH
function, which is in the net.sf.jasperreports.functions.standard.DateTimeFunctions
class
@Function("MONTH")
@FunctionParameters({
@FunctionParameter("dateObject")})
public static Integer MONTH(Object dateObject){
return getCalendarFieldFromDate(dateObject,Calendar.MONTH)+1;
}
from the jasperreports-functions
package which is in my classpath and is added to the package, as you may note by my maven configuration
<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>
The MONTH
function is called from a subreport. I found this post in the Jaspersoft Community but my report doesn't have such <returnValue>
tag. This is the fragment from the main report where the subreport is declared:
<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>
And this is the subReporteSummary.jrxml
(summarySubreport in spanish) fragment where the MONTH function is called:
<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>
briefly: fechacancelacion
is a java.util.Date
variable and the expression is for get the month's names in upper case (is a requirement), which I can't get with a DATEFORMAT
function because it gives me the names only in lowercase.
But getting back to the issue and to summarize, I have the MONTH
function available in my JAR, the report compiles and shows correctly when I run my application from the IDE (Netbeans) but I'm getting an error running from the console with java -jar myapp-1.0.jar
from the target
folder.
If you need any other evidence, comment it out. Any help will be appreciated. Thanks in advance for your answers