2012-02-09 177 views
2

如何才能让mcc识别从用户提供的Java库导入,或简单地忽略无法解析的导入?Matlab编译器从动态Java类路径导入Java类时的MCC错误

我有一个使用Matlab编译器构建的Matlab代码库,但构建打破原因,因为mcc在遇到关于Matlab的动态类路径中的JAR中的Java类的import语句时出错。我将包含mcc -a选项的类路径中的所有JAR文件。该代码在IDE中工作,并且我认为它将在部署的应用程序中起作用,如果它只允许我构建的话。 (在R2009b下工作,忽略非MCOS类中的这些输入。)

下面是一个简单的repro。该文件与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类的所有导入,这很痛苦。


UPDATE 12/2/2012:我听说MathWorks已经在Matlab R2012b中修复了这个问题。 (但我不再使用Matlab所以不​​能亲自验证它。)

更新12/09/2014:我再次使用Matlab(R2014b),并且Matlab编译器现在包括JAR编译程序的动态类路径中的动态类路径。尽管如此,它似乎没有自动将JAR文件包含在档案中;您必须使用mcc命令行开关手动包含它们,或者在Matlab Compiler应用程序中将它们添加为“附加包含文件”。

回答

4

在MATLAB IDE中执行的代码的工作原理是,通过javaaddpath方法将guava jar文件添加到“动态”类路径中。然而,当您使用MCC调用Matlab编译器,它不依赖于动态Java类路径,但“静态” Java类路径这是在定义:

$ MATLABROOT /工具箱/本地/类路径。 txt

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

所以为了测试这个,我下载了番石榴jar文件并尝试了上面的步骤。奇迹般有效。

而且,如果你读了MATLAB编译的“疑难解答”部分,这个确切的情况进行了说明:

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

从链接引用:“import语句被引用的Java类( )MATLAB Compiler(如果错误发生在编译时)或MCR(如果错误发生在运行时)找不到

要解决此问题,请确保包含Java类的JAR文件存储在一个位于Java类路径上的文件夹(请参见matlabroot/toolbox/loca如果错误发生在运行时,classpath将在开发机器上运行时存储在matlabroot/toolbox/local/classpath.txt中。“

+0

+1让最终用户修改系统库不是广泛部署的可接受解决方案。他们不一定拥有技术知识或文件许可权限,不同的程序可能会使用不同的库和版本库,并且会增加环境的差异性。但它看起来像你在这里的东西。我将尝试在构建环境中修改静态类路径文件足够长的时间以使其能够使用导入进行编译,然后查看它是否会在部署的MCR应用运行时将动态类路径上的JAR拉出来。 – 2012-02-10 07:52:46

+0

@AndrewJanke,好吧,如果你给他们编译的应用程序,他们必须安装MCR,对吗?所以我不认为权限是如此重要。至于最终用户的技术知识,您可以编写一个小工具来执行一些后期设置,比如说,一个执行所需工作的shell脚本,包括修改基于知识的MCR中的classpath.txt MCR的安装位置。 – eternaln00b 2012-02-10 13:09:36

+0

另外,请考虑接受我的回答,因为我相信这在技术上是对您问题的正确答案。 :) – eternaln00b 2012-02-10 13:10:28

-1

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

提取MATLAB维护Java类从搜索路径分离的路径。这意味着即使您在MATLAB路径中有一个.class或.jar文件,除非您使用javaaddpath,您将无法使用它。要查看路径上当前的内容,请使用javaclasspath。运行这个命令,你将会看到一个很长的MATLAB文件列表,称为静态类路径,然后你会看到动态类路径。动态类路径是添加到具有javaaddpath的路径的类将被放置的位置。他们可以用javarmpath删除,并且必须积极地重新加载每一次matlab。

+0

这个doco只提到Matlab本身,而不是'mcc'。这是我在Matlab的类路径中获取我的JAR的方式。但是我需要''mcc',正如Matlab所调用的那样,也要尊重它。 – 2012-02-09 23:54:03

+0

@AndrewJanke mcc只考虑静态类路径,而不考虑动态类路径(使用javaaddpath修改),请参阅上面的我的答案。 – eternaln00b 2012-02-10 03:00:41

1

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

,然后它会编译和工作。不需要混淆全系统的类路径。

+0

这不会有因为该版本中的mcc不会执行javaaddpath语句,所以导入语句仍然无法解析,并且构建将会中断。 – 2014-03-20 06:23:35