Jasper Report not getting the correct path - java

I have a report in jasper and want to use a logo (gif) that is inside my application (inside /src/main/resources/img)
The Code used to rettrieve the image logo is
public void imprimir(MyReport myreport) throws Exception
{
List myReportList = new ArrayList();
File logo = new File(getClass().getClassLoader().getResource("img/myLogo.gif").getPath());
myreport.setLogo(logo);
myReportList.add(myreport);
FileInputStream fis = (FileInputStream) getClass().getClassLoader().getResourceAsStream("jasper/myreport.jasper");
// JasperReport report = JasperCompileManager.compileReport(fis);
JasperPrint print = JasperFillManager.fillReport(fis, null, new JRBeanCollectionDataSource(myReportList));
JasperExportManager.exportReportToPdfFile(print, "c:/myreport.pdf");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(print, baos);
DataSource datasource = new ByteArrayDataSource(baos.toByteArray(), "application/pdf");
Email mail = new Email();
mail.setFromLabel("xxxxxxxx#xxxxxxxx.yyy.zz");
mail.setTo("destiny#xxxxxxxx.yyy.zz");
mail.setSubject("myreport");
mail.setMessage("Mesage");
EmailService emailService = new EmailService();
emailService.sendEmail(mail, datasource);
}
But this path does not exists.
[Server:server01] 09:40:12,492 ERROR [stderr] (default task-3) Caused by: java.io.FileNotFoundException: C:\Java\AS\wildfly-8.1.0.Final\content\MyProject.war\WEB-INF\classes\img\logo.gif
So, as it seems, the Path is beeing resolved to a different value.
The deployment is made over a Wildfly 8.1 Final in domain mode (Clustered).
What am I missing here?

Your myLogo.gif has been package in MyProject.war file. The path C:\Java\AS\wildfly-8.1.0.Final\content\MyProject.war\WEB-INF\classes\img\logo.gif isn't exist.
I suggest two solution to resolve this issue.
1.Move myLogo.gif out of MyProject.war. Use real path to load your gif file.
File logo = new File(realPath);
myreport.setLogo(logo);
2.Change the myreport.setLogo(logo) method's parameter type to InputStream.
InputStream logoInputStream = getClass().getClassLoader().getResourceAsStream("img/myLogo.gif");
myreport.setLogoInputStream(logoInputStream);

Related

Spring Webflux: FileNotFoundException inside my JAR

I am exports PDF usgin jasper reports. In develop, it works fine. But when compile the jar, system throws and FileNotFound Exception for "src/main/resources/reports/myJasperReport.jxml"
When I explore the JAR,I came across that the URL for the report is "/BOOT-INF/classes/resports/myJasperReport.jxml"
I found this link to File inside jar is not visible but didn't solve my problem.
Could you help me please?
#Slf4j
#Service
public class ReportService {
private static final String REPORTS_BASE_PATH = "src/main/resources/reports/";
public ByteArrayInputStream exportReport(
String reportFileName,
Integer idCC,
Map<String,Object> parameters
) throws Exception {
Connection connection = CustomEntityManagerFactoryPostgresImpl
.getInstance()
.getConnection(idCC);
File file = ResourceUtils.getFile(REPORTS_BASE_PATH + reportFileName);
JasperReport jasperReport = JasperCompileManager.compileReport(file.getAbsolutePath());
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
return new ByteArrayInputStream(outputStream.toByteArray());
}
}
Add classpath: prefix to your path. And consider the resources folder to be a root.
ResourceUtils.getFile("classpath:reports/" + reportFileName);
UPD:
Actually, you don't need to get a file at all. Try to get resource as stream:
InputStream report = ReportService.class.getClassLoader().getResourceAsStream("reports/" + reportFileName);
JasperReport jasperReport = JasperCompileManager.compileReport(report);

Java Mail API - Datasource from FileInputStream

