Skip to content

Commit

Permalink
Bug fix for Java 11: prevent exception while loading resources
Browse files Browse the repository at this point in the history
  • Loading branch information
jlolling committed Nov 25, 2020
1 parent 3a9a2de commit f26afce
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 19 deletions.
13 changes: 4 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.jlo.talendcomp</groupId>
<artifactId>jlo-talendcomp-jasperreportexec</artifactId>
<version>6.1</version>
<organization>
<name>Jan Lolling</name>
<url>http://jan-lolling.de</url>
Expand All @@ -23,7 +24,7 @@
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.15.0</version>
<version>6.16.0</version>
<exclusions>
<exclusion>
<artifactId>stax-api</artifactId>
Expand Down Expand Up @@ -118,12 +119,12 @@
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-functions</artifactId>
<version>6.15.0</version>
<version>6.16.0</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-fonts</artifactId>
<version>6.15.0</version>
<version>6.16.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down Expand Up @@ -199,11 +200,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
Expand Down Expand Up @@ -240,5 +236,4 @@
</plugin>
</plugins>
</build>
<version>6.0</version>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,13 @@ public class JasperReportExecuter {
private boolean printJRParameters = false;
private boolean replaceJrxmlRef = true;
private static final Object lock = new Object();
private static ReportResourceClassLoader resourceClassLoader;
private ReportResourceClassLoader resourceClassLoader;

public JasperReportExecuter() {
synchronized(lock) {
if (resourceClassLoader == null) {
resourceClassLoader = new ReportResourceClassLoader(new URL[0], this.getClass().getClassLoader());
Thread.currentThread().setContextClassLoader(resourceClassLoader);
}
}
}
Expand Down Expand Up @@ -442,7 +443,7 @@ private void compileReport(String jrxmlFilePath, boolean isMainReport) throws Ex
if (isMainReport && jasperReport.getQuery() != null) {
queryString = jasperReport.getQuery().getText();
}
if (jasperReport.getSectionType().equals(SectionTypeEnum.BAND)) {
if (SectionTypeEnum.BAND.equals(jasperReport.getSectionType())) {
// this is a normal report
// traverse through the report and gather the sub reports to compile them
JRElementsVisitor.visitReport(jasperReport, new JRVisitor() {
Expand Down
300 changes: 300 additions & 0 deletions src/main/java/net/sf/jasperreports/repo/RepositoryUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
* http://www.jaspersoft.com
*
* Unless you have purchased a commercial license agreement from Jaspersoft,
* the following license terms apply:
*
* This program is part of JasperReports.
*
* JasperReports is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JasperReports is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.jasperreports.repo;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.ReportContext;


/**
* @author Teodor Danciu (teodord@users.sourceforge.net)
*/
public final class RepositoryUtil
{
public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR = "repo.byte.data.loading.error";
public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_NOT_FOUND = "repo.byte.data.not.found";
public static final String EXCEPTION_MESSAGE_KEY_INPUT_STREAM_NOT_FOUND = "repo.input.stream.not.found";
public static final String EXCEPTION_MESSAGE_KEY_REPORT_NOT_FOUND = "repo.report.not.found";
public static final String EXCEPTION_MESSAGE_KEY_RESOURCET_NOT_FOUND = "repo.resource.not.found";

private AtomicReference<List<RepositoryService>> repositoryServices = new AtomicReference<List<RepositoryService>>();


private RepositoryContext context;


/**
*
*/
private RepositoryUtil(RepositoryContext context)//FIXMECONTEXT try to reuse utils as much as you can
{
this.context = context;
}


/**
*
*/
public static RepositoryUtil getInstance(JasperReportsContext jasperReportsContext)
{
return getInstance(SimpleRepositoryContext.of(jasperReportsContext));
}

public static RepositoryUtil getInstance(RepositoryContext repositoryContext)
{
return new RepositoryUtil(repositoryContext);
}


/**
*
*/
private List<RepositoryService> getServices()
{
List<RepositoryService> cachedServices = repositoryServices.get();
if (cachedServices != null)
{
return cachedServices;
}

List<RepositoryService> services = context.getJasperReportsContext().getExtensions(RepositoryService.class);

// set if not already set
if (repositoryServices.compareAndSet(null, services))
{
return services;
}

// already set in the meantime by another thread
return repositoryServices.get();
}


/**
*
*/
public JasperReport getReport(ReportContext reportContext, String location) throws JRException
{
JasperReport jasperReport = null;

JasperDesignCache cache = JasperDesignCache.getInstance(context.getJasperReportsContext(), reportContext);
if (cache != null)
{
jasperReport = cache.getJasperReport(location);
}

if (jasperReport == null)
{
ReportResource resource = null;
// Try to find out which resource fails to load
try {
resource = getResourceFromLocation(location, ReportResource.class);
} catch (Throwable t) {
throw new JRException("Loading resource from location: " + location + " failed: " + t.getMessage(), t);
}
if (resource == null)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_REPORT_NOT_FOUND,
new Object[]{location});
}

jasperReport = resource.getReport();

if (cache != null)
{
cache.set(location, jasperReport);
}
}

return jasperReport;
}


/**
*
*/
public <K extends Resource> K getResourceFromLocation(String location, Class<K> resourceType) throws JRException
{
K resource = null;
List<RepositoryService> services = getServices();
if (services != null)
{
for (RepositoryService service : services)
{
resource = service.getResource(context, location, resourceType);
if (resource != null)
{
break;
}
}
}
if (resource == null)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_RESOURCET_NOT_FOUND,
new Object[]{location}); //FIXMEREPO decide whether to return null or throw exception; check everywhere
}
return resource;
}


/**
*
*/
public InputStream getInputStreamFromLocation(String location) throws JRException
{
InputStream is = findInputStream(location);
if (is == null)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_INPUT_STREAM_NOT_FOUND,
new Object[]{location});
}
return is;
}


/**
*
*/
private InputStream findInputStream(String location) throws JRException
{
InputStreamResource inputStreamResource = null;
List<RepositoryService> services = getServices();
if (services != null)
{
for (RepositoryService service : services)
{
inputStreamResource = service.getResource(context, location, InputStreamResource.class);
if (inputStreamResource != null)
{
break;
}
}
}
return inputStreamResource == null ? null : inputStreamResource.getInputStream();
}


/**
*
*/
public byte[] getBytesFromLocation(String location) throws JRException
{
InputStream is = findInputStream(location);

if (is == null)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_BYTE_DATA_NOT_FOUND,
new Object[]{location});
}

ByteArrayOutputStream baos = null;

try
{
baos = new ByteArrayOutputStream();

byte[] bytes = new byte[10000];
int ln = 0;
while ((ln = is.read(bytes)) > 0)
{
baos.write(bytes, 0, ln);
}

baos.flush();
}
catch (IOException e)
{
throw
new JRException(
EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR,
new Object[]{location},
e);
}
finally
{
if (baos != null)
{
try
{
baos.close();
}
catch(IOException e)
{
}
}

if (is != null)
{
try
{
is.close();
}
catch(IOException e)
{
}
}
}

return baos.toByteArray();
}

public ResourceInfo getResourceInfo(String location)
{
ResourceInfo resourceInfo = null;
List<RepositoryService> services = getServices();
if (services != null)
{
for (RepositoryService service : services)
{
resourceInfo = service.getResourceInfo(context, location);
if (resourceInfo != null)
{
break;
}
}
}
return resourceInfo;
}

public RepositoryContext getRepositoryContext()
{
return context;
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit f26afce

Please sign in to comment.