简体   繁体   English

Jasper Reports作为Java应用程序的一部分

[英]Jasper Reports as part of Java aplication

I am using a Java application that allows you to add extensions written in Java. 我使用的Java应用程序允许您添加用Java编写的扩展。 I wish to run a JasperReports viewer within an extension. 我希望在扩展中运行JasperReports查看器。 As a test I have this code: 作为测试,我有以下代码:

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);
        }
    }
}

}

This fails with a null pointer exception on the line: 这将失败,并在行上出现空指针异常:

        btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/net/sf/jasperreports/view/images/save.GIF")));

within the class JRViewerToolBar 在类JRViewerToolBar中

If I run this in debug through Eclipse it works. 如果我通过Eclipse在调试中运行它,那么它将起作用。 If I include the JRViewer and JRViewerToolBar classes in my code and change the code to use the following snippet: 如果我在代码中包括JRViewer和JRViewerToolBar类,并更改代码以使用以下代码段:

    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;
}

where action is "/net/sf/jasperreports/view/images/save.GIF" it also works. 如果动作是“ /net/sf/jasperreports/view/images/save.GIF”,它也可以工作。

It is obviously a problem with determining the resource path. 确定资源路径显然是一个问题。 I suspect the app I am using uses its own class loader to load my extension. 我怀疑我正在使用的应用程序使用其自己的类加载器加载我的扩展程序。

The question is: Is there a way of loading the JasperReports classes so they behave themselves? 问题是:是否有一种加载JasperReports类的方式,以便它们表现出来? Alternatively all I can see is having a modified version of JasperReports in my extension, which is going to introduce bugs and be a maintenance nightmare. 另外,我所看到的只是扩展程序中具有JasperReports的修改版本,这将引入错误并成为维护的噩梦。

EDIT 编辑

This is not a duplicate of the File Resolver question. 这不是文件解析器问题的重复项。 This is about the class loader used to load the Jasper classes from within an application. 这是关于用于从应用程序中加载Jasper类的类加载器。

The issue is the CLASS-PATH of Moneydance (the app being extended). 问题是Moneydance的CLASS-PATH(正在扩展的应用程序)。 The path contains the jars of Moneydance and the extension itself because the ClassLoader has been extended. 该路径包含Moneydance的罐子和扩展本身,因为ClassLoader已经扩展。 The method getResourceAsStream has been overwritten but he method getResource has not so getResource does not find the Jasper resources. 方法getResourceAsStream已被覆盖,但是方法getResource尚未覆盖,因此getResource找不到Jasper资源。 The solution I have come up with is to load an executable jar (using Spring Boot) containing the JasperReports code and build an interface into that jar. 我想出的解决方案是加载包含JasperReports代码的可执行jar(使用Spring Boot),并在该jar中构建接口。

I am using as custom class loader to load the background task that contains the Jasper classes. 我使用自定义类加载器加载包含Jasper类的后台任务。 I can intercept the getResources method and find the resource in the jar. 我可以拦截getResources方法并在jar中找到资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM