Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Profiling Java in Matlab

Subject: Profiling Java in Matlab

From: Michael

Date: 19 Sep, 2007 07:00:51

Message: 1 of 9

I have some difficulties of profiling java source code from
Matlab. I ‘m creating an application which is invoked by a
Simulink block instead of the "Function Bllock Parameters"
dialog. Sometimes my application will runs in a deadlock
and I don’t know exactly were the error occurs. In addition
I would just like to mention that I’m using SWT and JFace
libraries.

I would be delighted if you send me tips for profiling java
code from Matlab.

Subject: Profiling Java in Matlab

From: Wolfgang Ulmer

Date: 9 Oct, 2007 14:42:04

Message: 2 of 9

Hi Michael,

while using Swing with Java, I discovered the same problem
which is due to the fact, that Matlab uses the AWT/Swing
Event Handling Thread to do some computation.

You can even easily create a deadlock if you enter the
following commands on the prompt:
>> import com.mathworks.jmi.*;
>> matlab = Matlab;
>> matlab.eval('1+1');

I think, that one solution is not to use the java event
mechanisms but the Matlab methods for defining callback
routines.

Example:

button = JButton('Close');
set(button,'ActionPerformedCallback',@buttonClosePressed);

function buttonClosePressed(handle,event)
   doSomething();
end

-------------

See http://xtargets.com/snippets/tag/java for details and
further examples.

Don't expect Mathworks to answer your question... they do
not support Java GUI-Matlab interaction.

Wolfgang

Subject: Profiling Java in Matlab

From: Michael Bushe

Date: 31 Oct, 2007 18:54:40

Message: 3 of 9

"Wolfgang Ulmer" <spam@wulmer.de> wrote in message
<feg3vs$6ha$1@fred.mathworks.com>...
> Hi Michael,
>
> while using Swing with Java, I discovered the same problem
> which is due to the fact, that Matlab uses the AWT/Swing
> Event Handling Thread to do some computation.
>
> You can even easily create a deadlock if you enter the
> following commands on the prompt:
> >> import com.mathworks.jmi.*;
> >> matlab = Matlab;
> >> matlab.eval('1+1');
>
> I think, that one solution is not to use the java event
> mechanisms but the Matlab methods for defining callback
> routines.
>
> Example:
>
> button = JButton('Close');
> set(button,'ActionPerformedCallback',@buttonClosePressed);
>
> function buttonClosePressed(handle,event)
> doSomething();
> end
>
> -------------
>
> See http://xtargets.com/snippets/tag/java for details and
> further examples.
>
> Don't expect Mathworks to answer your question... they do
> not support Java GUI-Matlab interaction.
>
> Wolfgang


Wolfgang's example will do most of what you want, and he is
right - you need to use MATLAB-provided APIs for accessing
Swing Events. It is not correct, however, that MATLAB does
computation on the AWT/Swing thread, this would lock up
GUIs. Also, using jmi classes is not a good idea. They are
not public or supported and it's easy to use them improperly
(even for developers inside the MathWorks). Lastly, there
is a memory leak in the example, the workaround is detailed
below, but first, let's discuss Swing threading.

The Swing threading problem is not specific to MATLAB. In
pure Java if you write the following innocent looking code,
it is erroneous:

package example;

import javax.swing.*;

public class SwingApp {
    JFrame frame = new JFrame();
    JButton button = new JButton("Do Something");

    public void showFrame() {
      frame.getContentPane().add(getButton());
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public JButton getButton() {
        return button;
    }

    public static void main(String args[]) {
        //Wrong! Swing object construction not on the
EventDispatchThread
        SwingApp app = new SwingApp();
        //Wrong! Swing component access not on the
EventDispatchThread
        app.showFrame();
    }
}

The problem is that the class is making Swing calls on
Java's main thread. Sun asks developers to follow the rule
that all access to Swing components must occur on Swing's
EventDispatchThread (there may be some leeway, but it's best
to always follow the rule). This may look like it works
fine, but every so often you'll encounter lock ups and
strange behavior like listeners not firing.

This rule is broken when calling Swing components from the
MATLAB command line in the same manner since Swing calls are
being made from the MATLAB thread:

>> javaaddpath c:\myapp\classes
>> app = example.SwingApp; % Wrong! Swing object
construction not on the EventDispatchThread
>> app.showFrame(); % Wrong! Swing component access not on
the EventDispatchThread

In pure Java, the right way to write this code is to wrap
all Swing calls in a Runnable that is later called on the
EventDispatchThread:

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                SwingApp app = new SwingApp();
                app.showFrame();
            }
        });
    }

