2012-02-09 60 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