Jump to content
JasperReports Library 7.0 is now available ×

ict-programmer
Go to solution Solved by ict-programmer,

Recommended Posts

I am using JasperStudio 5.5.1 and JasperServer 5.5.0.  I wrote a small Scriptlet which extends JRDefaultScriptlet.  Everything works perfectly, except that it works perfectly twice.  The only method I'm overriding is afterDetailEval().  I know that this was an issue raised several years ago (http://community.jaspersoft.com/questions/528909/every-function-my-scriptlet-called-twice), and I have done everything I can to find any duplicate jars, including using Tattletale, but cannot find anything.  I have been able to learn that my class is only being initialized once (I put a System.out in the constructor, and it only prints once), but the afterDetailEval() method is being run twice.  I'm thinking that there must be a simple solution, but I can't find it.  This problem happens both when I run the report from JasperStudio and when I run it from JasperServer.

I have a report that gets a list of accounts and the e-mails associated with each account.  The idea is that after each detail is evaluated, the program sends the info to the Jasper Server Scheduler so that account statements are automatically e-mailed for each account.  If anyone has an idea of an easier/better way to do this, that would be helpful, too.  Everything works great except that two e-mails get scheduled for each account instead of one.  (For testing purposes, right now it only sends to the 1023 account.)

Scriptlet:

