0
votes

I'm working with one problematic report and it always throws the same exception when client JRE is not the same as server's. This is an RMI app and the exception only occours with this report.


Report

It's a simple report, however it has an barcode component, and I've used 2 implementations offered by iReport 5.0.1 (Barbecue and Barcode4j) and both thrown the same exception:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.io.InvalidClassException: javax.swing.JComponent;
     local class incompatible:
        stream classdesc serialVersionUID = -2790168081368361182,
        local class serialVersionUID = 5670834184508236790
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:191)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
    at $Proxy17.geraRelatorio(Unknown Source)
    at base.gui.reports.ReportsPrinter.showReport(ReportsPrinter.java:151)
    at base.gui.reports.ReportsPrinter.showReport(ReportsPrinter.java:139)
    at jacad.gui.cadastros.curso.FrameCadastroPeriodoLetivo$30.executaAtividade(FrameCadastroPeriodoLetivo.java:1499)
    at jdaap.gui.components.loader.Loader$1.doInBackground(Loader.java:70)
    at jdaap.gui.components.loader.Loader$1.doInBackground(Loader.java:1)
    at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at javax.swing.SwingWorker.run(SwingWorker.java:335)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.InvalidClassException: javax.swing.JComponent;
    local class incompatible:
        stream classdesc serialVersionUID = -2790168081368361182,
        ocal class serialVersionUID = 5670834184508236790
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:604)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
 

I don't know what do now, I've tried everything I could to fix this, I don't believe that error was caused by Java code because this app have +- 300 reports, and only this one has a barcode. Here's a sample of Java code to call this report by RMI:

public JasperPrint executeReport(String reportFile, Map parameters) throws GenericException {

    FileInputStream is = (FileInputStream) getReportFile(reportFile);

    Connection conn = getConnection();

    JasperPrint print = null;

    try {
        parameters.put("P_REPORTS_PATH", Application.getInstance().getReportsPath());
        parameters.put(JRParameter.REPORT_LOCALE, new Locale("pt", "BR"));

        print = JasperFillManager.fillReport(Application.getInstance().getReportsPath() + reportFile, parameters, conn);
    } catch (JRException e1) {
        e1.printStackTrace();
        throw new GenericException(e1);
    }

    try {
        conn.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return print;
}

Client side:

public static void view(final JasperPrint print) throws GenericException {
    if (print == null) {
        throw new GenericException("Nenhuma visualização do relatório foi informada.");
    }

    new SwingWorker() {
        @Override
        protected Void doInBackground() throws Exception {
            JFrame viewer = new JFrame("Visualização do Relatório"); //$NON-NLS-1$
            viewer.setPreferredSize(new Dimension(800, 600));
            viewer.setLocationRelativeTo(null);

            JasperViewer jrViewer = new JasperViewer(print, true);
            viewer.getContentPane().add(jrViewer.getContentPane());
            new FrameConfig(viewer);
            return null;
        }
    }.execute();

}

public void showReport(String reportFile, Map parameters) throws GenericException {

    if (reportFile == null)
        throw new GenericException("Report file não pode ser nulo.");

    ReportsManager rm;
    try {
        rm = (ReportsManager) FacadeFactoryLocal.newInstance(ReportsManager.class);

        JasperPrint jasperPrint = rm.geraRelatorio(reportFile, parameters);
        view(jasperPrint);

    } catch (RemoteException e1) {
        e1.printStackTrace();
        throw new GenericException("Erro ao acessar o servidor para gerar o relatório.", e1.getStackTrace());

    }

}

Does anyone have a solution for this?

Thanks in advance.

1
Current, I've sended an byte array with compiled Jasper and send the same to a PDF generator to work. :/ - Carlos Spohr

1 Answers

0
votes

Don't serialize Swing components. There is a warning about that at the head of the Javadoc of every one of them. Serialized the underlying model.