Joe Taras
Joe Taras

Reputation: 15379

Getting error in case using JRImageLoader.loadAwtImageFromBytes method for loading image

I'm using JasperSoft Studio 6.8.0 and I've a struggling error:

I've a logo property of my Java class EnvParameter.

this property is a byte[]

I pass my Java class to Jasper Studio, so I try to load the image inside logo property as follow:

net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes($P{EnvParameter}.logo)

EDIT

I've also tried with

net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes($P{EnvParameter}.getLogo())

But I have this error at runtime (compile it's OK):

net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression for source text: net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes($P{EnvParameter}.logo) at net.sf.jasperreports.engine.fill.JREvaluator.handleEvaluationException(JREvaluator.java:284) at net.sf.jasperreports.compilers.GroovyEvaluator.handleEvaluationException(GroovyEvaluator.java:98) at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:316) at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:672) at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:640) at net.sf.jasperreports.engine.fill.JRFillElement.evaluateExpression(JRFillElement.java:1169) at net.sf.jasperreports.engine.fill.JRFillImage.evaluateImage(JRFillImage.java:466) at net.sf.jasperreports.engine.fill.JRFillImage.evaluate(JRFillImage.java:440) at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:383) at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:548) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillTitle(JRVerticalFiller.java:323) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:150) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:615) at net.sf.jasperreports.engine.fill.BaseReportFiller.fill(BaseReportFiller.java:414) at net.sf.jasperreports.engine.fill.JRFillSubreport.fillSubreport(JRFillSubreport.java:814) at net.sf.jasperreports.engine.fill.JRSubreportRunnable.run(JRSubreportRunnable.java:61) at net.sf.jasperreports.engine.fill.AbstractThreadSubreportRunner.run(AbstractThreadSubreportRunner.java:221) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: groovy.lang.MissingMethodException: No signature of method: static net.sf.jasperreports.engine.util.JRImageLoader.loadAwtImageFromBytes() is applicable for argument types: ([B) values: [[-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, ...]] Possible solutions: loadAwtImageFromBytes([B) at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1518) at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1504) at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:52) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128) at rptVTitolo_1558437271760_434544.evaluate(calculator_rptVTitolo_1558437271760_434544:203) at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:302) ... 17 common frames omitted mag 21, 2019 1:17:36 PM org.apache.catalina.core.StandardWrapperValve invoke

Upvotes: 1

Views: 1170

Answers (1)

Alex K
Alex K

Reputation: 22857

What is wrong?

Looks like you are using wrong method for loading image. The class JRImageLoader was changed during moving to 6.x version of engine and there is no static method loadAwtImageFromBytes(bytep[]) at this class at new versions of JasperReports (I believe that it was there at JR 5.5.0).

Working example

You can try this small example.

Small Bean for testing:

package ru.alex.model;

public class MyBean {

    private byte[] logo;

    public byte[] getLogo() {
        return logo;
    }

    public void setLogo(byte[] logo) {
        this.logo = logo;
    }
}

The template (jrxml file) is very simple (I'm using JasperReports 6.4):

<?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="ImageExample" pageWidth="612" pageHeight="792" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
    <parameter name="mybean" class="ru.alex.model.MyBean" isForPrompting="false"/>
    <title>
        <band height="72">
            <image>
                <reportElement x="200" y="10" width="50" height="50"/>
                <imageExpression><![CDATA[net.sf.jasperreports.engine.util.JRImageLoader.getInstance(DefaultJasperReportsContext.getInstance()).loadAwtImageFromBytes($P{mybean}.getLogo())]]></imageExpression>
            </image>
        </band>
    </title>
</jasperReport>

I used JRImageLoader.loadAwtImageFromBytes(byte[]) method for loading image from bytes array. As you can see we need to get instance of JRImageLoader first - I used default context using this code: JRImageLoader.getInstance(DefaultJasperReportsContext.getInstance()).

The code for generating report is simple as usual:

JasperReport jasperReport;
try (InputStream inputStream = JRLoader.getResourceInputStream("image.jrxml")) {
    jasperReport = JasperCompileManager.compileReport(JRXmlLoader.load(inputStream));
}
Map<String, Object> params = new HashMap<>();
MyBean myBean = new MyBean();

File file = new File(getClass().getClassLoader().getResource("smile.jpg").getFile());
myBean.setLogo(Files.readAllBytes(file.toPath()));

params.put("mybean", myBean);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource());

SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
File outputFile = new File("output.pdf");
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
     OutputStream fileOutputStream = new FileOutputStream(outputFile)) {
    JRPdfExporter exporter = new JRPdfExporter();
    exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
    exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(byteArrayOutputStream));
    exporter.setConfiguration(configuration);
    exporter.exportReport();
    byteArrayOutputStream.writeTo(fileOutputStream);
}

The generated report looks like:

enter image description here

Upvotes: 2

Related Questions