Uploaded image for project: 'Wicket'
  1. Wicket
  2. WICKET-3136

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

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.4.12
    • 1.4.15
    • wicket
    • None
    • JVM 1.6.0_22, CentOS release 5.3 (Final) and Mac OS 10.6.4

    Description

      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:

      #

      1. A fatal error has been detected by the Java Runtime Environment:
        #
      2. SIGSEGV (0xb) at pc=0xf44a859e, pid=3145, tid=2969234320
        #
      3. JRE version: 6.0_22-b04
      4. Java VM: Java HotSpot(TM) Server VM (17.1-b03 mixed mode linux-x86 )
      5. Problematic frame:
      6. J org.apache.wicket.util.io.WicketObjectOutputStream$HandleTable.hash(Ljava/lang/Object;)I
        #
      7. If you would like to submit a bug report, please visit:
      8. 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.

      Attachments

        1. test-WICKET-3136.patch
          2 kB
          Pedro Santos
        2. hs_err_pid3145.log
          74 kB
          Roland Groen
        3. fix-test-WICKET-3136.patch
          4 kB
          Pedro Santos
        There are no Sub-Tasks for this issue.

        Activity

          People

            jcompagner Johan Compagner
            rolandgroen Roland Groen
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: