Bug 910

Summary: IcedTea Web removes Components from the Applet Container before Applet.stop() causing a Crash.
Product: [JogAmp] Newt Reporter: Sven Gothel <sgothel>
Component: awtAssignee: Sven Gothel <sgothel>
Status: RESOLVED FIXED    
Severity: normal CC: xerxes
Priority: ---    
Version: 1   
Hardware: All   
OS: all   
Type: --- SCM Refs:
jogl cleanup 87fa56ba6f88b3f87199c70324b919dc4ae4e6cf jogl cleanup 42f56dea3dc31de8049186825e18dc4b4767827e jogl cleanup 832a69834200f34a44d72639bfd47e73c72d2b42 jogl cleanup fa1d211c9658ce209f411e559333da0e2fccd402 jogl fix 0c3709ba4ba2dd4ba7bb2e7f0783fba346e090e1 jogl fix 1617b3edfa006432dbb7332c283e219e6583f4ec jogl 9310b11b2b6e1e89fa5ed9b8de26e56ff6a6b262 jogl 65247a8188c7470ee7f599f2e84cae1bc84fff9c
Workaround: TRUE
Attachments: SIGSEGV JVM dump
Debug log
Oracle and IcedTea Log: grep -e "^NewtCanvasAWT." -e "^JOGLNewtApplet1Run."
Oracle Debug Log (post fix)
IcedTea Debug Log (post fix)
Oracle and IcedTea Log: grep -e "^NewtCanvasAWT." -e "^JOGLNewtApplet1Run."
Oracle Debug Log (post fix)
IcedTea Debug Log (post fix)
IcedTea-Web 1.5pre+rbc73a1362e9c crash.log.gz
DemoBug910ExtendedAWTAppletLifecycleCheck: Oracle Applet
DemoBug910ExtendedAWTAppletLifecycleCheck: IcedTea Web 1.3

Description Sven Gothel 2013-11-22 18:47:14 CET
IcedTea Web (icedtea-7-plugin 1.3.2) Applet Launcher invokes 
applet.init() and subsequent removeNotify() before applet.stop() from non AWT-EDT Thread, 
causing a Crash.

Applet Lifecycle:

