Safe Java Programming in MATlAB — A How-to Guide



as already mentioned, there are several potential pitfalls when programming using Matlab–
Java this section provides a suggested general programming guide for this environment
Programmers who abide by these suggestions should hopefully avoid most of the major pitfalls
In this book’s code snippets, I have often neglected to use these rules this was done merely
for book space considerations, but care should be taken while writing real code
Rule #1: Program Defensively
Never assume that the code will execute as expected: it may behave differently on different
computers; it may depend on some hidden timing order; it may depend on a particular JVM
major or minor version or for that matter on a specific Matlab release, it may depend on a
specific user action sequence, and so on
In short, the code may depend on things that we have never suspected and which may not
even be under our control When any of these dependencies fail, so will our code
While this is possible also in fully documented/supported code, it is especially important in
undocumented/unsupported code such as the Matlab–Java interface
the solution is simple: program defensively lavish the code with trycatch
blocks to catch
and handle run-time exceptions, and always test return values for illegal or unexpected values
In cases where you run some Java code on which you depend, proactively test the code’s successful
completion (e g , test the new GUI component’s visibility flag)
try
% Execute doSomething()
value = javaObject.doSomething();
% Check the return value
if (value ~= 0)
% error handling
else
% ok – continue normally
end
catch
% exception handling
end
% Execute doSomething(), no ret val
javaObject.doSomething();
% continue normally without checking
Do Don't
Rule #2: Never Forget EDt
Whenever you program anything in Java that is displayed onscreen (as opposed to doing
some non-GUI computational task), always remember to use the Event Dispatch thread
(EDt, explained in detail in Section 3 2)
Neglecting to use EDt is very tempting: the code is simpler and it will even work most of
the time but every now and then, our GUI (and Matlab itself) will hang, crash, or behave
in entirely unexpected ways Ouch !
In practice, especially for Matlab versions since R2008b (7 7), using EDt is relatively
painless: simply lavish the code with javaObjectEDT function calls whenever you create or use
any Java reference for the first time Matlab’s internal EDt-auto-delegation will then take
over all the dirty work Unfortunately, there is no such magic wand for Matlab versions
earlier than R2008b
% Create a JButton on the EDT
jButton = javax.swing.JButton('OK');
jButton = javaObjectEDT(jButton);
% R2008b + : rely on EDT auto-delegation
jButton.setLabel('also OK');
% R2008a-: use awtinvoke()
awtinvoke(jButton, ...
'setLabel(java.lang.String)',
'also OK');
% Create a JButton on Main Thread
jButton = javax.swing.JButton('OK');
% Not ok – might cause problems. . .
jButton.setLabel('Not OK');
Do Don't
© 2012 by Taylor & Francis Group, LLC
Undocumented Secrets of MATLAB26 ®-Java Programming
Rule #3: Use handle(. . .,‘CallbackProperties’)
Whenever you plan to use an event callback on a Java reference, never set the callback on
the naked (un-handled) Java reference, but always on the handled reference, as explained
in Section 3 4 Failing to do so will result in memory leaks and occasional run-time
errors, whereas using handled appears to carry no penalty other than slight extra code
complication
% Create a handled JButton reference
jButton = javax.swing.JButton('OK');
hButton = handle(jButton,...
'CallbackProperties');
% Set the requested callback
set(hButton,'MouseClickedCallback',...)
% Create a naked JButton reference
jButton = javax.swing.JButton('OK');
% Set the requested callback
set(jButton,'MouseClickedCallback',...)
Do Don't
Rule #4: Use Java Property accessor Methods
Matlab has a very convenient way to access Java objects’ property values: we can use the
built-in get and set functions to, respectively, retrieve and modify the specified object’s property
values
Unfortunately, using get and set on naked Java references causes memory leaks and should
be avoided In R2010b, a warning is even displayed in the Command Window whenever we
attempt to do so
Instead, either use get and set on the handled Java reference (see Rule #3), or better still use
the object’s natively supported property accessor methods, which are typically named getPropertyName
or isPropertyName (is for boolean [logical flag] properties; get for all the others),
and setPropertyName
% Use set on handled Java reference
set(hButton,'Label','This is OK');
% Use the native Java accessor method
jButton.setLabel('Even better');
% Use set on naked Java reference
set(jButton,'Label','Not OK')
Do Don't
Rule #5: Concentrate Undocumented Code
Concentrate as much of the code that uses undocumented features in a single location — a
single function or m-file this way, if and when our code breaks under a specific set of circumstances
(e g , new Matlab release or a different running platform), it will be easier to diagnose
and possibly fix the affected code If the undocumented-features-dependent code is
scattered throughout the entire program, then we would effectively need to diagnose and debug
the entire program Ouch, not again !
Rule #6: test backward Compatibility
as a corollary to Rule #1, try to test the code, especially sections that rely on undocumented
features, on earlier Matlab releases In some cases, Matlab has modified the interface
and/or behavior of its internal Java classes across Matlab releases Since we often cannot
know in advance on which Matlab release our code will run, it makes sense to test our code
on at least one old Matlab release
an example of using this rule (together with Rule #1) is given in Section 8 3:
try
cmdWinFrame = cmdWin.getTopLevelancestor; % MaTLaB 7
catch
cmdWinFrame = cmdWin.getTopLevelWindow; % MaTLaB 6
end