【发布时间】:2018-10-16 15:14:21
【问题描述】:
我正在使用一个 Java 应用程序,它允许您添加用 Java 编写的扩展。我希望在扩展中运行 JasperReports 查看器。作为测试,我有这个代码:
package com.moneydance.modules.features.jasperreports;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.swing.JRViewer;
public class MyJasperReport extends JFrame{
JasperReport report;
public MyJasperReport(Main main) throws JRException, IOException{
String sourceFileName = "c://users/miker/workspace/JasperReports-6.7.0/test" +
"/jasper_report_template.jasper";
Map<String,Object> parameters = new HashMap<>();
JasperReport report =(JasperReport)JRLoader.loadObjectFromFile(sourceFileName);
JRDataSource dataSource = new JREmptyDataSource();
JasperPrint jasperPrint = null;
JRViewer viewer = null;
try {
jasperPrint = JasperFillManager.fillReport(report, parameters,dataSource);
}
catch (JRException e) {
e.printStackTrace();
}
if (jasperPrint != null) {
viewer = new JRViewer(jasperPrint);
if (viewer !=null) {
getContentPane().add(viewer);
}
}
}
}
这行失败,出现空指针异常:
btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/sf/jasperreports/view/images/save.GIF")));
在 JRViewerToolBar 类中
如果我通过 Eclipse 在调试中运行它,它就可以工作。如果我在代码中包含 JRViewer 和 JRViewerToolBar 类并更改代码以使用以下 sn-p:
public Image getIcon(String action) {
try {
loader = getClass().getClassLoader();
java.io.InputStream in =
loader.getResourceAsStream(action);
if (in != null) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
byte buf[] = new byte[256];
int n = 0;
while((n=in.read(buf, 0, buf.length))>=0)
bout.write(buf, 0, n);
return Toolkit.getDefaultToolkit().createImage(bout.toByteArray());
}
} catch (Throwable e) { }
return null;
}
如果操作是“/net/sf/jasperreports/view/images/save.GIF”,它也可以工作。
这显然是确定资源路径的问题。我怀疑我正在使用的应用程序使用它自己的类加载器来加载我的扩展。
问题是:有没有一种方法可以加载 JasperReports 类,以便它们表现自己?或者,我所能看到的只是在我的扩展程序中有一个修改版本的 JasperReports,这将引入错误并成为维护的噩梦。
编辑
这不是文件解析器问题的重复。这是关于用于从应用程序中加载 Jasper 类的类加载器。
【问题讨论】:
-
您强制类加载器或资源加载问题的能力主要取决于您正在扩展的应用程序。您必须向我们提供一些详细信息才能继续,因为正如您所指出的,到目前为止您在扩展代码中所做的一切都很好。
-
我发现应用程序 (Moneydance) 覆盖了 getResourceAsStream。如果我创建一个自定义类加载器,覆盖 GetResource 并使用它来加载 JasperReports jasper 代码将使用我的类还是默认类?
-
这与我之前发布的问题有关。我应该建立联系的。 PaulProgrammer 我对你关于类加载器的回答很感兴趣。
-
您可能很难将自定义类加载器作为插件注入应用程序。我会花一些时间阅读应用程序文档,以了解它的插件类加载器(以及
getResourceAsStream()方法)的不同之处以及如何在问题的上下文中使用它。 -
我似乎无法为此添加答案。它被错误地声明为重复。问题是 Moneydance 的 CLASS-PATH(正在扩展的应用程序)。该路径包含 Moneydance 的 jar 和扩展本身,因为 ClassLoader 已扩展。方法 getResourceAsStream 已被覆盖,但方法 getResource 没有,因此 getResource 找不到 Jasper 资源。我想出的解决方案是加载一个包含 JasperReports 代码的可执行 jar(使用 Spring Boot)并在该 jar 中构建一个接口。
标签: java jasper-reports