How can you do the same from MATLAB? There are additional
undocumented APIs that you can use to avoid Java Swing
threading issues, specifically awtcreate, awtinvoke and
javacomponent. These APIs are not yet final and are
therefore undocumented and can change in future releases.
Please don’t expect this to be the best way to work with
Swing Components going forward as we are planning to change
these APIs. We appreciate any feedback you can give us to
help us deliver APIs that meet your needs.

The functions awtcreate and awtinvoke both ship undocumented
– open the M-file for example usage. They both ensure that
the work for the M command that interacts with the Java
component happens on Java's EventDispathThread and not
MATLAB's main thread.

For the SwingApp, you can ensure the calls are pushed onto
the EventDispatchThread by using awtcreate and awtinvoke
like so:

>> app = awtcreate('example.SwingApp');
>> awtinvoke(app, 'showFrame');

The undocumented awtcreate and awtinvoke commands are like
wrapping each M line in a SwingUtiities.invokeLater call.
Though unsupported now, it works well.

If you are writing your own Java classes, you may want to
consider not using awtcreate and awtinvoke and push
Swing-related Java code to your own classes. This will make
for better performance since it is one push to Swing's
EventDispatchThread, not many.

For example, you could run the example SwingApp above with
the main() corrected to use SwingUtilities.invokeLater,
directly from M:

>> example.SwingApp.main('')

Since the class's main() method calls invokeLater, this is
safe.

Rewriting your original example using awtcreate and
awtinvoke would look like this:

button = awtcreate('javax.swing.JButton');
awtinvoke(button,'setLabel','Close');

% make the button a handle object before calling set
button = handle(button,'callbackproperties');
set(button,'ActionPerformedCallback',@buttonClosePressed);
javacomponent(button)

In addition to the awtcreate and awtinvoke usage, there are
two other things to notice about the rewritten example:
1) It's better to use the "handle" command before calling
"set" (this will prevent a memory leak).
2) The javacomponent command, also undocumented, puts any
Java Swing component in a figure window – open the M-file
for example usage.

This is tricky stuff especially since the threading issues
are not immediately apparent. We are interested in
providing the best Java GUI experience we can in MATLAB.
Any feedback is greatly appreciated.

Subject: Profiling Java in Matlab

From: Yair Altman

Date: 31 Oct, 2007 21:59:55

Message: 4 of 9

Michael,

I'm absolutely thrilled that someone at TMW, finally after
all these years, has taken the time to publicly comment on
this issue. Please be assured that readers of this thread
understand that the entire issue of Swing/JMI integration is
not officially supported, and that the API is subject to
change and might contain bugs.

This said, please let us know if we may approach you (or
Bill, who has shown a flicker of Java-related interest) with
Java-related bugs/requests. All official doors are closed to
us, you know, because of the unsupported nature. You've
shown an interest in advancing ML-Java integration - user
inputs may help.

To the point: awtinvoke (and related parseJavaSignature)
have several limitations/bugs that prevent its usage in some
cases. In other cases, problems in the Java objects
reflection visibility, which is used by awtinvoke, cause
awtinvoke to fail. In all these cases we have to resort to
using the direct calling syntax:

jbutton.setLabel('Close');

Unfortunately, starting with R2007b, this syntax displays an
ugly warning and stack dump on the Command Window, although
the call itself works well. One has to use another
undocumented feature to turn the warnings off (I don't think
this has ever been reported yet):

com.mathworks.mwswing.MJUtilities.setThreadingChecksEnabled(0);

Another major problem using Java in Matlab is that AFAIK
Java exceptions cannot be caught (via matlab's try-catch)
nor suppressed from the Command Window.

I think I'll stop here (there's plenty more where this came
from). If you, Bill or anyone picks up the ball I'll be
happy to expand, and I'm sure others will too.

Yair Altman

Subject: Profiling Java in Matlab

From: Bill York

Date: 2 Nov, 2007 17:32:11

Message: 5 of 9

Yair, I'm glad to hear your enthusiasm!

Feel free to contact me directly with questions about Java.

Michael and I will craft a reply and possibly post it here.

Bill

Subject: Profiling Java in Matlab

From: Arwel Hughes

Date: 12 Nov, 2007 16:13:43

Message: 6 of 9

Hi Guys,
I too am very pleased to see these Java / ML issues being
adressed! I'm writing an application at the moment which
has a large, multi frame Swing MDI sitting on top of a
Matlab program. It seems to be working okay, but I guess
I've just been lucky as I've not taken any special
precautions for threading issues, so I read the above with
great interest.

