I'm trying to change the page persistence in our XPages application, intending to move from "Keep pages in memory" to "Keep only the current page in memory". And of course I get run-time errors telling me that XPages cannot serialize a JavaScript function. But which function? The stack trace only shows the standard Java error stuff, but nothing about which variable or function cannot be serialized?
I had similar issues before, and it always cost me a lot of time to dig deep in the code and solve the problem. It takes ages... and I've really had it by now.
Is there a clever way to find out which function cannot be serialized??
UPDATE
What OpenLog Logger comes up with:
Client Version
Release 9.0.1FP3
January 12, 2015
Database aalto803.nsf
Agent /aASK.xsp
Method class java.lang.StackTraceElement.writeValue
Error Num -
Error Line 364
Error Msg Impossible de sérialiser une fonction JavaScript
Language Java
Stack Trace
java.io.IOException: Impossible de sérialiser une fonction JavaScript
at com.ibm.jscript.types.FBSValue.writeValue(FBSValue.java:364)
at com.ibm.jscript.types.FBSDefaultObject.writeExternal(FBSDefaultObject.java:746)
at com.ibm.jscript.std.ObjectObject.writeExternal(ObjectObject.java:106)
at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1462)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at java.util.HashMap.writeObject(HashMap.java:942)
at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1020)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1502)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
at java.io.ObjectOutputStream.writeUnshared(ObjectOutputStream.java:413)
at com.ibm.xsp.application.AbstractSerializingStateManager$FastObjectOutputStream.writeObjectEx(AbstractSerializingStateManager.java:438)
at com.ibm.xsp.application.AbstractSerializingStateManager$FastObjectOutputStream.writeObjectEx(AbstractSerializingStateManager.java:417)
at com.ibm.xsp.application.AbstractSerializingStateManager$FastObjectOutputStream.writeObjectEx(AbstractSerializingStateManager.java:417)
at com.ibm.xsp.application.AbstractSerializingStateManager$FastObjectOutputStream.writeObjectEx(AbstractSerializingStateManager.java:417)
at com.ibm.xsp.application.AbstractSerializingStateManager$FastObjectOutputStream.writeObjectEx(AbstractSerializingStateManager.java:417)
at com.ibm.xsp.application.AbstractSerializingStateManager.saveSerializedView(AbstractSerializingStateManager.java:294)
at com.ibm.xsp.application.AbstractSerializingStateManager.doSaveSerializedView(AbstractSerializingStateManager.java:269)
at com.ibm.xsp.application.FileStateManager.doSaveSerializedView(FileStateManager.java:290)
at com.ibm.xsp.application.FileStateManager.doSaveSerializedView(FileStateManager.java:270)
at com.ibm.xsp.application.AbstractStateManager.saveSerializedView(AbstractStateManager.java:114)
at com.ibm.xsp.application.StateManagerImpl.saveSerializedView(StateManagerImpl.java:152)
at com.ibm.xsp.application.ViewHandlerExImpl._saveViewState(ViewHandlerExImpl.java:455)
at com.ibm.xsp.application.ViewHandlerExImpl.saveViewState(ViewHandlerExImpl.java:449)
at com.ibm.xsp.application.ViewHandlerExImpl._renderView(ViewHandlerExImpl.java:324)
at com.ibm.xsp.application.ViewHandlerExImpl.renderView(ViewHandlerExImpl.java:336)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:103)
A recent discovery of mine answers this question too IMHO, see XPages: how to put a Java Date value in an ObjectObject . A few years back, I started with moving my code from SSJS to Java, and I had some (better: a lot of) trouble with the ObjectObject and ArrayObject classes, mostly with the rather ugly way values have to be converted using a class called FBSUtility.
My main issue was with the fact that I couldn't manage to store a Date in an ObjectObject object. In a later stage, I was happy to have found a call with a JSContext parameter, FBSUtility.wrap(jsContext, someDate)
, which permits storing a Date value. Call me clueless, about what the JSContext actually does here (which I am), but I thought that was the end to it.
Recently, in order to test our application, I changed the Persistence Mode, from a few pages in memory to everything on disk, hence forcing the serialization of all objects. I found out that a specific element of my application no longer worked, always stopping on a Serialization error. Further tests proved that there were no errors when I removed all Date values from the OO object.
Earlier, I had already adopted JsonJavaObject and JsonJavaArray classes for some other parts of the application (yeah I know, messy coding, big application, never time to do things right, 50 Mb template db, etc.). I rewrote the code to remove all use of the classes JSContext, FBSUtility, ObjectObject and ArrayObject, to replace them with the JsonJava classes, and there's no longer the dreaded message that a JS function cannot be serialized.
So, what I learned is: if your Persistence Mode is set to Keep pages on Disk
or Keep only the current page in memory
, try avoid ObjectObject objects and never use FBSUtility in combination with JSContext.