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:
javaControl.doSomething(); 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!javaControl.doSomething(); 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; javaControl.doSomething(); pause(0.05); drawnow; % this never hurt anyone! javaControl.doSomethingElse(); 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.