package mypackage;import java.io.OutputStreamWriter;import java.net.Authenticator;import java.net.HttpURLConnection;import java.net.PasswordAuthentication;import java.net.URL;import java.text.SimpleDateFormat;import java.util.Arrays;import java.util.Calendar;import java.util.Date;import java.util.List;import java.util.Random;import net.sf.jasperreports.engine.JRDefaultScriptlet;import net.sf.jasperreports.engine.JRScriptletException;public class MonthEnd extends JRDefaultScriptlet {    Date sched;    Calendar cal;    SimpleDateFormat mySQLDateFormat;    SimpleDateFormat scheduletime;    int randVal;       public MonthEnd() {        sched = new Date();        cal = Calendar.getInstance();        mySQLDateFormat = new SimpleDateFormat("yyyy-MM-dd");        scheduletime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        Random rand = new Random();        randVal = rand.nextInt();               System.out.println("Initialized MonthEnd - "+randVal);        cal.setTime(sched);        // the e-mails will start about 30 seconds after the report is run (because incrementTime will also be run)        cal.add(Calendar.SECOND, 20);    }       private String incrementTime() {        // should send an e-mail out about every 10 seconds        cal.add(Calendar.SECOND, 10);        return scheduletime.format(cal.getTime());    }       @Override    public void afterDetailEval() throws JRScriptletException {        String acct = (String)this.getFieldValue("acctgroup");        String startdate = mySQLDateFormat.format(this.getParameterValue("PeriodStartDate"));        String enddate = mySQLDateFormat.format(this.getParameterValue("PeriodEndDate"));        Boolean sendemail = (Boolean) this.getParameterValue("SendEmails");        if (sendemail) {            if (acct.trim().matches("1023")) {                String schedTime = incrementTime();                System.out.println("Ran the 1023 account code: "+randVal+" - "+Math.random());                int scheduleEmail = setSchedule(acct.trim(),"/ReportToEmail",startdate,enddate,schedTime,(String)this.getFieldValue("accountemail"));                if (scheduleEmail == 200) {                    this.setVariableValue("chkAcct", "E-mail Scheduled for "+schedTime);                }                else {                    this.setVariableValue("chkAcct", "Response Error: "+scheduleEmail);                }            } else {                this.setVariableValue("chkAcct", "Not Sent");            }        }    }       public int setSchedule(String acct, String reportToSend, String StartDate, String EndDate, String sendReportTime, String emailAddress) {        // put the list of e-mail addresses in an array        List<String> emaillist = Arrays.asList(emailAddress.split("\s*,\s*"));               String data = "{"baseOutputFilename":"";        data += "Account_Statement-"+acct.trim();        data += "","outputFormats":{"outputFormat":["PDF"]},"source":{"reportUnitURI":"";        data += reportToSend;        data += "","parameters":{"parameterValues":{"AR_accountcode":["";        data += acct.trim();        data += "%"],"PeriodStartDate":["";        data += StartDate;        data += ""],"PeriodEndDate":["";        data += EndDate;        data += ""]}}},"trigger":{"simpleTrigger":{"timezone":"Pacific/Port_Moresby","occurrenceCount":1,"startType":2,"recurrenceInterval":null,"recurrenceIntervalUnit":null,"endDate":null,"startDate":"";        data += sendReportTime;        data += ""}},"outputTimeZone":"America/New_York","repositoryDestination":{"overwriteFiles":false,"sequentialFilenames":false,"folderURI":"/","saveToRepository":false,"timestampPattern":null,"outputFTPInfo":{"type":"ftp","port":21,"folderPath":null,"password":null,"propertiesMap":{},"serverName":null,"userName":null}},"mailNotification":{"toAddresses":{"address":[";        int counter = 0;        for(String elist : emaillist) {            if (counter != 0) { data += ","; }            data += """+elist+""";            counter++;        }        data += "]},"subject":"Monthly Statement","messageText":"If you are receiving this, go ahead and dance a little jig.","resultSendType":"SEND_ATTACHMENT","skipEmptyReports":true},";        data += ""alert":{"toAddresses":{"address":["myemail@test.org"]},"subject":"Failed account statement","messageText":"","messageTextWhenJobFails":"";        data += "Something went wrong with the report for account: "+acct.trim();        data += "","jobState":"FAIL_ONLY","includingReportJobInfo":true,"includingStackTrace":true},"label":"AutomaticMonthlyEmails","description":""}";               try {            Authenticator.setDefault(new Authenticator() {                @Override                protected PasswordAuthentication getPasswordAuthentication() {                  return new PasswordAuthentication("user", "password".toCharArray());                }            });                       URL url = new URL("http://mydomain.org:8080/jasperserver/rest_v2/jobs");            HttpURLConnection connection = (HttpURLConnection) url.openConnection();                       connection.setRequestMethod("PUT");            connection.setDoOutput(true);            connection.setRequestProperty("Content-Type", "application/job+json");            connection.setRequestProperty("Accept", "application/job+json");            try (OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream())) {                osw.write(data);                osw.flush();            }                       int respcode = connection.getResponseCode();            return respcode;        } catch (Exception e) {            System.err.println(e.getMessage());            return 0;        }    }}[/code]

Report JRXML:

<?xml version="1.0" encoding="UTF-8"?><!-- Created with Jaspersoft Studio version last--><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="PersonnelOverview" pageWidth="842" pageHeight="595" orientation="Landscape" columnWidth="802" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isIgnorePagination="true" uuid="56afbef4-9dfd-41f5-a016-bc8399f51f39">    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="Informix Pronto"/>    <property name="ireport.jasperserver.url" value="http://mydomain.org:8080/jasperserver/"/>    <property name="ireport.jasperserver.report.resource" value="/Business/BusinessOffice/MonthEnd/AccountEmails_files/main_jrxml"/>    <property name="ireport.jasperserver.reportUnit" value="/Business/BusinessOffice/MonthEnd/AccountEmails"/>    <scriptlet name="MonthEnd" class="mypackage.MonthEnd">        <scriptletDescription><![CDATA[]]></scriptletDescription>    </scriptlet>    <parameter name="PeriodStartDate" class="java.sql.Date"/>    <parameter name="PeriodEndDate" class="java.sql.Date"/>    <parameter name="SendEmails" class="java.lang.Boolean">        <defaultValueExpression><![CDATA[false]]></defaultValueExpression>    </parameter>    <queryString language="SQL">        <![CDATA[EXECUTE FUNCTION getMonthEndPersonnelEmails();]]>    </queryString>    <field name="acctgroup" class="java.lang.String"/>    <field name="acctname" class="java.lang.String"/>    <field name="location1" class="java.lang.String"/>    <field name="location2" class="java.lang.String"/>    <field name="location3" class="java.lang.String"/>    <field name="location4" class="java.lang.String"/>    <field name="location5" class="java.lang.String"/>    <field name="accountemail" class="java.lang.String"/>    <sortField name="location1"/>    <sortField name="location2"/>    <sortField name="location3"/>    <sortField name="location4"/>    <sortField name="location5"/>    <sortField name="acctgroup"/>    <variable name="acctgroup1" class="java.lang.Integer" resetType="Group" resetGroup="location4" calculation="Count">        <variableExpression><![CDATA[$F{acctgroup}]]></variableExpression>    </variable>    <variable name="acctgroup2" class="java.lang.Integer" resetType="Group" resetGroup="location3" calculation="Count">        <variableExpression><![CDATA[$F{acctgroup}]]></variableExpression>    </variable>    <variable name="acctgroup3" class="java.lang.Integer" resetType="Group" resetGroup="location2" calculation="Count">        <variableExpression><![CDATA[$F{acctgroup}]]></variableExpression>    </variable>    <variable name="acctgroup4" class="java.lang.Integer" calculation="Count">        <variableExpression><![CDATA[$F{acctgroup}]]></variableExpression>    </variable>    <variable name="chkAcct" class="java.lang.String" calculation="System"/>    <group name="location2">        <groupExpression><![CDATA[$F{location2}]]></groupExpression>        <groupHeader>            <band height="28">                <rectangle radius="8">                    <reportElement x="0" y="0" width="800" height="22" forecolor="#7088FF" backcolor="#7088FF" uuid="8b1bb0b4-6e18-42af-b582-b4492a42f37a">                        <property name="local_mesure_unitheight" value="pixel"/>                        <property name="com.jaspersoft.studio.unit.height" value="px"/>                    </reportElement>                </rectangle>                <textField>                    <reportElement x="10" y="0" width="780" height="22" uuid="2ee5de52-4bdc-49bb-a3e1-5a0e8afbdadb"/>                    <textElement verticalAlignment="Middle">                        <font size="14" isBold="true"/>                    </textElement>                    <textFieldExpression><![CDATA[$F{location2}]]></textFieldExpression>                </textField>            </band>        </groupHeader>    </group>    <group name="location3">        <groupExpression><![CDATA[$F{location3}]]></groupExpression>        <groupHeader>            <band height="28">                <printWhenExpression><![CDATA[$F{location3} != null]]></printWhenExpression>                <rectangle radius="8">                    <reportElement x="20" y="0" width="780" height="22" forecolor="#B3C3FF" backcolor="#B3C3FF" uuid="6e2b12f6-0b70-472e-97ee-9565b354d611"/>                </rectangle>                <textField>                    <reportElement x="30" y="0" width="760" height="22" uuid="d6ef5a3f-0eca-4b6e-8702-de0fbe6c37d8"/>                    <textElement verticalAlignment="Middle">                        <font size="12" isBold="true"/>                    </textElement>                    <textFieldExpression><![CDATA[$F{location3}]]></textFieldExpression>                </textField>            </band>        </groupHeader>    </group>    <group name="location4">        <groupExpression><![CDATA[$F{location4}.trim()+($F{location5}!=null ? " - "+$F{location5} : "")]]></groupExpression>        <groupHeader>            <band height="24">                <printWhenExpression><![CDATA[$F{location4} != null]]></printWhenExpression>                <rectangle radius="8">                    <reportElement x="40" y="0" width="760" height="20" forecolor="#E6E7FF" backcolor="#E6E7FF" uuid="b6b1bb57-ec2c-4ae2-b2e1-e516c886b8ad"/>                </rectangle>                <textField>                    <reportElement x="50" y="0" width="740" height="20" uuid="2f85f401-9b9e-4e95-8e01-94a1d4eb33f5"/>                    <textElement verticalAlignment="Middle">                        <font size="12"/>                    </textElement>                    <textFieldExpression><![CDATA[$F{location4}.trim()+($F{location5}!=null ? " - "+$F{location5} : "")]]></textFieldExpression>                </textField>            </band>        </groupHeader>    </group>    <background>        <band splitType="Stretch"/>    </background>    <title>        <band height="38" splitType="Stretch">            <staticText>                <reportElement x="0" y="0" width="800" height="30" forecolor="#7088FF" uuid="f83f847a-66a1-4682-863a-b549d7ce64a3"/>                <textElement textAlignment="Center">                    <font size="20" isBold="true"/>                </textElement>                <text><![CDATA[Month-End Emails]]></text>            </staticText>        </band>    </title>    <detail>        <band height="17" splitType="Stretch">            <textField>                <reportElement x="100" y="0" width="40" height="14" uuid="2176ceb0-09b4-4792-b933-0504fd6c51d0">                    <property name="local_mesure_unitheight" value="pixel"/>                    <property name="com.jaspersoft.studio.unit.height" value="px"/>                </reportElement>                <textFieldExpression><![CDATA[$F{acctgroup}]]></textFieldExpression>            </textField>            <textField>                <reportElement x="150" y="0" width="270" height="14" uuid="3fc04188-d9db-439a-8c46-1a47e90822cf">                    <property name="com.jaspersoft.studio.unit.height" value="px"/>                </reportElement>                <textFieldExpression><![CDATA[$F{acctname}.trim()]]></textFieldExpression>            </textField>            <textField isStretchWithOverflow="true">                <reportElement x="430" y="0" width="230" height="14" uuid="3a807127-386b-4488-9525-ce460133e8f7">                    <property name="com.jaspersoft.studio.unit.height" value="px"/>                </reportElement>                <textFieldExpression><![CDATA[$F{accountemail}]]></textFieldExpression>            </textField>            <textField isStretchWithOverflow="true" isBlankWhenNull="true">                <reportElement x="660" y="0" width="140" height="14" uuid="266b4dff-bbb6-45aa-b600-8ba21fbf0178"/>                <textFieldExpression><![CDATA[$V{chkAcct}]]></textFieldExpression>            </textField>        </band>    </detail></jasperReport>[/code]

 

Link to comment
Share on other sites

  • 2 weeks later...
  • Replies 2
  • Created
  • Last Reply

Top Posters In This Topic

  • Solution

The problem can be resolved by removing all of the

<sortField name="xxxx"/>[/code]

lines from the jrxml file.  I am assuming this is because the server reads all the data once, and then goes through it again to get the proper sorting, thus causing the afterDetailEval function to fire twice.  I believe this to be a bug.

 

Link to comment
Share on other sites

  • 4 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...