My main approach is to deal with most of the Swing in their
own pure classes, and invoke these from Matlab. But,
there's been a great deal of bits where I've felt I havent
been able to do this, because I didn't know how to access
the 'ActionPerformedCallback' etc for objects instantiated
in Java.
So for example, if I have something along the lines of....


import java.awt.*;
import javax.swing.*;

public class myButtons extends JFrame {
  public static void main(String[] args) {
    new myButtons();
  }

  public myButtons() {
    Container content = getContentPane();
    content.setLayout(new FlowLayout());
    JButton button1 = new JButton("Java");
    content.add(button1);
    button1.addActionListener(this)
    pack();
    setVisible(true);
  }
    
  public void ActionPerformed(ActionEvent event){
      !HOW TO GET THIS TO POINT TO MATLAB?!
}



...I have not been able to work out how to get Matlab
respond to the button events. So, I've had to do this in ML
on lots of things....


myFrame = JFrame();
button = JButton;
myFrame.getContentPane().add(button);
set(button,'ActionPerformedCallback',@myFun..


So it seems from the examples above that if I could find
the relevant objects in a pure Swing made GUI, then I could
use the

button = handle(button,'callbackproperties');
set(button,'ActionPerformedCallback',@buttonClosePressed);

approach to set the callback to point to Matlab. This would
actually be very nice indeed, as then in principle one
could make a very nice looking GUI using something like the
Netbeans GUI designer, and then just invoke this from
Matlab, and use the 'handle' way of setting up the relevant
callbacks??

Another drawback with my Swing based MDI of course is that
I've not been able to put Matlab graphics into a Java
container. I've had a look at Yair's 'GetJFrame' and hoped
that I could just steal the underlying Jpanel from a matlab
window and pop that into a Java frame, but when you do that
it produces a whole load of errors because of the
unexpected moving of the container, I think (something like
that. I've not looked at this in detail). I suppose one
would have to clone the container or something, but of
course you can't clone a JPanel. Anyway, for now my MDI
uses JFreeChart objects created from Matlab for the
plotting, which is frustrating but it works.

Anyway, very good to see this thread.
Cheers,
arwel

Subject: Profiling Java in Matlab

From: Malcolm Lidierth

Date: 12 Nov, 2007 18:47:06

Message: 7 of 9

I vote with Yair. I use swing components extensively for my
GUIs. They are more extensive, controllable, flexible and a
lot more attractive than the MATLAB GUIs. They also produce
more consistent results across platforms.

I have not seen the exceptions Yair comments on in R2007B
but saw something similar in its pre-release. The fix from
TMW support then was
"To prevent these warning messages from appearing, you may
create a java.opts file in the $MATLAB/bin/$ARCH
(Where $MATLAB is your root MATLAB directory and $ARCH is
your architecture.)
or in the current directory when you start MATLAB,
containing the following command:
-Dmathworks.WarnIfWrongThread=false"

Subject: Profiling Java in Matlab

From: Arwel Hughes

Date: 16 Nov, 2007 12:05:25

Message: 8 of 9

"Michael Bushe" <michael.bushe-removeme@mathworks.com>
wrote in message <fgaj1g$imo$1@fred.mathworks.com>...
> "Wolfgang Ulmer" <spam@wulmer.de> wrote in message
> <feg3vs$6ha$1@fred.mathworks.com>...
> > Hi Michael,
> >
> > while using Swing with Java, I discovered the same
problem
> > which is due to the fact, that Matlab uses the AWT/Swing
> > Event Handling Thread to do some computation.
> >
> > You can even easily create a deadlock if you enter the
> > following commands on the prompt:
> > >> import com.mathworks.jmi.*;
> > >> matlab = Matlab;
> > >> matlab.eval('1+1');
> >
> > I think, that one solution is not to use the java event
> > mechanisms but the Matlab methods for defining callback
> > routines.
> >
> > Example:
> >
> > button = JButton('Close');
> > set
(button,'ActionPerformedCallback',@buttonClosePressed);
> >
> > function buttonClosePressed(handle,event)
> > doSomething();
> > end
> >
> > -------------
> >
> > See http://xtargets.com/snippets/tag/java for details
and
> > further examples.
> >
> > Don't expect Mathworks to answer your question... they
do
> > not support Java GUI-Matlab interaction.
> >
> > Wolfgang
>
>
> Wolfgang's example will do most of what you want, and he
is
> right - you need to use MATLAB-provided APIs for accessing
> Swing Events. It is not correct, however, that MATLAB
does
> computation on the AWT/Swing thread, this would lock up
> GUIs. Also, using jmi classes is not a good idea. They
are
> not public or supported and it's easy to use them
improperly
> (even for developers inside the MathWorks). Lastly, there
> is a memory leak in the example, the workaround is
detailed
> below, but first, let's discuss Swing threading.
>
> The Swing threading problem is not specific to MATLAB. In
> pure Java if you write the following innocent looking
code,
> it is erroneous:
>
> package example;
>
> import javax.swing.*;
>
> public class SwingApp {
> JFrame frame = new JFrame();
> JButton button = new JButton("Do Something");
>
> public void showFrame() {
> frame.getContentPane().add(getButton());
> frame.setDefaultCloseOperation
(JFrame.DISPOSE_ON_CLOSE);
> frame.pack();
> frame.setVisible(true);
> }
>
> public JButton getButton() {
> return button;
> }
>
> public static void main(String args[]) {
> //Wrong! Swing object construction not on the
> EventDispatchThread
> SwingApp app = new SwingApp();
> //Wrong! Swing component access not on the
> EventDispatchThread
> app.showFrame();
> }
> }
>
> The problem is that the class is making Swing calls on
> Java's main thread. Sun asks developers to follow the
rule
> that all access to Swing components must occur on Swing's
> EventDispatchThread (there may be some leeway, but it's
best
> to always follow the rule). This may look like it works
> fine, but every so often you'll encounter lock ups and
> strange behavior like listeners not firing.
>
> This rule is broken when calling Swing components from the
> MATLAB command line in the same manner since Swing calls
are
> being made from the MATLAB thread:
>
> >> javaaddpath c:\myapp\classes
> >> app = example.SwingApp; % Wrong! Swing object
> construction not on the EventDispatchThread
> >> app.showFrame(); % Wrong! Swing component access not on
> the EventDispatchThread
>
> In pure Java, the right way to write this code is to wrap
> all Swing calls in a Runnable that is later called on the
> EventDispatchThread:
>
> public static void main(String args[]) {
> SwingUtilities.invokeLater(new Runnable() {
> public void run() {
> SwingApp app = new SwingApp();
> app.showFrame();
> }
> });
> }
>
> How can you do the same from MATLAB? There are additional
> undocumented APIs that you can use to avoid Java Swing
> threading issues, specifically awtcreate, awtinvoke and
> javacomponent. These APIs are not yet final and are
> therefore undocumented and can change in future releases.
> Please don’t expect this to be the best way to work with
> Swing Components going forward as we are planning to
change
> these APIs. We appreciate any feedback you can give us to
> help us deliver APIs that meet your needs.
>
> The functions awtcreate and awtinvoke both ship
undocumented
> – open the M-file for example usage. They both ensure
that
> the work for the M command that interacts with the Java
> component happens on Java's EventDispathThread and not
> MATLAB's main thread.
>
> For the SwingApp, you can ensure the calls are pushed onto
> the EventDispatchThread by using awtcreate and awtinvoke
> like so:
>
> >> app = awtcreate('example.SwingApp');
> >> awtinvoke(app, 'showFrame');
>
> The undocumented awtcreate and awtinvoke commands are like
> wrapping each M line in a SwingUtiities.invokeLater call.
> Though unsupported now, it works well.
>
> If you are writing your own Java classes, you may want to
> consider not using awtcreate and awtinvoke and push
> Swing-related Java code to your own classes. This will
make
> for better performance since it is one push to Swing's
> EventDispatchThread, not many.
>
> For example, you could run the example SwingApp above with
> the main() corrected to use SwingUtilities.invokeLater,
> directly from M:
>
> >> example.SwingApp.main('')
>
> Since the class's main() method calls invokeLater, this is
> safe.
>
> Rewriting your original example using awtcreate and
> awtinvoke would look like this:
>
> button = awtcreate('javax.swing.JButton');
> awtinvoke(button,'setLabel','Close');
>
> % make the button a handle object before calling set
> button = handle(button,'callbackproperties');
> set(button,'ActionPerformedCallback',@buttonClosePressed);
> javacomponent(button)
>
> In addition to the awtcreate and awtinvoke usage, there
are
> two other things to notice about the rewritten example:
> 1) It's better to use the "handle" command before calling
> "set" (this will prevent a memory leak).
> 2) The javacomponent command, also undocumented, puts any
> Java Swing component in a figure window – open the M-file
> for example usage.
>
> This is tricky stuff especially since the threading issues
> are not immediately apparent. We are interested in
> providing the best Java GUI experience we can in MATLAB.
> Any feedback is greatly appreciated.
>
>



Michael,
I tried playing around with the example, and couldn't get
it to work by calling the 'main' method as you suggest. It
runs, but the callback doesn't seem to respond.

So, if I have the 'public static void main..' in there, and
do this...

app = swingApp();
app.main('');
button = app.getButton();
buttonProps = handle(button,'callbackproperties');
set(buttonProps,'ActionPerformedCallback',@buttonPressed);

... the @buttonPressed callback doesn't get called on a
button press.

However, if I comment out the 'public static...main'
method, and call ShowFrame directly from Matlab like
this....

app = swingApp()
app.ShowFrame();
button = app.getButton();
buttonProps = handle(button,'callbackproperties');
set(buttonProps,'ActionPerformedCallback',@buttonPressed);

.. it works fine. Am I doing something wrong? The complete
codes of the example I'm trying are below, matlab first
(and yes, I know theres none of the threading bits in there
yet.)

-mTest.m

function mTest()
clear
javaaddpath c:\java\matlabthreads2\Main\build\classes

app = swingApp();
%app.main('');
app.ShowFrame();

button = app.getButton();
buttonProps = handle(button,'callbackproperties');
set(buttonProps,'ActionPerformedCallback',@buttonPressed);

disp('debug')



function buttonPressed(src,ev)
disp('Button Pressed Callback');





- swingApp.java

import javax.swing.*;
import java.awt.*;

public class swingApp {
        JFrame frame = new JFrame();
        JButton button1 = new JButton("Do Something");
        
