2

如何mcc识别来自用户提供的 Java 库的导入,或者简单地忽略无法解析的导入?

我有一个使用 Matlab 编译器构建的 Matlab 代码库,但是构建正在中断,因为mcc当它遇到import在 Matlab 的动态类路径上的 JAR 中的 Java 类的语句时出错。我在类路径中包含所有 JAR 文件和mcc -a选项。该代码在 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:\Temp\import_test\hello_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 年 12 月 2 日更新:我从 MathWorks 听说这已在 Matlab R2012b 中修复。(但我不再使用 Matlab,所以无法亲自验证。)

更新 12/09/2014:我再次使用 Matlab (R2014b),Matlab 编译器现在包括已编译程序的动态类路径中动态类路径上的 JAR。不过,它似乎不会自动将 JAR 文件包含在存档中。您必须使用mcc命令行开关手动包含它们,或者在 Matlab 编译器应用程序中将它们添加为“附加包含的文件”。

4

3 回答 3

4

在 MATLAB IDE 中执行的代码有效,因为 guava jar 文件已通过 javaaddpath 方法添加到“动态”类路径中。但是,当您使用 MCC 调用 MATLAB 编译器时,它不依赖于动态 java 类路径,而是定义在以下位置的“静态”java 类路径:

$MATLABROOT/toolbox/local/classpath.txt

如果您在此处为您的 JAR 文件添加一个条目,那么 MCC 将能够解析您的 M-File 中的 IMPORT 行。

因此,为了测试这一点,我下载了 guava jar 文件并尝试了上述步骤。奇迹般有效。

此外,如果您阅读了 MATLAB 编译器的“疑难解答”部分,则会记录这种确切情况:

http://www.mathworks.com/help/toolbox/compiler/brtm1xm-8.html

从链接中引用:“导入语句引用了 MATLAB 编译器(如果错误发生在编译时)或 MCR(如果错误发生在运行时)找不到的 Java 类 ()。

要解决此问题,请确保包含 Java 类的 JAR 文件存储在 Java 类路径上的文件夹中。(类路径见matlabroot/toolbox/local/classpath.txt。)如果运行时出错,在开发机上运行时类路径存储在matlabroot/toolbox/local/classpath.txt中。

于 2012-02-10T02:39:43.900 回答
2

您只需将导入语句放在单独的 .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...

然后它将编译并工作。无需弄乱系统范围的类路径。

于 2012-10-24T10:26:55.823 回答
-1

这是链接http://blogs.mathworks.com/desktop/2009/07/06/calling-java-from-matlab/的摘录

MATLAB 为 Java 类维护一个独立于搜索路径的路径。这意味着即使您在 MATLAB 路径上有一个 .class 或 .jar 文件,除非您使用 javaaddpath,否则您将无法使用它。要查看当前路径上的内容,请使用 javaclasspath。运行此命令,您将向您显示 matlab 附带的一长串文件,称为静态类路径,然后您将看到动态类路径。动态类路径是放置使用 javaaddpath 添加到路径的类的位置。它们可以用 javarmpath 删除,并且必须主动重新加载 matlab 的每个会话。

于 2012-02-09T23:42:12.257 回答