Search code examples
javaserializationjasper-reportsjfreechart

Java JasperPrint RMI deserialization error


I have two projects set up as client and server using Spring in Java 7 update 51. The underlying system is Scientific Linux 6.5 (kernel version 2.6.32-431.23.3.el6.x86_64). The used libraries are jasperreports-5.6.0, iText-2.1.7, jcommon-1.0.15 and jfreechart-1.0.12 .

The client reads a JasperReports design document (.jrxml) into a byte array and sends it to the server. The server then creates a JasperPrint object:

InputStream inputStream = new ByteArrayInputStream(reportDesignByteArray);
jasperReport = JasperCompileManager.compileReport(inputStream);
jasperPrint = JasperFillManager.fillReport(jasperReport, parameter, dataSource);

This object is returned to the client via RMI. At this point I am getting the following error (JasperPrint is derived from Serializable though):

java.io.EOFException
  at java.io.ObjectInputStream$BlockDataInputStream.readBoolean(ObjectInputStream.java:2758)
  at java.io.ObjectInputStream.readBoolean(ObjectInputStream.java:905)
  at org.jfree.io.SerialUtilities.readStroke(SerialUtilities.java:204)
  at org.jfree.chart.plot.CategoryPlot.readObject(CategoryPlot.java:5037)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:500)
  at org.jfree.chart.JFreeChart.readObject(JFreeChart.java:1670)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:500)
  at net.sf.jasperreports.engine.fill.JRTemplatePrintImage.readObject(JRTemplatePrintImage.java:445)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
  at java.util.ArrayList.readObject(ArrayList.java:771)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
  at java.util.ArrayList.readObject(ArrayList.java:771)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
  at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:500)
  at net.sf.jasperreports.engine.JasperPrint.readObject(JasperPrint.java:722)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
  at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
  at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
  at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
  at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
  at cern.lhc.hwc.acctesting.gui.dialog.CreateNewReportDialog.createReport(CreateNewReportDialog.java:185)
  at cern.lhc.hwc.acctesting.gui.dialog.CreateNewReportDialog$2$1.construct(CreateNewReportDialog.java:126)
  at cern.accsoft.gui.frame.Task.doConstruct(Task.java:320)
  at cern.accsoft.gui.frame.Task.access$300(Task.java:58)
  at cern.accsoft.gui.frame.Task$SwingWorkerExt.doInBackground(Task.java:420)
  at javax.swing.SwingWorker$1.call(SwingWorker.java:296)
  at java.util.concurrent.FutureTask.run(FutureTask.java:262)
  at javax.swing.SwingWorker.run(SwingWorker.java:335)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  at java.lang.Thread.run(Thread.java:744)

I tried to perform the serialization myself with the following procedure:

Server

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(jasperPrint);
byte[] serializedPrint = byteArrayOutputStream.toByteArray();

Client

ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serializedPrint);
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
jasperPrint = (JasperPrint) objectInputStream.readObject();

I still get the same error. However, it works in a local unit test, so the error only appears when using RMI. I also checked the serialized object regarding size and SHA-1 hash on the server and the client side. They are identical.

Do you have any suggestions how to fix this?


Solution

  • The problem was solved by updating JFreeChart to version 1.0.13 on both server and client side.