如何让mcc
识别来自用户提供的Java库的导入,或者简单地忽略无法解决的导入?
我有一个使用Matlab编译器构建的Matlab代码库,但由于mcc
遇到Java类的import
语句时出错,该语句位于Matlab的动态类路径上的JAR中,因此构建正在中断。我使用mcc -a
选项将所有JAR文件包含在类路径中。代码在IDE中工作,我认为它会在部署的应用程序中工作,如果它只允许我构建的话。(在R2009b下工作,它忽略了非MCOS类中的这些导入。)
这里有一个简单的反驳。该文件与Google guava的guava-11.0.1.jar位于同一目录中。
%file hello_world_with_import.m
function hello_world_with_import
import com.google.common.base.Stopwatch;
disp('Hello, world!');
end
在Matlab中运行它效果很好。但建造它失败了。(这里的javaaddpath
在这个例子中并不是绝对必要的,因为糟糕的导入本身在普通的Matlab中并不是一个错误。只是展示了它在实践中的工作方式,以及我希望mcc
如何利用它。)
>> javaaddpath('guava-11.0.1.jar');
>> hello_world_with_import()
Hello, world!
>> mcc -m -a guava-11.0.1.jar hello_world_with_import
Error: File: C:Tempimport_testhello_world_with_import.m Line: 3 Column: 8
Arguments to IMPORT must either end with ".*"
or else specify a fully qualified class name: "com.google.common.base.Stopwatch" fails this test.
Unable to determine function name or input/output argument count for function
in MATLAB file "hello_world_with_import".
Please use MLINT to determine if this file contains errors.
Error using mcc
Error executing mcc, return status = 1 (0x1).
这是在Windows上的Matlab R2011b中。
我的一些环境背景。我的应用程序在动态类路径上有大约40个JAR,它们是第三方库和我们自己的Java代码的混合体。它在单用户和多用户Windows机器上部署到50多个用户。还有其他小组可能正在向相同的用户和机器部署其他MCR应用程序。在任何机器上,不同的MCR应用程序可能由相同或不同的用户同时运行。我们每周发布一次,(主要是由于我们自己的Java代码发生了更改)每隔一次发布,至少会有一个JAR文件发生更改。我需要一个能在这种环境下工作的机制。
有什么建议吗?有人知道让mcc
在编译步骤中向其java类路径添加内容的好方法吗?或者忽略伪导入?我的后备计划是遍历代码库并删除Java类的所有导入,这有点痛苦。
2012年2月12日更新:我从MathWorks那里听说这是在Matlab R2012b中修复的。(但我不再使用Matlab,所以无法亲自验证。)
2014年9月12日更新:我再次使用Matlab(R2014b),Matlab编译器现在包含了位于编译程序动态类路径中动态类路径上的JAR。不过,它似乎不会自动将JAR文件包括在归档中;您必须使用mcc
命令行开关手动包含它们,或者将它们作为"附加包含文件"添加到Matlab编译器应用程序中。
在MATLAB IDE中执行的代码之所以有效,是因为番石榴jar文件已通过javaaddpath方法添加到"动态"类路径中。但是,当您使用MCC调用MATLAB编译器时,它不依赖于动态java类路径,而是依赖于在中定义的"静态"java类路径
$MATLABROOT/toolbox/local/classpath.txt
如果您在这里为JAR文件添加一个条目,那么MCC将能够解析M-file中的IMPORT行。
因此为了测试这一点,我下载了番石榴jar文件并尝试了上面的步骤。工作起来很有魅力
此外,如果您阅读了MATLAB编译器的"故障排除"部分,则会记录以下确切情况:
http://www.mathworks.com/help/toolbox/compiler/brtm1xm-8.html
引用链接中的话:"import语句引用了MATLAB编译器(如果错误发生在编译时)或MCR(如果错误出现在运行时)找不到的Java类()。
要解决此问题,请确保包含Java类的JAR文件存储在Java类路径上的文件夹中。(类路径请参见matlabroot/toolbox/local/classpath.txt。)如果在运行时发生错误,则在开发机器上运行时,类路径存储在matlabroot/toolbox/local/classpathtxt中。"
您只需要将导入语句放在一个单独的.m文件中。
因此来自:
javaaddpath 'c:some.jar';
import com.something.Element;
...interesting stuff...
将有一个do_imports.m:
import com.something.Element;
并且在原始.m:中
javaaddpath 'c:some.jar';
do_imports
...interesting stuff...
然后它将编译并工作。无需在系统范围内使用classpath。
以下是链接的摘录http://blogs.mathworks.com/desktop/2009/07/06/calling-java-from-matlab/
MATLAB为Java类维护了一个独立于搜索路径的路径。这意味着,即使MATLAB路径上有.class或.jar文件,除非使用javaaddpath,否则您将无法使用它。要查看路径上当前的内容,请使用javaclasspath。运行此命令,您将向您显示一长串matlab附带的文件,称为静态类路径,然后您将看到动态类路径。动态类路径是用javaaddpath添加到路径中的类将被放置的位置。它们可以用javarmpath删除,并且必须主动重新加载matlab的每个会话。