Am integrating JavaMailAPI in my webapplication. I have to embed images in the html body. How do i get the images from the src/main/resource directory instead of hard code the image path.
Please find the below code that i have hard coded the image path.
try {
messageBodyPart = new MimeBodyPart();
DataSource fds = new FileDataSource("C:\\email\\logo_email.png");
messageBodyPart.setDataHandler(new DataHandler(fds));
messageBodyPart.setHeader("Content-ID","<image>");
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
Transport.send(message);
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
I want to get the images from the following code : ( src/main/resource )
ClassLoader classLoader = getClass().getClassLoader();
FileInputStream fileinputstream = new FileInputStream(new
File(classLoader.getResource("email/logo_email.png").getFile()));
I dont have idea to call fileinputstream inside DataSource
Do not use URL.getFile() as it returns the filename part of the URL...
Use URLDataSource instead of FileDataSource. Try something like this:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("email/logo_email.png");
DataSource ds = new URLDataSource(url);
Edit
In Web applications getClass().getClassLoader() might not get the correct class loader. Should use the Thread's context class loader...

How to serve .jasper file with HTTP Server?

I am creating HTTP server with Tomee, i am placed jasper report file (.jasper) in webapp directory. if i access http://localhost:8080/test.jasper in browser, the browser will prompt to download the file.
In my java project i'm creating simple code to access that link and then preview the report. I use async-http-client library for request.
DefaultAsyncHttpClient client = new DefaultAsyncHttpClient();
BoundRequestBuilder brb = client.prepareGet("http://localhost:8765/qa/test.jasper");
Future<InputStream> f = brb.execute(new AsyncCompletionHandler<InputStream>() {
#Override
public InputStream onCompleted(Response resp) {
try {
String[][] data = {{"Jakarta"},{"Surabaya"},{"Solo"},{"Denpasar"}};
String[] columnNames = {"City"};
DefaultTableModel dtm = new DefaultTableModel(data, columnNames);
Map<String,Object> params = new HashMap<>();
JasperPrint jPrint = JasperFillManager.fillReport(
resp.getResponseBodyAsStream(),
params,
new JRTableModelDataSource(dtm)
);
JasperViewer jpView = new JasperViewer(jPrint,false);
jpView.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jpView.setSize(800, 600);
jpView.setLocationRelativeTo(null);
jpView.setVisible(true);
} catch (JRException ex) {
System.out.println(ex.getMessage());
}
return resp.getResponseBodyAsStream();
}
});
From my code above, i got an error Error loading object from InputStream
normally i can use
InputStream input = MainContext.class.getResourceAsStream(filename);
But i want to replace file input stream with http request (stream too).
How exactly i can serve .jasper file with http server...?
Error loading object from InputStream error came from corrupt InputStream, if i download .jasper file normally via browser and execute the report with JRLoader.loadObjectFromFile(path to file) it doesn't works too, because tomee give corrupt file (the source file not corrupt).
My own solution is read source file as stream, convert it to base64 encode, and serve it via HTTP API protocol.
finput = new FileInputStream(sPath);
byte[] bFile = Base64.getEncoder().encode(IOUtils.toByteArray(finput));
String sFile = new String(bFile);
inside client side, i received it as body string, decode the base64 string, convert it to InputStream and Finally execute the report with InputStream.
byte[] bBody = Base64.getDecoder().decode(sBody);
InputStream mainReport = new ByteArrayInputStream(bBody);
return JasperFillManager.fillReport(mainReport, params);

I can not choose where to save the generated report in Jasper

I have a problem when I click to generate a report ... I would like the moment I clicked the button to generate the report to be shown a window asking where I want to save the document, the way it is now I'm in java code specifying the location and file name, and always the file is saved in the specified place in the code, I do not want it, I need to leave it open for the person to choose where to save ... down goes a piece of code I am using.
.
try {
URL arquivo = getClass().getResource(/reports/term.jasper);
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(arquivo);
//It generates the dto that will be sent to IReport
ArrayList<MinutoTRDto> dataList = getDataBeanList(licitacao);
JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource(dataList);
Map<String, Object> parameters = getParametros();
JasperPrint print = JasperFillManager.fillReport(jasperReport, parameters, beanColDataSource);
JROdtExporter exporterOdt = new JROdtExporter();
exporterOdt.setExporterInput(new SimpleExporterInput(print));
// HERE IS THE PROBLEM!
exporterOdt.setExporterOutput(new SimpleOutputStreamExporterOutput("C://teste//sample_report.odt"));
exporterOdt.exportReport();
} catch (JRException jre) {
jre.printStackTrace();
}
You will have to write the following in your code
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename=<your file name>");
With this, the 'file download' dialog will appear. You can refer here for the complete code.
Following the AMDG replied, I changed my file to the following code, only it was launched the following exception:
org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
I using Wicket from framework
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
URL arquivo = getClass().getResource(REPORT_PATH);
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(arquivo);
ArrayList<MinutoTRDto> dataList = getDataBeanList(licitacao);
JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource(dataList);
Map<String, Object> parameters = getParametros();
print = JasperFillManager.fillReport(jasperReport, parameters, beanColDataSource);
JROdtExporter exporterOdt = new JROdtExporter();
exporterOdt.setExporterInput(new SimpleExporterInput(print));
exporterOdt.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream));
exporterOdt.exportReport();
byte[] bytes = outputStream.toByteArray();
if (bytes != null && bytes.length > 0) {
HttpServletResponse response =(HttpServletResponse)((WebResponse)comp.getResponse()).getContainerResponse();
response.setContentType("application/odt");
response.setHeader("Content-disposition", "inline; filename=\"file_generated.odt\"");
response.setContentLength(bytes.length);
ServletOutputStream outputStream2 = response.getOutputStream();
outputStream2.write(bytes, 0, bytes.length);
outputStream2.flush();
outputStream2.close();
}
} catch (Exception e) {
e.printStackTrace();
}

