Try this steps for testing master report and subreport in iReport:
- Create Connection in iReport and test it. Don't forget to add jar file (jdbc driver) to the application (iReport in this test case) classpath.
- Create master report with query. Test it with iReport connection.
- Create subreport with query. Test it with iReport connection.
- Add Subreport component to the master report.
- Set subreport's subreportExpression and subreportParameterExpression expressions in master report.
- Create parameter of
java.sql.Connection
type in master report. Set defaultValueExpression for it. Use this parameter in the subreport's connectionExpression expression of master report.
- Compile subreport and master report.
- Test master report via Preview button in iReport.
The snippet of master report:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ...>
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA["<some_path>"]]></defaultValueExpression>
</parameter>
<parameter name="connectionParam" class="java.sql.Connection" isForPrompting="false">
<defaultValueExpression><![CDATA[java.sql.DriverManager.getConnection("jdbc:oracle:thin:@//<server_name>:<server_port>/<SID_name>", "<user>", "<password>")]]></defaultValueExpression>
</parameter>
<queryString>
<![CDATA[SELECT id, name FROM main_table]]>
</queryString>
<field name="ID" class="java.lang.String"/>
<field name="NAME" class="java.lang.String"/>
<title>
<band height="79" splitType="Stretch"/>
</title>
<detail>
<band height="125" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{ID}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="0" y="20" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{NAME}]]></textFieldExpression>
</textField>
<subreport>
<reportElement x="259" y="25" width="200" height="100"/>
<subreportParameter name="masterId">
<subreportParameterExpression><![CDATA[$F{ID}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{connectionParam}]]></connectionExpression>
<subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "several_connections_subreport1.jasper"]]></subreportExpression>
</subreport>
</band>
</detail>
</jasperReport>
The snippet of subreport:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ...>
<parameter name="masterId" class="java.lang.String"/>
<queryString>
<![CDATA[SELECT details, id FROM details_table where masterId =$P{masterId}]]>
</queryString>
<field name="DETAILS" class="java.lang.String"/>
<field name="ID" class="java.lang.String"/>
<title>
<band height="50">
<textField>
<reportElement x="176" y="20" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$P{masterId}]]></textFieldExpression>
</textField>
</band>
</title>
<detail>
<band height="125" splitType="Stretch">
<textField>
<reportElement x="57" y="17" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{DETAILS}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
I tried to replace the jtd compiler that used by iReport with new version of jtd compiler (used by JasperReports 6.3).
The last version of iReport is 5.6.0 and it is using JasperReports 5.6.0 behind the scene.
The JasperReports 5.6 is using the jdt 3.1, you can find this dependency at pom.xml:
<dependency>
<groupId>eclipse</groupId>
<artifactId>jdtcore</artifactId>
<version>3.1.0</version>
<scope>compile</scope>
</dependency>
It means that JasperReports API is using the old version jdt that has not support for Java 8.
For example, the net.sf.jasperreports.engine.design.JRJdtCompiler class is using the jdt core. It means that changes of jdt API can break the compiling mechanism.
Despite these facts I continued my experiment and replace the jdt with new version: 4.3.1 (this version is used by JasperReports 6.3). This version allow us to use Java 8 syntax at templates.
I also set properties at iReport:
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.source=1.8
But I got the error (as expected) during compiling the template (jrxml) via iReport:
java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.CompilationResult.getErrors()[Lorg/eclipse/jdt/core/compiler/IProblem;
at com.jaspersoft.ireport.designer.compiler.ExtendedJRJdtCompiler$CompilerRequestor.acceptResult(ExtendedJRJdtCompiler.java:96)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:480)
at net.sf.jasperreports.engine.design.JRJdtCompiler.compileUnits(JRJdtCompiler.java:167)
at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:201)
at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:512)
It means that my attempt failed, because the jdt API was changed in new version. But JasperReports API is still using "old" methods instead of methods from new jdt.jar.
Solutions as I see:
- To stop using unsupported IDE and replace it with Jaspersoft Studio
- Don't use compiling at IDE (iReport) and try to compile/test reports with Java code.
More information:
Use lambda expressions inside TextField expression in Jaspersoft Studio 6.3
How to use lambda expression in jrxml file?
Best Answer
here is the solution
how to use divide() method in jasper reports?
And note to check for nullity by assigning the initial value to 0.
${total_answer}.divide( ${total_max_score} )
and you can do the same for multiplication using
.multiply()