Cannot serialize JavaScript function - java

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)

XPages OpenLog Logger not only catches uncaught exceptions (it sounds like this is one of those), but also catches which component triggered the problem. It needs an error XPage in the application (otherwise after the error occurs there is no Render Response phase run, from which XPages OpenLog Logger retrieves the details). That might help you track it down.
Otherwise, check what functions you're storing in viewScope etc. That might help you narrow things down. SSJS is not really designed for object orientated programming, which I think is where issues arise when storing functions in scope.

The answer to your question is not so much WHICH function can't be serialized, its that NONE of your functions can be serialized. OR if you want to get very technical, none can be expected to persist in any way reliably. SSJS is not meant to be serialized. In this blog post here: http://xomino.com/2014/03/26/why-learning-javascript-is-more-critical-to-xpage-developers-than-java/ there is a good discussion in the comments about why and where serialization is toxic, specifically with SSJS (you can sort of disregard the actual discussion surrounding the blog post of java vs JavaScript - just concentrate on the bits concerning serialization).

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.

Related

Java equivalent to python EnvironmentError?

Is there any equivalent to EnvironmentError from python in java? Example follows:
raise EnvironmentError
With Java we take a rather myopic point of view and assume that we are in control of virtually every error that can come up (in the case of anything that is an Exception), or we assume that this is the result of some extraneous behavior (RuntimeException). However, both of those exceptions are still within some realm of our control.
The one thing that happens that's outside of our control are Errors. Y'know, things like running out of memory would be well outside of our control. Since EnvironmentError deals with errors outside the purview of Python, I would believe that Error is its Java counterpart in spirit.
In practice, it's likely closer to an Exception, given that it deals with OSError and IOError (and those are things that Java believes it can recover from, for the most part).

Persistent background checking with Selenium

