Handling red Java console errors

Anyone who has worked with non-trivial Matlab GUIs knows that from time to time we see various red Java stack-trace errors appear in the Matlab console (Command Window). These errors do not appear often when using documented Matlab controls, but they do from time to time. The errors appear significantly more frequently when working with undocumented Java-based hacks that I often show on this blog, and especially when working with complex controls such as uitable or uitree. Such controls have a very large code-base under the hood, and the Matlab code and data sometimes clashes with the asynchronous Java methods that run on a separate thread. Such clashes and race conditions often lead to red Java stack-trace errors that are spewed onto the Matlab console. For example:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at com.jidesoft.plaf.basic.BasicCellSpanTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at com.jidesoft.grid.CellStyleTable.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
	at java.util.Vector.elementAt(Unknown Source)
	at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
	at com.jidesoft.grid.ContextSensitiveTable.getCellRenderer(Unknown Source)
	at com.jidesoft.grid.CellSpanTable.getCellRenderer(Unknown Source)
	at com.jidesoft.grid.TreeTable.getActualCellRenderer(Unknown Source)
	at com.jidesoft.grid.GroupTable.getCellRenderer(Unknown Source)
	at com.jidesoft.grid.JideTable.b(Unknown Source)
	at com.jidesoft.grid.CellSpanTable.calculateRowHeight(Unknown Source)

In almost all such Java error messages, the error is asynchronous to the Matlab code and does not interrupt it. No error exception is thrown (or can be trapped), and the Matlab code proceeds without being aware that anything is wrong. In fact, in the vast majority of such cases, nothing is visibly wrong – the program somehow overcomes the reported problem and there are no visible negative effects on the GUI. In other words, these error messages are harmless and can almost always be ignored. Still, if we could only stop those annoying endless red stack-trace messages in the Matlab console!

Note that today’s post only discusses untrappable asynchronous Java error messages, not synchronous errors that can be trapped in Matlab via try-catch. These synchronous errors are often due to programmatic errors (e.g., bad method input args or an empty reference handle) and can easily be handled programmatically. On the other hand, the asynchronous errors are non-trappable, so they are much more difficult to isolate and fix.

In many of the cases, the error occurs when the control’s underlying data model is changed by the Matlab code, and some of the controls’s Java methods are not synced with the new model by the time they run. This can be due to internal bugs in the Matlab or Java control’s implementation, or to simple race conditions that occur between the Matlab thread and the Java Event Dispatch Thread (EDT). As noted here, such race conditions can often be solved by introducing a simple delay into the Matlab code:

pause(0.05); drawnow;javaControl.doSomethingElse();

In addition, asking Matlab to run the Java component’s methods on the EDT can also help solve race conditions:

javaControl = javaObjectEDT(javaControl);

Unfortunately, sometimes both of these are not enough. In such cases, one of the following ideas might help:

  • Add fprintf(' \b') to your Matlab code: this seemingly innocent hack of displaying a space & immediately erasing it with backspace, appears to force the Java engine to flush its event queue and synchronize things, thereby avoiding the annoying Java console errors. I know it sounds like adding a sprinkle of useless black magic to the code, but it does really work in some cases!
    pause(0.05); drawnow;  % this never hurt anyone!
    fprintf( '\b');javaControl.doSomethingElse();
  • It is also possible to directly access the console text area and remove all the text after a certain point. Note that I strongly discourage messing around with the console text in this manner, since it might cause problems with Matlab’s internals. Still, if you are adventurous enough to try, then here’s an example:
    jCmdWinDoc = com.mathworks.mde.cmdwin.CmdWinDocument.getInstance;
    currentPos = cmdWinDoc.getLength;
    pause(0.05); drawnow;  % this never hurt anyone!
    pause(0.1);  % let the java error time to display itself in the console
    jCmdWinDoc.remove(currentPos, cmdWinDoc.getLength-currentPos);
  • When all else fails, consider simply clearing the Matlab console using the Matlab clc command a short while after updating the Java control. This will erase the red Java errors, along with everything else in the console, so naturally it cannot be freely used if you use the console to display useful information to the user.

It should be emphasized: not all of these suggested remedies work in all cases; in some cases some of them work, and in other cases others might work. There does not seem to be a general panacea to this issue. The main purpose of the article was to list the possible solutions in a single place, so that users could try them out and select those that work for each specific case.

Do you know of any other (perhaps better) way of avoiding or hiding such asynchronous Java console errors? If so, then please post a comment below.

Categories: Desktop, Java, Low risk of breaking in future versions

Tags: ,

Bookmark and SharePrint Print

3 Responses to Handling red Java console errors

  1. Malcolm Lidierth says:

    A couple of general comments:

    pause(0.05); drawnow;  % this never hurt anyone!

    Flushing the event queue unnecessarily can hurt when large data sets are displayed. Repaints are handled on the EDT, and managed by a RepaintManager that runs on another thread. The RepaintManager seeks to collapse multiple paint requests into a single, or fewer requests (so, if a request to update a specific screen region is called repeatedly, the RepaintManager can paint that region just once putting the end result on the screen). Flushing the queue can potentially disrupt that optimisation.

    For Swing components, calling the revalidate() method will often be more efficient – and may be what

    fprintf( '\b')

    achieves. This marks a component as “dirty” and schedules a layout for its parent. It also marks it to be repainted next time an ancestor is repainted – which can be achieved with a direct call to the repaint() method. Both revalidate and repaint methods are thread-safe for JComponents.

    In MATLAB, there is still an issue of how that relates to TMW’s graphics pipeline. A final pause/drawnow may be needed.

    For the unwanted errors: I wonder if those are being written direct to the console or via a logger. MATLAB ships, or once shipped, with log4J. If that is using a console logger for output, it might be possible to replace it and install a custom logger or turn it off.


  2. Xiangrui Li says:

    Wow, this post is just in time for me! I am experiencing the exact problem recently since I start to use DefaultListModel. I figured out drawnow reduces the chance of red output, but it still happens occasionally.

    I just tried the suggested tricks one by one. It seems fprintf(‘ \b’) is not very effective. pause+drawnow works well, and javaObjectEDT trick alone works well too. Anyway I am using both for now.

    Thanks, Yair.


    • @Xiangrui – I’m glad I helped. I should have emphasized in the post text that not all suggested remedies work in all cases; in some cases some of them work and in other cases others work. There does not seem to be a general panacea to this issue. The main purpose of the article was to list the possible solutions in a single place, so that users like yourself could try them out and select those of them that work for each specific case. I’ve now added this clarification to the main text.

Leave a Reply

Your email address will not be published. Required fields are marked *