Getting error when I attach an image to Classpath Resource in scheduler jobclass

protected void executeInternal(JobExecutionContext context) throws JobExecutionException
{
System.out.println("Sending Birthday Wishes... ");
try
{
for(int i=0;i<maillist.length;i++)
{
Email email = new Email();
email.setFrom("spv_it#yahoo.com");
email.setSubject("Happy IndependenceDay");
email.setTo(maillist[i]);
email.setText("<font color=blue><h4>Dear Users,<br><br><br>Wish you a Happy Independence Day!<br><br><br>Regards,<br>Penna Cement Industries Limited</h4></font>");
byte[] data = null;
ClassPathResource img = new ClassPathResource("newLogo.gif");
InputStream inputStream = img.getInputStream();
data = new byte[inputStream.available()];
while((inputStream.read(data)!=-1));
Attachment attachment = new Attachment(data, "HappyBirthDay","image/gif", true);
email.addAttachment(attachment);
emailService.sendEmail(email);
}
}
catch (MessagingException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
This is the error I'm getting:
java.io.FileNotFoundException: class path resource [newLogo.gif] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:135)
at com.mail.schedular.BirthdayWisherJob.executeInternal(BirthdayWisherJob.java:55)
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:66)
at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549)
The best practise is to read/write or to provide reference of any file is by mentioning the ABSOLUTE PATH of that file.
To your question, It shows the FileNotFoundException because, JVM failed to locate the file in your current directory which is by default your source path. So provide the absolute path in ClassPathResource or copy that image file to your current directory. It will solve your problem.
I think you need to put your file inside inside the src folder , if it's there then check whether it's under some directory which is inside the src directory.
Then give the correct location like given details below
src[dir]----->newLogo.gif
ClassPathResource img = new ClassPathResource("newLogo.gif");
or,
src[dir]----->images[dir]---->newLogo.gif
ClassPathResource img = new ClassPathResource("/images/newLogo.gif");
You got this error since the job is running in a separate quartz thread, I suggest that you locate your file newLogo.gif outside the jar and use the following to load it.
Thread.currentThread().getContextClassLoader().getResource("classpath:image/newLogo.gif");

Categories