First time poster, long time lurker. I've gotten a lot of great advice to problems from this site, but I haven't found anything here for the topic of this question. Normally I would bug our SME at the office but he's indisposed.
So, we use Selenium Web Driver to do automated tests. I'm working on an application with some mapping and demographics features, so my tests are very function vs. form oriented.
My tests are written such that I have classes/methods that are a part of the puzzle (the site is essentially one workflow where you go from page 1 to page 5 and the same actions need to be performed in steps 2-3, for example, but test A might do something different on page 4 to see the result in page 5. Clear as mud?
Anyways, during manual tests, I can sometimes see an error message pop up on the site (a hidden div that will become visible if it detects an error, but it's usually a very generic/vague error). This error sometimes pops up even if you're able to go through the flow with no other ill-effects. However, I want to capture when these errors happen so I can look for patterns - if this means just logging it to console or failing the test...I can figure that out later.
The immediate problem is having a persistent check in place that will always look for this error during every test. I could create a method and call it in my "action" methods, though this would leave gaps and slow the tests down. Is there any clever way of implementing something like this without slowing the tests down or calling this check every time I do a step in the process? Also, forgive me, I'm still learning Java and the selenium web driver, so if I've said anything stupid, that's why.
Since this message is persistent if it is there, you might try adding a check for it in your test case teardown method. (I would recommend that you reduce the implicit wait time before you do that check, though, otherwise each test will take an extra amount of time waiting for an error message that isn't there.)
Another possible option is to define your own listener on your own test runner and update the testFinished() method to go check for your error message. See this for some ideas.
Since it sounds like the error messages are always in known locations on each page, I would create a method (or methods, depending on how many error message locations there are on a given page) that looks to see if an error exists and then log it before leaving the page. It sounds like you might be using the page object model. If so, you can add these methods to the each relevant page object for easy access.
NOTE: Checking for errors once before you leave the page may not be enough. You may need to check each time you do some action that might cause an error. This is probably not a bad practice anyway because it will help in debugging errors because you will notice an error closer to the time it was triggered, thus narrowing down what caused the error.
If you have the ability, do something like log it as a warning so that it doesn't fail your test but stands out (and is searchable) in your logs.
You seem concerned that checking for all these errors will significantly slow your script. If properly written, it shouldn't add a significant delay. One significant delay you might run into is if you have implicit waits turned on and are checking for elements that don't exist (e.g., unless there's an error). This will cause the implicit wait to be applied each time you search for the missing element and will likely add significant time to the run time. My suggestion is to turn off implicit waits and add explicit waits only where needed. Searching for any element will add some time but 25ms here and there should be negligible in an overall script run.
Have you tried using EventFiringWebDriver?
There is an answer here on what it does:
What is EventFiringWebDriver in selenium?
Newer selenium versions have more types of events present in the interface, which can broaden its use on these types of tests.

Does absence of serialization errors mean absence of pitfalls?

Thinking about what is serializable and what is not, do I get it right that if no error messages pop up during de/serialization then everything has been perfectly serialized and deserialized? Or is it still possible while not getting any errors to have my object somehow damaged or changed during de/serialization?
My question may seem odd but it's rather difficult for a newbie like myself to keep track of every part of an object (which is fairly vast) whether this part can be serialized or not. So I'd rather fully rely on error indications if it's an adequate approach.
Actually not. Absence of error in writing/reading serializable object to/from DataStream means there is no exceptional situations. But that doesn't mean that you will get consistent data.
You could read a lot more in Effective Java by Bloch. There are several chapters concerning serialization.

Capture all thrown exceptions in java?

I doubt such a thing is possible, but without attaching a debugger to a java application, is it possible to have some collection populated with information about every exception that is generated in a java application, regardless of if it is caught or not? I know that in .NET, messages get generated by the application about exceptions which at that point are called "First Chance Exceptions", which may or may not subsequently be handled by the application. I'm wondering if there might be a similar mechanism in java I can exploit to view information about all the exceptions generated at runtime.
Just to clarify. This has nothing to do with the context in which an exception occurs. This question is not about what I do in a catch block, or unhandled exceptions. Its about knowing if the JVM provides a mechanism to see every exception generated at runtime, regardless of what generated it, or the context.
Why not, it's of course possible! But firstly.. Logging all exceptions encountered by the JVM is a waste of life. It's meaningless in every sense, there could be several excetion's thrown without any significance.
But if indeed if you have no choice, you could tweak your Java to do that.
Breaking every rule of good programming, what we live for, I give you this idea:
Copy the source code of java.lang.Exception from JDK sources to your project.
Create a method in your Exception.java like below:
private void logException() {
// Your logging routine here.
}
Edit java.lang.Exception to call this method logException() at the end of every constructor.
Add the new java.lang.Exception to bootstrap classpath.
Set your logging levels etc and run.
Put your heads up, present this to your weird client, use your diplomatic skills and scare them in few words 'we can do it.. but its your own risk'. Likely you will convince him not to use this.

how can I get the History of an object or trace an Object

I have a requirement, where support in my application a lot of processing is happening, at some point of time an exception occrured, due to an object. Now I would like to know the whole history of that object. I mean whatever happened with that object over the period of time since the application has started.
Is this peeping into this history of Object possible thru anyway using JMX or anything else ?
Thanks
In one word: No
With a few more words:
The JVM does not keep any history on any object past its current state, except for very little information related to garbage collection and perhaps some method call metrics needed for the HotSpot optimizer. Doing otherwise would imply a huge processing and memory overhead. There is also the question of granularity; do you log field changes only? Every method call? Every CPU instruction during a method call? The JVM simply takes the easy way out and does none of the above.
You have to isolate the class and/or specific instance of that object and log any operation that you need on your own. You will probably have to do that manually - I have yet to find a bytecode instrumentation library that would allow me to insert logging code at runtime...
Alternatively, you might be able to use an instrumenting profiler, but be prepared for a huge performance drop when doing that.
That's not possible with standard Java (or any other programming language I'm aware of). You should add sufficient logging to your application, which will allow you to get some idea of what's happened. Also, learn to use your IDE's debugger if you don't already know how.
I generally agree with #thkala and #artbristol (+1 for both).
But you have a requirement and have no choice: you need a solution.
I'd recommend you to try to wrap your objects with dynamic proxies that perform auditing, i.e. write all changes that happen to object.
You can probably use AspectJ for this. The aspect will note what method was called and what are the parameters that were sent. You can also use other, lower level tools, e.g. Javasist or CgLib.
Answer is No.JVM doesn't mainatain the history of object's state.Maximum what you can do you can keep track of states of your object that could be some where in-memory and when you get exception you can serialize that in-memory object and then i think you can do analysis.

Categories