Message2460

Author paulfernhout
Recipients
Date 2005-08-11.03:33:48
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
The sys.excepthook functionality does not appear to
catch Swing generated exceptions, only exceptions
generated from straight Jython. This is perhaps because
Swing events happen in a different thread.

As discussed on the Jython users list on 2003-12-01:
"Re: sys.excepthook doesn't affect Swing exception
handling  "
by (Randolph Brown)
http://sourceforge.net/mailarchive/message.php?msg_id=6710944
in order to catch Swing exceptions, there needs to be
some special handling code written in Java. Apparently
there is a hack of:
   System.setProperty("sun.awt.exception.handler",
         "full.name.of.your.Class");
to do so.

For reference, that hack is "temporary", according to:
  http://www.jguru.com/faq/view.jsp?EID=427279
"Note: This method is a temporary hack to work around
the absence of a real API that provides the ability to
replace the event-dispatch thread. The magic
"sun.awt.exception.handler" property will be removed in
a future release."

Clearly this approach has worked for several versions
of Java, but it would be something that might need
future maintenance if Java changesthe API for doing
such hooks.

Still, based on that idea, I put together the following
change to the Jython code in case it is of use to anyone.

First, here is a test case that shows the latest Jython not
handling sys.excepthook in response to code activated
from a menu event. (All three of 2.1, 2.2a, and the
latest CVS seem to have this issue).

==== jython_swing_excepthook_test.py  ===

import sys
from javax.swing import JFrame, JMenuBar, JMenu, JMenuItem

class TestFrame(JFrame):
    def __init__(self):
        JFrame.__init__(self, "Jython excepthook Test")
        self.setBounds(200, 200, 400, 300)

        menuBar = JMenuBar()
        self.setJMenuBar(menuBar)

        fileMenu = JMenu("File")
        menuBar.add(fileMenu)

        menuItem = JMenuItem("Test",
                    actionPerformed=self.test)
        fileMenu.add(menuItem)

    def test(self, event=None):
        print "test exception -- divide by zero attempt
follows"
        x = 1 / 0
        print "divide by zero done"

def MyExceptHook(type, value, traceback):
    print "my exception handler:", type, value, traceback

sys.excepthook = MyExceptHook
frame = TestFrame()
frame.setVisible(1)

# now try the menu item
# and you will get default exception handler, 
# not my exception handler
# unless you apply patch

======================

Here is a patch that makes the exception handler be
called for the latest Jython from CVS. The patch consists
of a new class file (AwtExceptionHandler.java), and a
one line addition to an existing class file (jython.java).

==== AwtExceptionHandler.java ====
package org.python.util;

import org.python.core.Py;

public class AwtExceptionHandler {
      public void handle(Throwable t) {
        // This indirectly calls the excepthook if it
exists
        Py.printException(t, null, null);
      }
}

=========================

One line added to jython.java below to hook up the class...

==== jython.java changes =====

public class jython

...
    public static void main(String[] args) {

+       System.setProperty("sun.awt.exception.handler",
"org.python.util.AwtExceptionHandler");

...

=====================

Now this patch has not been heavily tested; I just got
it working as a proof of concept. Also the
"System.setProperty" line may not be in the best place
to link it in; I suspect there is a more general place
to put it and perhaps it may not be called when Jython
is used in other ways? I just downloaded the Jython
source recently, and this internal exception stuff is
bound to be tricky, and I don't know the Jython
codebase, so think of this as just a pointer in one
possible direction for a bug fix to be mulled over,
rather than the final answer. There may perhaps be
other Java exceptions still not caught. Also, I was
working in Java 1.4.2 (GNU/Linux Blackdown-1.4.2-02),
perhaps Java 1.5 has other options? For example, a
newly added feature in 1.5 (though I'm currently using
1.4.2, so it is unavailable to me) is this function:
 http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html
"java.lang
Class Thread
static void
setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler
eh)
          Set the default handler invoked when a thread
abruptly
terminates due to an uncaught exception, and no other
handler has been defined for that thread."

Also, I was not too sure about passing those two nulls to
"Py.printException(t, null, null);". Maybe they could
be something else?

Anyway, there was discussion in that thread above from
2003-12-01 of making a flag somewhere to set this
behavior and questioning what the default expectation
should be. Personally I think an excepthook in Python
should always fire on any exception, but I could see
not changing default behavior if people rely on it
already, especially if they call
Jython from Java and expect Java to be in control of
things. 
History
Date User Action Args
2008-02-20 17:18:29adminlinkissue1256374 messages
2008-02-20 17:18:29admincreate