eoinDub eoinDub - 5 months ago 53
Java Question

How to set relative path of images in report?

So I have a java application that displays a jasper report. There is an image I placed in the report using the iReport plugin for netbeans. Everything displays fine on my current machine but when I try to run the compiled jar on a different machine, the report won't load.

From looking at the windows console, I think it's because the path to the image is absolute, i.e. referencing a specific folder on the hard drive of the development machine. I need to make it relative to the jar file. I've placed the image into the package and have confirmed it's inside the compiled jar. But when I change the "image expression" value in iReport to "/reports/Logo.jpg" (where /reports is the package) and run the app I get

EXCEPTION: Byte data not found at : /reports/Logo.jpgnet.sf.jasperreports.engine.JRException: Byte data not found at : reports/Logo.jpg


Any ideas what to do? I am very stuck and would appreciate any help!

UPDATE: Got it. Had to create a parameter in the report and called the parameter from the image expression. Then I created a HashMap and InputStream in the Java code and placed the input stream into the hash map! So much code for so simple a thing!

Java code:

//to get images to display in report, pass their relative path as input stream and add to HashMap
//there must be one stream and one HashMap per image
InputStream imgInputStream = this.getClass().getResourceAsStream("/reports/omacLogo.jpg");
InputStream imgInputStream2 = this.getClass().getResourceAsStream("/reports/omacLogo.jpg");
parameters.put("omacLogo", imgInputStream);
parameters2.put("omacLogo", imgInputStream2);

InputStream jasper1 = this.getClass().getResourceAsStream("/reports/OmacYTDReportFinalpg1.jasper");
InputStream jasper2 = this.getClass().getResourceAsStream("/reports/OmacYTDReportFinalpg2.jasper");

JasperPrint jp1 = JasperFillManager.fillReport(jasper1, parameters,new JRBeanCollectionDataSource(ie.orderofmalta.BeanFactory.getCalcs()));
JasperPrint jp2 = JasperFillManager.fillReport(jasper2, parameters2, new JRBeanCollectionDataSource(ie.orderofmalta.BeanFactory.getCalcs()));


Hope this helps someone else! Be aware you have to create separate hash maps and input streams for each image you want to place, even if it's the same image.

Answer

I've personally had not tried this way with a jar, but i hope it helps. As you've stated the problem comes from the file path. On the iReport tool you can use relative paths and it works on the preview, but when the report generation is integrated within an application, it can only work with absolute paths.
The way i've dealt with this drawback was by getting the absolute path of the image inside the java application, and passing it as a parameter to the report. Example:

 String image = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/Cards_Template/front.jpg");

NOTE: I've built a JSF app, that's why i'm getting the path from it's context. If you don't, Java's IO or NIO API does have some methods to do the same. Basically, i get an absolute path from a relative path.