Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

Java class access pitfalls

July 2, 2014 8 Comments

A few days ago I consulted to a company that wanted to integrate some of their Java code in Matlab. The Java code compiled ok and ran just fine in the Java environment, but when we wanted to use the relevant Java classes in Matlab we got all sorts of errors. Since I believe that this could be a common problem, and I’m not sure that there’s any other place that does this, I thought to list the possible error causes in today’s article:

  1. Forgetting or mistyping the package name:
    >> jObject = JButton('Click me!');  % missing package name
    Undefined function 'JButton' for input arguments of type 'char'.
    >> jObject = java.swing.JButton('Click me!');  % should be javax.swing...
    Undefined variable "java" or class "java.swing.JButton". 
    >> jObject = javax.Swing.JButton('Click me!');  % should be javax.swing...
    Undefined variable "java" or class "javax.Swing.JButton". 
    >> import java.swing.*  % should be javax.swing... - no error here, only in the next line
    >> jObject = JButton('Click me!');   % missing package name
    Undefined function 'JButton' for input arguments of type 'char'.
    >> import java.swing.JButton  % should be javax.swing...
    Error using import
    Import argument 'java.swing.JButton' cannot be found or cannot be imported.
    

    Note: package names are typically lowercase, but 3rd-party packages might not follow this convention! Since Java is case-sensitive, the package name must be exact.

  1. Mistyping the class name. As with package names, Java class names are also case-sensitive. Beware of cases of O/0 (capital-“o” vs. the digit zero), and I/l/1 (capital-“i” vs. lowercase “L” vs. the digit 1). Also note whether the class name includes the underscore (“_”) character.
     
  2. Using a Java class that was compiled using a newer JDK major-version than the JVM used in Matlab. The specific JVM used by Matlab varies across platforms and Matlab releases. On R2014a Win64, the default (pre-installed) version is 1.7, which means that classes compiled using (or targeting) JDK 7 or below are ok, but classes compiled using JDK 8 or above would simply not run:
    >> a = MyJavaClass;
    Undefined function or variable 'MyJavaClass'.
    >> a = my.java.Class;
    Undefined variable "my" or class "my.java.Class".
    

    To get Matlab’s current JVM version, use the version command:

    >> version -java
    ans =
    Java 1.7.0_11-b21 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
    

    The default JVM used in Matlab R14 (7.0) to R2013a (8.1) was 1.6 (=JDK 6); R2013b (8.2) and later use 1.7 (=JDK 7). If you wish to ensure compatibility with earlier Matlab releases, I suggest compiling using JDK 6 rather than 7 or 8. This can easily be modified in all Java IDEs, in the project’s preferences. Remember to reference the corresponding JRE 1.6 libraries as well, rather than the newer JRE ones. In many cases, the Java code would still compile and run properly, even when compiled using the earlier JDK/JRE.
    If downgrading the compilation JDK is not possible (for example, if you do not have access to the source code, or if it uses some new JDK features), then consider installing a newer compatible JVM in Matlab.
    Note that when we try running the Java classes using the java executable (outside Matlab), we do get a meaningful message about the fact that the classes were compiled for a higher JVM version. Unfortunately, this information is simply not being provided by Matlab – just the standard plain error about the function or file not being found. I hope this will be fixed in some future Matlab release.

  3. Forgetting to update the Java classpath. Java has a different classpath than Matlab’s. Class or JAR files placed on Matlab’s path are not recognized. Instead, these files need to be added to the Java classpath, either dynamically within the Matlab session (using the javaaddpath function), or statically (by adding entries to the classpath.txt or javaclasspath.txt files, or using these undocumented hacks). Read here for additional details. Note that the javaclasspath.txt alternative only exists since R2012b (8.0). You can view the current Java classpath in Matlab using the javaclasspath command.
     
    When updating the Java classpath, either dynamically or statically, beware of the following pitfalls:

    • If you add a folder name to the javaclasspath, then all *.class files are automatically recognized and they will be loaded when first used. However, this does NOT include *.jar or *.zip files placed in these folders. The Java specification requires such files to be added individually to the classpath, using their full pathname.
    • While we can use relative paths when adding elements dynamically (using javaaddpath), we must specify the full pathname when updating the static classpath files.

     

  4. Dependency #1: A class that depends on any other class that is not on the current Java classpath (either dynamic or static). This is typically due to the fact that the class was compiled in a Java IDE where there were multiple referenced libraries, which were not copied to the Matlab classpath. It is not enough to simply place the generated output *.class or *.jar files in Matlab’s Java classpath – the referenced libs must also be placed there. If they are not, then Matlab simply issues the generic error that the function or class cannot be found. Matlab provides no information that this is a dependency error and we must infer this ourselves. Note that it does not matter that the non-existent class might referenced in an obscure portion of the class code that is never reached – the mere fact that there is a reference in the class that cannot be located causes the entire class to fail to load. Debugging this can indeed be nerve wrecking (and another example)… I hope that this too will be fixed in some future Matlab release.
     
  5. Dependency #2: A class on the static Java classpath that depends on another class which is on the dynamic Java classpath. All static classes must depend only on other static classes, since the static classpath is processed before the dynamic one, when the JVM is launched at Matlab startup.
     
  6. Non-public class – Matlab can only access public classes. If the class is private, protected or has package visibility (by not specifying any visibility modifier at all), then the class would not be loadable by Matlab, only by other Java classes. So remember to add the public keyword in the definition of all the Java classes that you wish to directly use in Matlab.
     
  7. Non-public constructor – Matlab can only create objects for non-static classes that have public constructors. If all the class constructors are non-public, then Matlab cannot create a class instance object. In such a case we would get a misleading error message, that at least hints that the problem is with the constructor:
    >> jObject = MyJavaClass();
    No constructor 'MyJavaClass' with matching signature found.
    

    Note that using private constructors is common practice for singleton designs. In such cases we might find a public static class method that returns the class reference (e.g., MyJavaClass.getInstance()).

  8. Non-matching constructor – This is a variation of the previous pitfall. In this case, we try to invoke a class constructor with input parameters that do not match the declaration. A typical example of this is when the constructor is declared to accept an int, and we try to pass a standard Matlab number (which is a double). In such cases, a simple solution could be to either modify the class, overloading the constructor to also accept double, or to type-cast the inputs in Matlab to the relevant type expected by a constructor:
    jObject = MyJavaClass(int32(value));

    jObject = MyJavaClass(int32(value));

  9. Not enough PermGen space – PermGen is the memory area where Java stores the code for its loaded classes. The more classes you load, and the more complex they are, the larger the required PermGen. By default Matlab allocates a relatively small amount of memory to PermGen (32MB for the initial space, with a maximum of 64MB or 128MB – this may change across releases and platforms; see here for various ways to diagnose your specific installation). If you load additional Java classes, you may well run out of PermGen space, even if you increase the total amount of Java heap memory in Matlab’s preferences:
    >> jObject = MyJavaClass();
    Java exception occurred:
    java.lang.OutOfMemoryError: PermGen space
    

    The solution in this case is to create a java.opts file in Matlab’s startup folder, that contains a higher specification of the maximal allowed PermGen space. The java.opts file is a simple text file that is automatically loaded by Matlab when it starts its internal Java engine. For example, to set the initial PermGen space to 64MB and the maximal PermGen space to 256MB, include the following lines in java.opts:

    -XX:PermSize=64m
    -XX:MaxPermSize=256m

    -XX:PermSize=64m -XX:MaxPermSize=256m

    An alternative solution that might help in some cases is to load the new classes on Matlab’s static Java classpath, rather than on the dynamic classpath (see item #4 above).

Any other pitfalls I forgot to mention? Let us know in a comment below.
p.s. – the javaclasspath function has an undocumented input parameter: specifying -v0, -v1 or -v2 sets the Java classloader’s verbosity level to the relevant value. If you don’t know what this means, then you probably don’t need to use this feature…

Related posts:

  1. Accessing internal Java class members – Java inner classes and enumerations can be used in Matlab with a bit of tweaking. ...
  2. Extending a Java class with UDD – Java classes can easily be extended in Matlab, using pure Matlab code. ...
  3. Static Java classpath hacks – Several hacks that facilitate using the static Java classpath in Matlab are explained. ...
  4. Matlab callbacks for Java events in R2014a – R2014a changed the way in which Java objects expose events as Matlab callbacks. ...
  5. Matlab callbacks for Java events – Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...
  6. Creating a simple UDD class – This article explains how to create and test custom UDD packages, classes and objects...
Java Undocumented feature
Print Print
« Previous
Next »
8 Responses
  1. waldroje21 May 1, 2015 at 08:22 Reply

    Any idea why a Matlab would recognize a Java class file from the Dynamic path, but not the Static? I’ve added it to my Static path, and it’s in there… but does not work… when I then add the same path using javaaddpath , it works.

    • Yair Altman May 1, 2015 at 08:26 Reply

      Perhaps one or more of the following happened:

      * you edited the wrong classpath.txt file
      * you forgot to restart Matlab after editing the classpath.txt file
      * you mistyped the class’s full path in the file
      * you used a relative path in the file

      • waldroje21 May 1, 2015 at 13:21

        in regard to the first… it shows up on the bottom when I type javaclasspath in the workspace, so I assume it can’t be the wrong file, and that path is what i get when i type prefdir… I definitely restarted Matlab…. and I’m using the same exact file string in the Dynamic path, that I use in the javaclasspath.txt, i just copied it straight from terminal. I’ve done this with no problem on 3 other installs, so it’s a bit strange.

      • Yair Altman May 2, 2015 at 10:18

        If you wish me to help you debug your specific installation, contact me by mail for a private consulting.

  2. Vincent March 16, 2016 at 20:38 Reply

    How about what to do when you get a “java.lang.NoSuchFieldError” because your java code uses a version of Apache’s httpcore that is newer than the one matlab ships with, and the old one seems to be creating conflicts with the newer one you’ve added to your java path?

    • Malcolm Lidierth March 16, 2016 at 22:26 Reply

      The class loader will only load one copy of a specific package/class combination. A newer version will not replace the older one even if you have called javaaddpath (hence the NoSuchFieldError which implies you have created an instance using the old code). This is a Java class loader feature: if you load a jar that has dependencies on other jars (e.g. in a /dist/lib folder), and some of those jars are already loaded, the already loaded versions will continue to be used.

      In general, open source projects with the Apache brand will maintain backwards compatibility – deprecating, but not removing, old fields/methods. If backwards compatibility is not maintained Apache projects will usually alter the package names so both versions can be used simultaneously. This being the case, replacing the jar file shipped with MATLAB with the newer version should produce no problems. But, anyone else using your code will need to do that too. Buyer beware.

  3. Amaury Vanvinckenroye October 19, 2016 at 14:26 Reply

    Hi, I’m using some Java classes in a Matlab code and it seems that a specific java class is not loaded, but only at the first run (i.e. at the start of Matlab). Later calls to the java function don’t give any error, even if I “clear all; clear classes; clear java”. Here’s the part of code failing at first run.

    javaaddpath(Obj.MongoDBPath)
    import java.util.ArrayList;
    import java.lang.String;
    import com.mongodb.*;
     
    credentialsList = ArrayList();
    credentials = MongoCredential.createCredential(Username, 'admin' , password);
    credentialsList.add(credentials);
    mongoClient = MongoClient(ServerAddress(IP,Port), credentialsList);

    javaaddpath(Obj.MongoDBPath) import java.util.ArrayList; import java.lang.String; import com.mongodb.*; credentialsList = ArrayList(); credentials = MongoCredential.createCredential(Username, 'admin' , password); credentialsList.add(credentials); mongoClient = MongoClient(ServerAddress(IP,Port), credentialsList);

    The failing java class is ServerAdress and is part of the mongodb package.
    Other java classes run fine immediately.
    This error doesn’t occur on all computers, so I’m giving you my specs.
    Windows 10 (previously windows 8), Matlab R2013a with Java 1.6.0_17-b04 (also tried with Java 1.8.0_25-b18 when adding it as environment variable).
    It worked on a Mac with Matlab R2015b with Java 1.7, but also failed on another Mac with Matlab R2014a and java 1.8.
    Thanks in advance

    • Yair Altman October 20, 2016 at 20:29 Reply

      @Amaury – this seems to be something specific to the MongoClient class. You should probably ask about this in the MongoDB forums.

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
ActiveX (6) AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
  • Nicholas (7 days 1 hour ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Nicholas (7 days 1 hour ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Yair Altman (7 days 8 hours ago): Nicholas – yes, I used it in a compiled Windows app using R2022b (no update). You didn’t specify the Matlab code location that threw the error so I can’t help...
  • Nicholas (8 days 4 hours ago): Hi Yair, Have you attempted your displayWebPage utility (or the LightweightHelpPanel in general) within a compiled application? It appears to fail in apps derived from both R2022b...
  • João Neves (11 days 9 hours ago): I am on matlab 2021a, this still works: url = struct(struct(struct(struct(hF ig).Controller).PlatformHost). CEF).URL; but the html document is empty. Is there still a way to do...
  • Yair Altman (14 days 8 hours ago): Perhaps the class() function could assist you. Or maybe just wrap different access methods in a try-catch so that if one method fails you could access the data using another...
  • Jeroen Boschma (14 days 10 hours ago): Never mind, the new UI components have an HTML panel available. Works for me…
  • Alexandre (14 days 11 hours ago): Hi, Is there a way to test if data dictionnatry entry are signal, simulink parameters, variables … I need to access their value, but the access method depends on the data...
  • Nicholas (15 days 2 hours ago): In case anyone is looking for more info on the toolbar: I ran into some problems creating a toolbar with the lightweight panel. Previously, the Browser Panel had an addToolbar...
  • Jeroen Boschma (18 days 9 hours ago): I do not seem to get the scrollbars (horizontal…) working in Matlab 2020b. Snippets of init-code (all based on Yair’s snippets on this site) handles.text_explorer...
  • Yair Altman (46 days 11 hours ago): m_map is a mapping tool, not even created by MathWorks and not part of the basic Matlab system. I have no idea why you think that the customizations to the builtin bar function...
  • chengji chen (46 days 17 hours ago): Hi, I have tried the method, but it didn’t work. I plot figure by m_map toolbox, the xticklabel will add to the yticklabel at the left-down corner, so I want to move down...
  • Yair Altman (54 days 10 hours ago): @Alexander – this is correct. Matlab stopped including sqlite4java in R2021b (it was still included in 21a). You can download the open-source sqlite4java project from...
  • Alexander Eder (60 days 6 hours ago): Unfortunately Matlab stopped shipping sqlite4java starting with R2021(b?)
  • K (66 days 17 hours ago): Is there a way to programmatically manage which figure gets placed where? Let’s say I have 5 figures docked, and I split it into 2 x 1, I want to place 3 specific figures on the...
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top