I have a class which has variables that are instances of classes such as vector, hashtable etc.
Code to serialize:
CRC32 checksum = new CRC32();
try {
// serialize the object tree to a byteArray so we can get a checksum
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
checksum.update(baos.toByteArray());
oos.close();
baos.close();
Code to deserialize:
ByteArrayInputStream fis = new ByteArrayInputStream(serFile);
List<Class<?>> safeClasses = Arrays.asList(AdHocReportDefinition.class,
TrustAdHocReportDefinition.class,
Hashtable.class,
SimpleReportField.class,
ReportField.class,
Date.class,
Vector.class,
SplittableSQLSimpleExpression.class,
Expression.class,
ArrayList.class);
reptDef = safeReadObject(AdHocReportDefinition.class, safeClasses, fis);
private static AdHocReportDefinition safeReadObject(Class<?> type,
List<Class<?>> safeClasses,
InputStream in) throws
IOException,
ClassNotFoundException {
return (AdHocReportDefinition) new ObjectInputStream(in) {
@Override
protected Class<?> resolveClass(ObjectStreamClass d) throws IOException,
ClassNotFoundException {
Class<?> clazz = super.resolveClass(d);
if (validationCondition(type, safeClasses, clazz)) {
return clazz;
}
// Not throwing an exception here as it will lead to functionality fail for any
// new class reference that added in TrustAdHocReportDefinition.
Logger.warn(LoggerCategories.ADHOC_REPORTING,
"Attempt to deserialize unauthorized " + clazz);
return clazz;
}
private boolean validationCondition(Class<?> type,
List<Class<?>> safeClasses,
Class<?> clazz) {
return clazz.isArray() ||
clazz.isPrimitive() ||
clazz.equals(type) ||
clazz.equals(String.class) ||
Number.class.isAssignableFrom(clazz) ||
safeClasses.contains(clazz);
}
}.readObject();
}
SimpleReportField#readObject
method:
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
in.defaultReadObject();
DBTable table = DBTable.forName(dbTableName, dbIndicator);
dbField = table.getField(dbFieldName);
}
Exception stack trace while deserializing by reading the serialized byte array from database:
java.io.EOFException
at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2905)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readUTFBody(ObjectInputStream.java:3678)
at java.base/java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:3470)
at java.base/java.io.ObjectInputStream.readString(ObjectInputStream.java:2058)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1663)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2490)
at java.base/java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:629)
at com.xxx.trust.trustadhoc.reporting.adhoc.SimpleReportField.readObject(SimpleReportField.java:150)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1175)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2351)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2222)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1681)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:493)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:451)
at java.base/java.util.Hashtable.readHashtable(Hashtable.java:1315)
at java.base/java.util.Hashtable.readObject(Hashtable.java:1259)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1175)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2351)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2222)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1681)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2490)
at java.base/java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:629)
at com.xxx.trust.trustadhoc.reporting.adhoc.AdHocReportDefinition.readObject(AdHocReportDefinition.java:814)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1175)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2351)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2222)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1681)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:493)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:451)
at com.xxx.trust.trustadhoc.reporting.adhoc.AdHocReportDefinition.safeReadObject(AdHocReportDefinition.java:479)
at com.xxx.trust.trustadhoc.reporting.adhoc.AdHocReportDefinition.forName(AdHocReportDefinition.java:426)
at com.xxx.trust.trustadhoc.display.AdHocCustomizeProcess.doProcess(AdHocCustomizeProcess.java:70)
at com.xxx.trust.dispatch.DispatcherServlet.dispatch(DispatcherServlet.java:60)
at com.xxx.trust.trustadhoc.display.TrustAdHocDispatcher.dispatch(TrustAdHocDispatcher.java:50)
at com.xxx.trust.dispatch.DispatcherServlet.doPost(DispatcherServlet.java:192)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at com.xxx.trust.dispatch.SecureServlet.service(SecureServlet.java:91)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.xxx.trust.trustadhoc.util.appFilter.doFilter(appFilter.java:42)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:829)
Hashtable has SimpleReportField as its value - that is where the error comes from.
Code works fine with less data selected in the application - so less number of fields to serialize/deserialize. Checked the memory issue by analyzing heap dump - there does not seem to be any memory related issue.
If someone can tell me how to troubleshoot this issue e.g. how to check whether all the instance variables of the class in question have been serialized properly - that will also be helpful. Thanks in advance.
Edit
Made code changes as per comments by Louis Wasserman but result is same. Still getting same error.
Here are those code changes:
CRC32 checksum = new CRC32();
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this);
oos.close();
byte[] bOutArray = baos.toByteArray() ; baos.close();
checksum.update(bOutArray);