【问题标题】:Why do I get error (ClassCastException) when trying to retrive bean from my data adapter?尝试从我的数据适配器检索 bean 时,为什么会出现错误 (ClassCastException)?
【发布时间】:2017-05-18 11:58:18
【问题描述】:

我使用 JasperSoft Studio 创建了一份报告。

我引用了Jaspersoft Studio: How to use Collection of Java Beans in data adapterAlex K 的这篇有用的帖子

我想检索订单列表。 Order 类的定义如下:

public class Order {
    private double price;
    private int quantity;
    private Product product;

    // Getters & Setters
}

如果我想检索 pricequantity,报告会成功生成。但是,一旦我检索到 product,就会显示:

详情:

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

文件 sample.jrxml 是:

<?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>

JRBeanCollection 如下:

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;
        }
    // (...)
}

您能告诉我异常的原因是什么吗?

【问题讨论】:

  • Error evaluating expression for source text: $F{product}.getName() - 你有 name 字段的公共 getter 吗?看起来你正在使用我的sample :)
  • 你应该发布小 jrxml 来重现问题
  • 您好 @AlexK 先生,非常感谢您提供的出色样品,这对我帮助很大。我按照你介绍的做了,只是我在检索产品时发现了问题。是的,我有名称字段的公共吸气剂。我对我的问题进行了更改,请您看一下:我共享了文件 sample.jrxml 吗?非常感谢先生。
  • 考虑使用 BigDecimal 而不是 double。 stackoverflow.com/a/3730040/59087
  • 您好@DaveJarvis 先生,非常感谢您的回复,但我的问题不在于price,一旦我谈到price ,报告就会成功生成。 当我想检索具有nameString 类型的Product 时发现问题。

标签: java jasper-reports classcastexception jaspersoft-studio


【解决方案1】:

它看起来像 Jaspersoft Studio (JSS) 的错误。

我认为获得 ClassCastException 的原因(查看堆栈跟踪的这一部分:Caused by: java.lang.ClassCastException: ru.alex.Product cannot be cast to ru.alex.Product)是使用了两个 jar 文件:

  • 第一个 jar 是为数据提供者设置的;
  • 第二个 - 通过项目的构建路径。

是的,它是具有相同类的相同 jar 文件(物理上)。看起来像在类路径中有多个 jar 的问题。

了解问题的根源后,我们可以很容易地解决这个问题。

我们的 bean 类应该只保留一个 jar - 在 JSS 构建路径:

这意味着我们应该从数据适配器的属性中删除 jar。像这样:

之后最好重启JSS

对于这个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>

我们正在JSS成功获得报告:


Java 项目中一切正常(没有任何黑魔法),因为在类路径中我们的 bean 类只有一个 jar

【讨论】:

  • 您好 @AlexK 先生,非常感谢您的帮助和好意。你让我很开心。我很抱歉浪费你的时间。真的,我找到了另一种检索产品名称的解决方案(在 Order 类上,我使用 String 名称而不是 Product 产品,然后我对 OrderFactory 类进行了相同的更改,所以我给出了想要的结果,但是它没有优化) .在此,大大感谢先生。老实说,您是 StackOverFlow 上的佼佼者。问候。
【解决方案2】:

如果其他人正在寻找解决方案,我的设置略有不同,因此解决方案也略有不同(但根本问题相同)。

包括我的设置 -

  1. 我的主项目以及报告中需要的所有类/子类。

  2. 一个带有 bean 工厂的单独项目,用于为报告加载对象。

  3. 指向#2 中的工厂方法的数据适配器(无 jar 文件)。

  4. 在彼此的构建路径中包含项目 1 和 2。

我能够通过将工厂类/方法从项目 2 移动到项目 1 并完全删除项目 2 来修复它。我使用的是 eclipse 插件,但在我重新启动 eclipse 之前这不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多