1 引言
以Matlab作为开发平台,进行数值计算,具有直接、高效的特点。
然而,在面向对象程序设计方面,现有的Matlab支持特性在开发和运行效率上并不高。
将Java语言面向对象及其平台特性引入Matlab,能够拓展其模型表达能力与手段。此外,Java本身的特性,也决定了其具有良好的开发性能。
与C语言编写mex动态链接库的开发目的不同(mex主要以速度见长),基于Java的matlab扩展能为matlab带来更大的灵活性。甚至于,Java平台下更多的类库,能够丰富matlab平台功能。
2 Java编译器的选择
测试平台:麒麟14.04 64bits
Matlab版本:13a
Java环境:Oracle sun jdk8 和 Gnu gcj
搜索了网络上的参考资料,其中,就Matlab中java静态和动态类搜索路径的设置阐述得多,但具体使用jdk8实验都没有成功——当加载自定义类的时候,matlab报错
<span style="color:#3333FF;">>> d = javaObject('Dog')</span> A Java exception occurred trying to load the Dog class: Java exception occurred: java.lang.UnsupportedClassVersionError: Dog : <span style="color:#FF0000;">Unsupported major.minor version 52.0</span> at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClassInternal(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at com.mathworks.jmi.OpaqueJavaInterface.findClass(OpaqueJavaInterface.java:470) Error using javaObject No class Dog can be located on the Java class path
分析,主要原因是Java版本过高,与Matlab所使用的Java版本不适应。
查看Matlab中的Java版本
>> version -java
ans =
Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) 64-Bit Server VM mixed mode
经javac -target 1.6 xxx.java测试,显示javac: 目标发行版 1.6 与默认的源发行版 1.8 冲突; 无法使用当前javac编译器产生Matlab需要版本的类。
鉴于一些帖子中提到使用GNU gcj编译器,故安装该编译器测试:
安装方法为:
sudo apt-get install gcj-jdk
安装后gcj-jdk版本为4.8
3 使用gcj-jdk编译Java类
3.1 测试代码Dog.java
class Dog { private String name; private Integer count; public Dog() { name = null; count = 0; } public Dog(String aname) { count = 0; name = aname; } public String getName() { count++; return name + "_" + count.toString(); } public void setName(String newName) { name = newName; } public static void main(String[] args) { Dog d = new Dog("martin chen"); System.out.println(d.getName()); } }
为便于调试和在Matlab中测试,没有使用package。
3.2 代码编译
gcj -C Dog.java
产生了Dog.class
压缩Dog.class到Dog.jar,为了简化操作,不写manifest.mf文件,直接压缩
jar cvf Dog.jar Dog.class
3.3 Matlab中Java类搜索路径设置
1) 查看Matlab中现有的类路径命令,可以看到其内置可加载的Java类以及动态类加载信息
javaclasspath
信息如下:
>> javaclasspath STATIC JAVA PATH /usr/local/MATLAB/R2013a/java/patch /usr/local/MATLAB/R2013a/java/jarext/jaxen.jar /usr/local/MATLAB/R2013a/java/jarext/xstream.jar 省略... /usr/local/MATLAB/R2013a/java/jarext/commons-io.jar /usr/local/MATLAB/R2013a/java/jar/toolbox/dastudio.jar /usr/local/MATLAB/R2013a/java/jarext/freehep-util.jar /usr/local/MATLAB/R2013a/java/jarext/RXTXcomm.jar /usr/local/MATLAB/R2013a/java/jar/instutil.jar /usr/local/MATLAB/R2013a/java/jar/toolbox/instrument.jar /usr/local/MATLAB/R2013a/java/jarext/openxml4j.jar DYNAMIC JAVA PATH <empty>
2) 在Matlab中查看静态路径存储文件的位置
which classpath.txt
结果:
/usr/local/MATLAB/R2013a/toolbox/local/classpath.txt
3) 编辑该classpath.txt,添加Dog.jar到静态路径中
sudo gedit /usr/local/MATLAB/R2013a/toolbox/local/classpath.txt
在文件尾添加
/home/your_username/matlab_java/Dog.jar
4) 在Matlab中测试Dog
>> d1 = javaObject('Dog', 'martin') d1 = [email protected] >> d1.setName('程序') >> d1.getName() ans = 程序_1 >> d1.getName() ans = 程序_2 >> d1.getName() ans = 程序_3 >> d2 = javaObject('Dog') d2 = [email protected] >> d2.getName() ans = null_1
说明:d1和d2创建时,分别调用了Dog的两种构造函数。
测试结果表明,Java类被正确加载和调用了。
5)在Matlab中动态加载类并调用它
开发过程中,由于需要不断修改代码,故调试期间,可采用动态加载方式,加载用户自定义类。
重新编辑classpath.txt文件,去除Dog.jar的加载信息。
在Matlab中运行以下命令:
>> javaaddpath('/home/your_username/documents/matlab_java/Dog.jar') >> d = javaObject('Dog', 'martin') d = [email protected] >> d.getName() ans = martin_1
实验结果也说明Dog被正确加载和调用。
6) 查看Dog类的可用方法
>> methods Dog Methods for class Dog: Dog getClass hashCode notify setName wait equals getName main notifyAll toString
Ok,经过上述实验,大家终于可以放心和自由地在Matlab中使用Java了。