| Apache Wicket > Framework Documentation > Best Practices and Gotchas > More Potential Issues > InternalCloningError |
Wicket serializes pages to the session between requests. That's why entire component tree must be serializable - i.e., may not contain non-serializable objects. And, if such an object happens to be referenced at the moment of serialization by a field somewhere in a component tree, an WicketRuntimeException will be thrown. Unfortunately, in Tomcat stack trace displayed is not very helpful and the only useful information there is the class of WebPage that contains a non-serializable somewhere in the component tree. This faulty object may be found using the exclusion method - by removing components one by one and checking after each removal if the exception is no longer thrown.
There is a pitfall concerning final variables and serialization. Consider the following fragment:
public MyPanel(String id) { super(id); // ... final NonSerializableObject nonSerializableObj = getNSO(); // ... Link link = new Link("myLink") { public void onClick() { if (nonSerializableObj.getSomeBooleanProperty()) { // ... } // ... } } // ... }
Everything looks fine at the first sight, but let's look closer at how it works:
How this can be worked around? Extract this property as a local variable and reference it inside the inner class instead of the entire object. If this property is a Serializable then its conversion to field won't do any harm and therefore serializableness will be preserved.