MATLAB配置为在搜索用户可修改的动态路径之前搜索其静态java类路径。不幸的是,静态路径包含相当多的非常旧的公共库,因此如果您尝试使用新版本,最终可能会加载错误的实现并获得错误。
例如,静态路径包含google-collections.jar的旧副本,该副本长期以来被Google的guava库取代,并且具有一些相同的类名(例如com.google.common.base.Objects)。因此,如果你调用一个使用这种类之一的新方法的Guava方法,你最终会得到令人惊讶的NoSuchMethodErrors,因为首先找到了google-collections jar。
从R2012b开始,MATLAB允许您通过在首选项文件夹中放置javaclasspath.txt文件来指定要添加到静态路径的其他jar,但是将jar添加到路径的末尾,并且不允许您覆盖生成的jar进入MATLAB。
那么最好的解决方法是什么?
我收到了Mathworks的正式回复:
从MATLAB R2013a(也在R2012b中)开始,通过在javaclasspath.txt中包含以下行,可以将类添加到静态Java类路径的前面:
<before>
javaclasspath.txt中此行之后的任何目录都将添加到静态Java类路径的前面。从R2013a开始,这是对javaclasspath.txt的未记录使用。
但总体而言,在MATLAB中,通过MATLAB 8.0(R2012b)中的javaclasspath.txt无法将类添加到静态Java类路径的前端。
MATLAB按以下顺序搜索classpath.txt:
虽然最终用户通常不使用第2点的MATLABPATH环境变量,但我们可以在变通方法中使用它来允许读取工具箱/本地目录之外的自定义classpath.txt。
在Windows上:
您需要创建MATLABPATH环境变量。它上面的第一个目录应该是你的自定义classpath.txt的目录。你还需要添加toolbox \ local目录作为第二个选项。所以从cmd提示符你可以做到:
设置MATLABPATH = c:\ Users \ user \ Documents \ myMATLABClasspath; c:\ Program Files \ MATLAB \ R2012b \ toolbox \ local matlab.exe
一个似乎有用的黑客是将jar添加到classpath.txt文件的顶部,该文件可以在MATLAB安装工具箱/本地文件夹中找到。不幸的是,这是自动生成的,并且可能会在某些未指定的时间重写,例如当您安装新的工具箱时,因此这种方法需要您在发生这种情况时需要注意并重新应用黑客。
如果您正在分发一个打算与matlab一起使用的jar,那么最好使用http://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava中描述的proguard。
如果指定要保留所有类及其(公共)字段和方法并将guava包含为程序jar(而不是库),则它将重命名所有guava的方法并更新已编译的字节码以引用新的名。
它看起来有点像hackish,但是根据受众的不同,它可能比教你的用户关于静态和动态类路径要容易得多,并且它不会破坏任何依赖于旧行为的matlab代码。
我没有按照@ user2443532的建议对包进行模糊处理,而是发现更容易“遮蔽”冲突的包而不是混淆包 - 除非你真的需要混淆。一个简单的方法是使用Maven构建包并使用maven-shade-plugin
。内部调用会自动修改,因此您无需修改任何Java代码。
需要修改Matlab的直接调用 - 例如,调用com.opensource.Class
成为shaded.com.opensource.Class
。
有关着色的更多信息,请参阅What is the maven-shade-plugin used for, and why would you want to relocate Java packages?