I created a report using JasperSoft Studio.
I'm referencing to this helpful post Jaspersoft Studio: How to use Collection of Java Beans in data adapter by Alex K
I'd like to retrieve a list of orders. The class Order is defined as in the post:
public class Order {
private double price;
private int quantity;
private Product product;
// Getters & Setters
}
The report is generated with success if I'd like to retrieve price or quantity. But, once I retrieve product this is displayed:
Details:
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression for source text: $F{product}.getName()
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.fillReport(ReportControler.java:530)
at com.jaspersoft.studio.editor.preview.view.control.ReportControler.access$20(ReportControler.java:505)
...
Caused by: java.lang.ClassCastException: ru.alex.Product cannot be cast to ru.alex.Product
at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:277)
... 14 more
The file sample.jrxml was:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.3.1.final using JasperReports Library version 6.3.1 -->
<!-- 2017-05-18T13:29:14 -->
<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="sample" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="ade9e357-e2d0-42bb-ae0d-000b69f4e2e9">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="JavaBeanCollection - orders"/>
<queryString>
<![CDATA[]]>
</queryString>
<field name="product" class="ru.alex.Product">
<fieldDescription><![CDATA[product]]></fieldDescription>
</field>
<field name="quantity" class="java.lang.Integer">
<fieldDescription><![CDATA[quantity]]></fieldDescription>
</field>
<field name="price" class="java.lang.Double">
<fieldDescription><![CDATA[price]]></fieldDescription>
</field>
<title>
<band height="80" splitType="Stretch">
<staticText>
<reportElement x="70" y="49" width="100" height="30" uuid="a19f5b7c-21ed-4c00-a224-af5cf7ef27ec"/>
<text><![CDATA[price]]></text>
</staticText>
<staticText>
<reportElement x="170" y="49" width="100" height="30" uuid="772c4807-25f7-4e7a-8a10-eba5232b92c7"/>
<text><![CDATA[quantity]]></text>
</staticText>
<staticText>
<reportElement x="270" y="49" width="140" height="30" uuid="613da9ef-6a5a-45b2-8c8f-c3cd450e66ed"/>
<text><![CDATA[product]]></text>
</staticText>
</band>
</title>
<detail>
<band height="130" splitType="Stretch">
<textField>
<reportElement x="70" y="0" width="100" height="30" uuid="a594224b-c015-4dab-b52b-6e317e76cea3"/>
<textFieldExpression><![CDATA[$F{price}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="170" y="0" width="100" height="30" uuid="b60503ca-f6bc-48dc-ad01-178d9befd805"/>
<textFieldExpression><![CDATA[$F{quantity}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="270" y="0" width="140" height="30" uuid="480bfb2f-2831-4700-8adc-f818bbbf6592"/>
<textFieldExpression><![CDATA[$F{product}.getName()]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
The JRBeanCollection is the following:
public class MyImplementation implements JRDataSource {
// (...)
public static Collection<Order> getOrders() {
List<Order> orders = new ArrayList<Order>();
orders.add(new Order(1, "aa", new BigDecimal("1111.11"), 2, new Product("apples")));
orders.add(new Order(2, "bb", new BigDecimal("2222.22"), 10, new Product("oranges")));
return orders;
}
// (...)
}
Could you please tell me what is the reason for the exception?
It looks like a bug of Jaspersoft Studio (JSS).
I think that the reason of getting ClassCastException (look at this part of stacktrace: Caused by: java.lang.ClassCastException: ru.alex.Product cannot be cast to ru.alex.Product
) is using of two jar files:
Yes, it is the same jar file (physically) with the same classes. Looks like the issue of having multiple jar at classpath.
After understanding the root of the problem we can fix this issue very easy.
We should stay only one jar with our bean classes - at JSS build path:
It means that we should remove the jar from data adapter's properties. Like this:
After this it is better to restart JSS.
For this jrxml:
<?xml version="1.0" encoding="UTF-8"?>
<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="Report with Bean" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="JavaBeanCollection - orders"/>
<field name="product" class="ru.alex.Product">
<fieldDescription><![CDATA[product]]></fieldDescription>
</field>
<field name="quantity" class="java.lang.Integer">
<fieldDescription><![CDATA[quantity]]></fieldDescription>
</field>
<field name="price" class="java.lang.Double">
<fieldDescription><![CDATA[price]]></fieldDescription>
</field>
<detail>
<band height="30" splitType="Stretch">
<textField>
<reportElement x="10" y="0" width="100" height="30"/>
<textFieldExpression><![CDATA[$F{quantity}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="110" y="0" width="100" height="30"/>
<textFieldExpression><![CDATA[$F{price}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="210" y="0" width="100" height="30"/>
<textFieldExpression><![CDATA[$F{product}.getName()]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
we are getting report at JSS successfully:
Everything working fine (without any black magic) at Java project, because we have only single jar with our bean classes at classpath.