4

I have setup an UncaughtExceptionHandler in my Swing app which will catch and log any uncaught exceptions in my code and report them to me. The stack traces for most of these errors are helpful in diagnosing the issues. However, sometimes I get a problem like this:

Thread : AWT-EventQueue-2
   Thread[AWT-EventQueue-2,6,javawsApplicationThreadGroup]

Error Message:
java.lang.Double cannot be cast to java.lang.Integer

Error String:
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer

StackTrace: class java.lang.ClassCastException
   java.lang.Integer.compareTo(Unknown Source)
   javax.swing.table.TableRowSorter$ComparableComparator.compare(Unknown Source)
   javax.swing.DefaultRowSorter.compare(Unknown Source)
   javax.swing.DefaultRowSorter.access$100(Unknown Source)
   javax.swing.DefaultRowSorter$Row.compareTo(Unknown Source)
   javax.swing.DefaultRowSorter$Row.compareTo(Unknown Source)
   java.util.ComparableTimSort.binarySort(Unknown Source)
   java.util.ComparableTimSort.sort(Unknown Source)
   java.util.Arrays.sort(Unknown Source)
   javax.swing.DefaultRowSorter.sortExistingData(Unknown Source)
   javax.swing.DefaultRowSorter.setSortKeys(Unknown Source)
   javax.swing.DefaultRowSorter.toggleSortOrder(Unknown Source)
   javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler.mouseClicked(Unknown Source)
   java.awt.AWTEventMulticaster.mouseClicked(Unknown Source)
   java.awt.Component.processMouseEvent(Unknown Source)
   javax.swing.JComponent.processMouseEvent(Unknown Source)
   java.awt.Component.processEvent(Unknown Source)
   java.awt.Container.processEvent(Unknown Source)
   java.awt.Component.dispatchEventImpl(Unknown Source)
   java.awt.Container.dispatchEventImpl(Unknown Source)
   java.awt.Component.dispatchEvent(Unknown Source)
   java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
   java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
   java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
   java.awt.Container.dispatchEventImpl(Unknown Source)
   java.awt.Window.dispatchEventImpl(Unknown Source)
   java.awt.Component.dispatchEvent(Unknown Source)
   java.awt.EventQueue.dispatchEventImpl(Unknown Source)
   java.awt.EventQueue.access$500(Unknown Source)
   java.awt.EventQueue$3.run(Unknown Source)
   java.awt.EventQueue$3.run(Unknown Source)
   java.security.AccessController.doPrivileged(Native Method)
   java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   java.awt.EventQueue$4.run(Unknown Source)
   java.awt.EventQueue$4.run(Unknown Source)
   java.security.AccessController.doPrivileged(Native Method)
   java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   java.awt.EventQueue.dispatchEvent(Unknown Source)
   java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
   java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
   java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
   java.awt.EventDispatchThread.pumpEvents(Unknown Source)
   java.awt.EventDispatchThread.pumpEvents(Unknown Source)
   java.awt.EventDispatchThread.run(Unknown Source)

I don't need help diagnosing this particular problem, the problem is clear (the user is trying to sort a JTable somewhere in the application, but the values in that column are Doubles, but the table declaration said to expect Integers). However, I have no idea by this stack trace which JTable is the source of the problem (and there are a LOT of tables in my app). Without knowing WHERE the problem is coming from, I have no way of fixing it.

So, is there any more useful debugging information I can obtain to help find the source of this problem and others like it?

Note: it's not just the fact that every line says "Unknown source," because none of the classes listed in the stack trace are my classes, they are all library classes. So even if they gave a line number to the problem, it would be to a class I cannot fix.

Mordechai
  • 15,437
  • 2
  • 41
  • 82
ryvantage
  • 13,064
  • 15
  • 63
  • 112
  • 2
    Can you reproduce the problem in a debugger? If you can, just set an exception breakpoint and then examine the variables. – biziclop Jul 20 '15 at 18:54
  • @biziclop, to reproduce the problem, I need to know the source. – ryvantage Jul 20 '15 at 18:55
  • Haha, yes, fair enough. I'm afraid you'd have to rely on user reports then. – biziclop Jul 20 '15 at 18:56
  • Can you compile with [`-g`](http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html) in a build for that user? – trashgod Jul 20 '15 at 19:06
  • @trashgod, I've never used (or heard of) -g in compiling. It's a Java Web Start app so I cannot compile it differently for any one user. But that looks intriguing. How much does the extra debugging info hinder performance? – ryvantage Jul 20 '15 at 19:12
  • `-g` won't help you one bit because as you say, none of your classes is in the call chain when the exception happens. The only part of performance the extra debug information really affects is the downloading of jars/class loading, it has very little runtime effect. – biziclop Jul 20 '15 at 19:23
  • @ryvantage: I never noticed a hit; it makes reverse-engineering easier, so check policy. – trashgod Jul 20 '15 at 19:24
  • @biziclop: I only see JRE classes; sorry if I'm overlooking the obvious. – trashgod Jul 20 '15 at 19:28
  • @trashgod That's the problem. Recompiling the application with `-g` won't have an effect on this stack trace. – biziclop Jul 20 '15 at 19:29
  • This [Q&A](http://stackoverflow.com/q/25174761/230513) reflects my experience with `-g`, but @biziclop is right about not helping with core classes. As suggested [here](http://stackoverflow.com/q/3132302/230513), the customer would need a full JDK. – trashgod Jul 20 '15 at 20:00
  • @trashgod, I think you're still missing the point. Even compiling with -g and the full JDK won't help because "Unknown Source" is not the problem. The problem is I don't know WHICH `JTable` in the app threw the error because the error was thrown by a `TableRowSorter`. But which table was it that caused the error? Finding the answer to that is the purpose of this question. – ryvantage Jul 20 '15 at 23:20
  • @ryvantage: Got it; thanks for clarifying. You might look for EDT violations using one the approaches cited [here](http://stackoverflow.com/q/7787998/230513). – trashgod Jul 21 '15 at 01:46

1 Answers1

1

In cases like this I override something just to add debugging info. For example in this case, we see in the stack trace that DefaultRowSorter.setSortKeys was called, so we could use a class

public class MyRowSorter<M, I> extends DefaultRowSorter<M, I> {
    ....

    @Override
    public void setSortKeys(List<? extends SortKey> sortKeys) {
        try {
            super.setSortKeys(sortKeys);
        } catch (Exception e) {
            //   
            // print debugging info here!
            //
            throw e;
        }
    }
}

Now you can set MyRowSorter to sort your tables, add the necessary debugging info to MyRowSorter, and you can debug which table had the problem.

lbalazscs
  • 17,474
  • 7
  • 42
  • 50
  • Ok, so now I'm gumbling, but I've just been using `JTable::setAutoCreateRowSorter(true)` all these years. Never needed to set a manual `RowSorter` :( – ryvantage Jul 21 '15 at 02:36
  • @ryvantage it's not that hard. But you can also override something else from the stack trace, the principle is the same. – lbalazscs Jul 21 '15 at 02:42