从动态 Java 类路径导入 Java 类时出现 Matlab 编译器 MCC 错误

发布于 2025-01-04 00:21:52 字数 2018 浏览 4 评论 0原文

如何让 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:\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 编译器应用程序中的“附加包含文件”。

How can I get mcc to recognize imports from user-provided Java libraries, or to simply ignore unresolvable imports?

I have a Matlab codebase that I'm building with the Matlab Compiler, but the build is breaking because mcc is erroring out when it encounters import statements for Java classes that were in JARs on Matlab's dynamic classpath. I am including all the JAR files on the classpath with the mcc -a option. The code works in the IDE, and I think it will work in the deployed app, if it will only allow me to build. (Works under R2009b, which ignores these imports in non-MCOS classes.)

Here's a simple repro. This file is in the same dir as guava-11.0.1.jar from Google Guava.

%file hello_world_with_import.m
function hello_world_with_import
import com.google.common.base.Stopwatch;
disp('Hello, world!');
end

Running it in Matlab works fine. But building it fails. (The javaaddpath here is not strictly necessary in the example, because bad imports by themselves are not an error in plain Matlab. Just showing how it works in practice, and how I wish mcc picked up on it.)

>> 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).

This is in Matlab R2011b on Windows.


Some background on my environment. My app has about 40 JARs on the dynamic classpath which are a mix of third party libraries and our own Java code. It's deployed to 50+ users on a mix of single-user and multi-user Windows machines. And there are other groups that may be deploying other MCR apps to the same users and machines. On any machine, different MCR apps may be run concurrently by the same or different users. We do weekly releases, and (mostly due to changes in our own Java code) at least one JAR file changes about every other release. I need a mechanism that will work in this environment.


Any suggestions? Anybody know a good way to get mcc to add stuff to its java classpath in the compilation step, or just ignore bogus imports? My fallback plan is to go through the codebase and remove all the imports for Java classes, which is kind of a pain.


UPDATE 12/2/2012: I heard from MathWorks that this is fixed in Matlab R2012b. (But I'm no longer using Matlab so can't personally verify it.)

UPDATE 12/09/2014: I'm using Matlab again (R2014b), and the Matlab Compiler now includes JARs that are on the dynamic classpath in the compiled program's dynamic classpath. It doesn't seem to automatically include the JAR files in the archive, though; you must manually include them using an mcc command line switch, or adding them as "additional included files" in the Matlab Compiler app.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

辞慾 2025-01-11 00:21:52

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

$MATLABROOT/toolbox/local /classpath.txt

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

因此,为了测试这一点,我下载了番石榴 jar 文件并尝试了上述步骤。工作起来就像一个魅力。

此外,如果您阅读 MATLAB 编译器的“故障排除”部分,会记录这种确切情况:

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

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

要解决此问题,请确保 JAR包含 Java 类的文件存储在 Java 类路径上的文件夹中(有关类路径,请参阅 matlabroot/toolbox/local/classpath.txt。)如果在运行时发生错误,则类路径存储在在开发计算机上运行时的 matlabroot/toolbox/local/classpath.txt。”

The code executing in the MATLAB IDE works because the guava jar file has been added to the "dynamic" classpath via the javaaddpath method. However, when you use MCC to invoke the MATLAB Compiler, it does not rely on the dynamic java classpath, but the "static" java classpath which is defined in:

$MATLABROOT/toolbox/local/classpath.txt

If you add an entry for your JAR file here, then MCC will be able to resolve the IMPORT line in your M-File.

So to test this, I downloaded the guava jar file and tried the steps above. Works like a charm.

Also, If you read the "Troubleshooting" section for the MATLAB Compiler, this exact situation is documented:

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

Quoting from the link: "The import statement is referencing a Java class () that MATLAB Compiler (if the error occurs at compile time) or the MCR (if the error occurs at run time) cannot find.

To work around this, ensure that the JAR file that contains the Java class is stored in a folder that is on the Java class path. (See matlabroot/toolbox/local/classpath.txt for the class path.) If the error occurs at run time, the classpath is stored in matlabroot/toolbox/local/classpath.txt when running on the development machine."

挖鼻大婶 2025-01-11 00:21:52

您只需将 import 语句放在单独的 .m 文件中即可。

所以 from:

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...

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

You just have to put import statements in a separate .m file.

so from:

javaaddpath 'c:\some.jar';
import com.something.Element;
...interesting stuff...

There will be a do_imports.m:

import com.something.Element;

And in original .m:

javaaddpath 'c:\some.jar';
do_imports
...interesting stuff...

And then it will compile and work. No need to mess around with system-wide classpaths.

睫毛上残留的泪 2025-01-11 00:21:52

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

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

Here is an extract from the link
http://blogs.mathworks.com/desktop/2009/07/06/calling-java-from-matlab/

MATLAB maintains a path for Java classes separate from the search path. That means even if you have a .class or .jar file on the MATLAB path, unless you use javaaddpath you will not be able to use it. To see what is currently on the path use javaclasspath. Running this command you will show you a long list of files that ship with matlab called the Static Class Path and then you'll see the Dynamic Class Path. The dynamic class path is where classes added to the path with javaaddpath will be placed. They can be removed with javarmpath and have to actively reloaded each session of matlab.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文