JVM 1.6 crash caused by WicketObjectOutputStream, ClassStreamHandler, and 
Page.writePageObject 
-----------------------------------------------------------------------------------------------

                 Key: WICKET-3136
                 URL: https://issues.apache.org/jira/browse/WICKET-3136
             Project: Wicket
          Issue Type: Bug
          Components: wicket
    Affects Versions: 1.4.12
         Environment: JVM 1.6.0_22, CentOS release 5.3 (Final) and Mac OS 10.6.4
            Reporter: Roland Groen


The JVM 6u22 (1.6.0_22) crashes while clicking on a page in the wicket 
application. This is always the same page, but there are pages that function. 
When serializing a Page object with the pageMapName field set, a JVM 1.6 
crashes on a segmentation fault. The error message is:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0xf44a859e, pid=3145, tid=2969234320
#
# JRE version: 6.0_22-b04
# Java VM: Java HotSpot(TM) Server VM (17.1-b03 mixed mode linux-x86 )
# Problematic frame:
# J  
org.apache.wicket.util.io.WicketObjectOutputStream$HandleTable.hash(Ljava/lang/Object;)I
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

What goes on (and it took some time to find it):

The WicketObjectOutputStream has a field wich is called classHandler. This 
classHandler is suppose to match the class of the curObject. 
When Page.writePageObject is called AND the field Page.pageMapName is set, the 
method Page.writePageObject  will call writeObject(pageMapName). This call will 
change the value of WicketObjectOutputStream.classHandler into the classHandler 
of java.lang.String somewhere in WicketObjectOutputStream.writeObjectOverride. 
What happens next is a true disaster. Though some abstractions 
(PageSerializer), the method WicketObjectOutputStream.defaultWriteObject will 
is called. This method states:

classHandler.writeFields(this, curObject);

and due to fact that classHandler is a class handler of java.lang.String and 
not the one of the curObject, an instance of FieldAndIndex belonging to 
String.value  will be called with another object. This ends up at calling 
unsafe.getObject(object, index) (a native method) with the wrong object 
reference, something which is not a good idea with sun.misc.Unsafe. Every 
operation on the returned object will crash the JVM. Unfortunately the next in 
line to operate on the object is WicketObjectOutputStream.HandleTable.hash 
which also calls a native method called System.identityHashCode. This method is 
known for some JVM crashes, and has been attributed for the JVM crash for a 
while during the investigation into this JVM crash.

The solutions:
1) Do not use the WicketObjectOutputStream/WicketObjectStreamFactory. Works.
2) The method org.apache.wicket.Page.writePageObject(ObjectOutputStream) should 
not do a s.writeObject(pageMapName), but a s.writeUTF(pageMapName) instead. 
This way, the WicketObjectOutputStream.classHandler will not get the wrong 
value. org.apache.wicket.Page.readPageObject(ObjectInputStream) should be 
matched, of course.
3) WicketObjectOutputStream.defaultWriteObject() should update/get the right 
classHandler reference, just as 
WicketObjectOutputStream.writeObjectOverride(Object) does. You might even 
consider dropping the field entirely. 

The last option seems the best to me, because calling a writeObject from 
writePageObject is not semantically incorrect, furthermore, there might be 
other instances of this.





-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to