    public void ShowFrame() {
        frame.getContentPane().add(getButton());
        frame.setDefaultCloseOperation
(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setSize(400,400);
        frame.setVisible(true);
    }
    
    
    public JButton getButton() {
        return button1;
    }
    
 /* public static void main(String[] args) {
        swingApp app = new swingApp();
        app.ShowFrame();
}*/
}

Subject: Profiling Java in Matlab

From: Michael Bushe

Date: 11 Dec, 2007 18:23:07

Message: 9 of 9

"Arwel Hughes" <a.v.hughes@rl.ac.uk> wrote in message
<fhk125$8rq$1@fred.mathworks.com>...

> Michael,
> I tried playing around with the example, and couldn't get
> it to work by calling the 'main' method as you suggest. It
> runs, but the callback doesn't seem to respond.
>
> So, if I have the 'public static void main..' in there, and
> do this...
>
> app = swingApp();
> app.main('');
> button = app.getButton();
> buttonProps = handle(button,'callbackproperties');
> set(buttonProps,'ActionPerformedCallback',@buttonPressed);
>
> ... the @buttonPressed callback doesn't get called on a
> button press.
>
> However, if I comment out the 'public static...main'
> method, and call ShowFrame directly from Matlab like
> this....
>
> app = swingApp()
> app.ShowFrame();
> button = app.getButton();
> buttonProps = handle(button,'callbackproperties');
> set(buttonProps,'ActionPerformedCallback',@buttonPressed);
>
> .. it works fine. Am I doing something wrong? The complete
> codes of the example I'm trying are below, matlab first
> (and yes, I know theres none of the threading bits in there
> yet.)
>
> -mTest.m
>
> function mTest()
> clear
> javaaddpath c:\java\matlabthreads2\Main\build\classes
>
> app = swingApp();
> %app.main('');
> app.ShowFrame();
>
> button = app.getButton();
> buttonProps = handle(button,'callbackproperties');
> set(buttonProps,'ActionPerformedCallback',@buttonPressed);
>
> disp('debug')
>
>
>
> function buttonPressed(src,ev)
> disp('Button Pressed Callback');
>
>
>
>
>
> - swingApp.java
>
> import javax.swing.*;
> import java.awt.*;
>
> public class swingApp {
> JFrame frame = new JFrame();
> JButton button1 = new JButton("Do Something");
>
> public void ShowFrame() {
> frame.getContentPane().add(getButton());
> frame.setDefaultCloseOperation
> (JFrame.DISPOSE_ON_CLOSE);
> frame.pack();
> frame.setSize(400,400);
> frame.setVisible(true);
> }
>
>
> public JButton getButton() {
> return button1;
> }
>
> /* public static void main(String[] args) {
> swingApp app = new swingApp();
> app.ShowFrame();
> }*/
> }
>
>
>

Sorry to take so long to get back to you.

The problem with calling main is that it causes a threading
problem. I said it was safe in my post, but it is not. See
this threading stuff is tricky! :-)

The reason why calling main is not thread-safe is that
MATLAB just calls main and returns. MATLAB does not know
that main() calls SwingUtilities. What is likely happening
is that the call to main() returns before the
EventDispatchThread can initialize and run the first event.
 This messes up the listener registration.

I recommend that you change your code to make it thread
safe. It looks like you can get away with what you are
doing, but a stitch in time saves nine.

Michael

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us