Jasper Reports как часть Java-приложения - PullRequest
0 голосов
/ 11 октября 2018

Я использую приложение 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 и изменим код для использования следующего фрагмента:

    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 в моем расширении, которая будет представлять ошибки и быть кошмаром обслуживания.

EDIT

Это не дубликат File Resolverвопрос.Речь идет о загрузчике классов, используемом для загрузки классов Jasper из приложения.

1 Ответ

0 голосов
/ 16 октября 2018

Проблема в ПУТИ КЛАССА Moneydance (приложение расширяется).Путь содержит файлы Moneydance и само расширение, потому что ClassLoader был расширен.Метод getResourceAsStream был перезаписан, но метод getResource не имеет, поэтому getResource не находит ресурсы Jasper.Решение, которое я придумала, состоит в том, чтобы загрузить исполняемый jar (с использованием Spring Boot), содержащий код JasperReports, и встроить интерфейс в этот jar.

Я использую в качестве пользовательского загрузчика классов для загрузки фоновую задачу, которая содержит классы Jasper.Я могу перехватить метод getResources и найти ресурс в банке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...