1 - JOGLNewtApplet1Run.init() START - [NetxPanelThread@http://test.net/a.html, isAWT-EDT false]
     Issues applet.add(NewtCanvasAWT) on AWT-EDT manually!
     (Current patch in my work-space)

1.1    - NewtCanvasAWT.addNotify.0 @ [AWT-EventQueue-1, isAWT-EDT true]

2 - JOGLNewtApplet1Run.start() START (isVisible false, isDisplayable true) - [NetxPanelThread@http://test.net/a.html, isAWT-EDT false]

...

3 - NewtCanvasAWT.removeNotify.0 @ [AWT-EventQueue-0, isAWT-EDT false]

Issues:

- Missing: Applet stop() and destroy() !

- Calling removeNotify(..) from AWT-EventQueue-0, which is _NOT_ this Applet's AWT-EDT,
  AWT-EventQueue-1 is instead.


+++

icedtea-7-plugin:amd64                   1.3.2-1
Comment 1 Sven Gothel 2013-11-22 18:49:43 CET
Created attachment 548 [details]
SIGSEGV JVM dump
Comment 2 Sven Gothel 2013-11-22 18:50:27 CET
Created attachment 549 [details]
Debug log
Comment 3 Sven Gothel 2013-11-22 18:53:22 CET
(In reply to comment #0)
> 3 - NewtCanvasAWT.removeNotify.0 @ [AWT-EventQueue-0, isAWT-EDT false]

If forcing execution of NEwtCanvasAWT.destroyImpl() on 'real' AWT-EDT,
i.e.  AWT-EventQueue-0, that task never gets executed!
Comment 4 Sven Gothel 2013-11-23 02:09:55 CET
(In reply to comment #0)
> Issues:
> 
> - Missing: Applet stop() and destroy() !
Not called due to crash !
Comment 5 Sven Gothel 2013-11-23 13:05:38 CET
Created attachment 550 [details]
Oracle and IcedTea Log: grep -e "^NewtCanvasAWT." -e "^JOGLNewtApplet1Run."
Comment 6 Sven Gothel 2013-11-23 13:06:58 CET
Created attachment 551 [details]
Oracle Debug Log (post fix)
Comment 7 Sven Gothel 2013-11-23 13:07:34 CET
Created attachment 552 [details]
IcedTea Debug Log (post fix)
Comment 8 Sven Gothel 2013-11-23 13:09:20 CET
Turns out the difference is the 'NewtCanvasAWT.removeNotify()' call,
which happens before Applet.stop() w/ IcedTea-Web - see  attachment 550 [details].
Comment 9 Sven Gothel 2013-11-23 14:20:11 CET
Fix is to detect whether NewtCanvasAWT.removeNotify() is performed on a valid thread.

This employs a certain heuristic, since the crash seems to be specific to IcedTea-Web Applet
and is not reproduced in other environments.

The crash is also not fully understood - since it should be acceptable to destroy
the JAWTWindow on a different thread - and locking is properly performed.

Heuristic:
   final boolean destroyJAWTOK = !isApplet || !addedOnAWTEDT || isOnAWTEDT;

if !destroyJAWTOK - the JAWTWindow shall be destroyed w/ next call - if destroyJAWTOK.

+++

Hence special safeguards needs to be 'installed', i.e. the window-closing-listener
is not operated thread safe if removeNotify() is called from !AWT-EDT.
Comment 10 Sven Gothel 2013-11-23 17:03:46 CET
Created attachment 553 [details]
Oracle and IcedTea Log: grep -e "^NewtCanvasAWT." -e "^JOGLNewtApplet1Run."

update
Comment 11 Sven Gothel 2013-11-23 17:04:16 CET
Created attachment 554 [details]
Oracle Debug Log (post fix)

update
Comment 12 Sven Gothel 2013-11-23 17:04:43 CET
Created attachment 555 [details]
IcedTea Debug Log (post fix)

update
Comment 13 Sven Gothel 2013-11-23 17:07:12 CET
Preparation / Cleanup of NEWT Applet Code to add workaround for Bug 910:
  jogl cleanup 87fa56ba6f88b3f87199c70324b919dc4ae4e6cf
  jogl cleanup 42f56dea3dc31de8049186825e18dc4b4767827e
  jogl cleanup 832a69834200f34a44d72639bfd47e73c72d2b42
  jogl cleanup fa1d211c9658ce209f411e559333da0e2fccd402

Fix as described in comment 9
  jogl fix 0c3709ba4ba2dd4ba7bb2e7f0783fba346e090e1
Comment 14 Sven Gothel 2013-11-24 18:35:01 CET
Refined the culprit as documented in comment 9:

  Applet Launcher removes Components from the Applet Container
  before Applet.stop() from non AWT-EDT causing a Crash. 

  - NewtCanvasAWT is added to the Applet AWT Container.

  - Before Applet.stop() is invoked, 'NewtCanvasAWT.removeNotify() is issued,
    indicating NewtCanvasAWT is removed from the Container.

  - NewtCanvasAWT should not be removed from the Container
    before Applet.destroy() has been called.
Comment 15 Xerxes Rånby 2013-11-25 15:36:59 CET
Created attachment 556 [details]
IcedTea-Web 1.5pre+rbc73a1362e9c crash.log.gz

IcedTea-Web Plugin (using IcedTea-Web 1.5pre+rbc73a1362e9c)

(15:20:28) xranby: 1. go to http://jogamp.org/deployment/archive/master/gluegen_751-joal_502-jogl_1160-jocl_881-signed/jogl-test-applets.html
(15:20:50) xranby: 2. click on "Dual" top right      that links to http://jogamp.org/deployment/archive/master/gluegen_751-joal_502-jogl_1160-jocl_881-signed/jogl-applet-runner-newt-GraphTextDemo01.html
(15:21:03) xranby: 3. let the applet load
(15:21:18) xranby: 4. press browser back button -> crash

xranby@xranby-ESPRIMO-P7935:~$ _JAVA_OPTIONS="-Dnativewindow.debug=all -Djogl.debug=all -Dnewt.debug=all" firefox
log attached.
Comment 16 Sven Gothel 2013-11-25 21:13:36 CET
Reopened: Issue still exist in IcedTea-Web 1.5*
Comment 17 Sven Gothel 2013-11-25 21:18:20 CET
IcedTea-Web_1.5pre+rbc73a1362e9c still issues NewtCanvasAWT.removeNotify() 
before before Applet.destroy(), i.e. removes NewtCanvasAWT from the Container
ahead of time (Applet protocol destroy()).

However, it fixes the non AWT-EDT issue, i.e. calls NewtCanvasAWT.removeNotify() 
from the actual AWT-EDT - good.

Since the root cause still exist, we cannot use heuristics as described in 
comment 9, but need to set a flag in NewtCanvasAWT to skip JAWT destruction
and remove it latter within Applet.destroy().

NewtCanvasAWT.removeNotify.0 - isApplet true @ [AWT-EventQueue-0, isAWT-EDT true]
Comment 18 Sven Gothel 2013-11-25 22:09:54 CET
Commit 1617b3edfa006432dbb7332c283e219e6583f4ec
adds workaround as described in comment 17.
Comment 19 Xerxes Rånby 2013-11-26 10:01:22 CET
IcedTea-Web_1.5pre+rbc73a1362e9c
using src: http://icedtea.classpath.org/hg/icedtea-web/rev/bc73a1362e9c

is now able to run and close all the applets; Dual, LApplet and NApplet w/o crashing.
tested using: http://jogamp.org/deployment/archive/master/gluegen_751-joal_502-jogl_1161-jocl_882-signed/jogl-test-applets.html
The workaround work.
Comment 20 Sven Gothel 2013-11-26 20:11:26 CET
9310b11b2b6e1e89fa5ed9b8de26e56ff6a6b262
    Bug 910: Add Standalone Extended Applet Lifecycle Validation Test
    
    Test is online @ http://jogamp.org/deployment/test/bug910/
    
    Test validates the state of the added component:
      TC1 - addNotify() and removeNotify() has been called from AWT-EDT.
      TC2 - removeNotify() is not called before Applet.destroy()
    
    Test also validates the Applet state:
      TA1 - isActive()
      TA2 - init count
      TA3 - start count
      TA4 - stop count
      TA5 - destroy count
Comment 21 Sven Gothel 2013-11-26 20:13:05 CET
Created attachment 559 [details]
DemoBug910ExtendedAWTAppletLifecycleCheck: Oracle Applet
Comment 22 Sven Gothel 2013-11-26 20:13:50 CET
Created attachment 560 [details]
DemoBug910ExtendedAWTAppletLifecycleCheck: IcedTea Web 1.3
Comment 23 Sven Gothel 2013-11-26 20:16:32 CET
IcedTea Web exposes the following errors:

isActive() state between start()-stop():
========================
Applet-State @ start: ERROR, active[exp true, has false]*, init[exp 1, has 1], start[exp 1, has 1], stop[exp 0, has 0], destroy[exp 0, has 0]

removeNotify() not called from AWT-EDT (Fixed in 1.5*):
================================
Applet.Canvas.removeNotify() ERROR: Not on AWT-EDT

removeNotify() called before destroy():
========================
Component-State @ stop: ERROR, contained[exp true, has true], addNotify[exp 1, has 1], removeNotify[exp 0, has 1]*, compCount 1, compClazz canvas0
Component-State @ destroy-remove.pre: ERROR, contained[exp true, has true], addNotify[exp 1, has 1], removeNotify[exp 0, has 1]*, compCount 1, compClazz canvas0
Comment 24 Sven Gothel 2013-11-26 20:19:33 CET
(In reply to comment #23)
> IcedTea Web exposes the following errors:
> 
> isActive() state between start()-stop():
> ========================
> Applet-State @ start: ERROR, active[exp true, has false]*, init[exp 1, has
> 1], start[exp 1, has 1], stop[exp 0, has 0], destroy[exp 0, has 0]
> 
> removeNotify() not called from AWT-EDT (Fixed in 1.5*):
> ================================
> Applet.Canvas.removeNotify() ERROR: Not on AWT-EDT
> 
> removeNotify() called before destroy():
> ========================
> Component-State @ stop: ERROR, contained[exp true, has true], addNotify[exp
> 1, has 1], removeNotify[exp 0, has 1]*, compCount 1, compClazz canvas0
> Component-State @ destroy-remove.pre: ERROR, contained[exp true, has true],
> addNotify[exp 1, has 1], removeNotify[exp 0, has 1]*, compCount 1, compClazz
> canvas0

See attachment 560 [details]
or test is online @ http://jogamp.org/deployment/test/bug910/
Comment 25 Sven Gothel 2013-11-26 20:39:39 CET
65247a8188c7470ee7f599f2e84cae1bc84fff9c
  Refine DemoBug910ExtendedAWTAppletLifecycleCheck: Test start/stop balance.

Updated on  http://jogamp.org/deployment/test/bug910/
Comment 26 Xerxes Rånby 2013-11-26 21:46:05 CET
Assigned bug to IcedTea Web:
http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1607