0

問題のあるレポートを 1 つ扱っていますが、クライアント JRE がサーバーのものと同じでない場合、常に同じ例外がスローされます。これは RMI アプリであり、例外はこのレポートでのみ発生します。


報告

これは単純なレポートですが、バーコード コンポーネントがあり、iReport 5.0.1 で提供される 2 つの実装 (バーベキューと Barcode4j) を使用しましたが、どちらも同じ例外をスローしました。

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)
 

このアプリには +- 300 件のレポートがあり、バーコードがあるのはこのアプリだけなので、Java コードが原因でエラーが発生したとは思いません。RMI でこのレポートを呼び出す Java コードのサンプルを次に示します。

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

クライアント側:

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

    }

}

誰かがこれに対する解決策を持っていますか?

前もって感謝します。

4

1 に答える 1

0

Swing コンポーネントをシリアライズしないでください。それらのすべてのJavadocの先頭に、それに関する警告があります。基礎となるモデルをシリアル化しました。

于 2013-01-22T23:02:36.080 に答える