免責聲明母語不是英語,如果需要,隨意編輯。Java:重新使用已加載的本機庫?
我有一個類似的問題是,一個在這裏解釋: java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader
我試圖按照user2543253的答案。但是我真的對Java缺乏瞭解,而且上下文有點不同。
鏈接
- .dll already loaded in another classloader?好像也涉及到這個問題。
- https://github.com/PatternConsulting/opencv/issues/7相似。
- https://cycling74.com/articles/mxj-class-loading解釋MXJ 的類加載器的行爲
語境
編輯:不知道這方面是非常重要的,這似乎是同樣的問題,在鏈接描述1
我想在名爲Max/MSP的應用程序中使用OpenCV。
舉一個想法,它看起來像這樣:
最大/ MSP允許用戶通過佈線的一些對象一起被稱爲的外部組裝補丁,其中大部分是用C語言編碼但你也可以用Java創建外部的。爲此,您需要通過名爲「mxj」的對象來實例化它們。例如,如果我的Java類名爲TestOpenCV,我將創建一個框並在其中放入「mxj TestOpenCV」。
OpenCV似乎正確實現,例如,我可以實例化一個Mat對象並將其內容發佈到Max控制檯。
當我更改mxj對象的Java代碼時出現問題。要更新我的對象,我將其刪除並重新創建。然後,解釋here出現同樣的問題...
最大控制檯返回該錯誤消息:
java.lang.UnsatisfiedLinkError: Native Library C:\Windows\System32\opencv_java300.dll already loaded in another classloader at java.lang.ClassLoader.loadLibrary1(Unknown Source) at java.lang.ClassLoader.loadLibrary0(Unknown Source) at java.lang.ClassLoader.loadLibrary(Unknown Source) at java.lang.Runtime.loadLibrary0(Unknown Source) at java.lang.System.loadLibrary(Unknown Source) at OpenCVClassLoad.loadNativeLibrary(OpenCVClassLoad.java:5) at TestOpenCV.(TestOpenCV.java:22) (mxj) unable to alloc instance of TestOpenCV
我試過
我試圖執行user2543253的答案。他建議創建一個導入本地庫並將其導出爲JAR的小類。所以,我創建了一個新的Eclipse項目添加源文件,它
import org.opencv.core.Core;
public class OpenCVClassLoad {
public static void loadNativeLibrary() {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
我加入OpenCV的JAR到該項目,並出口它作爲一個JAR。
然後我根據什麼user2543253解釋改變了我的代碼(有更多的代碼,我不停的必備):
import com.cycling74.max.*;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
public class TestOpenCV extends MaxObject {
static {
// System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
OpenCVClassLoad.loadNativeLibrary();
}
public TestOpenCV(Atom[] args)
{
// ...
}
public void notifyDeleted()
{
// ...
}
public void bang() {
// Executed when I trig the little bang button you can see
Mat m = new Mat(5, 9, CvType.CV_8UC4, new Scalar(0));
post("OpenCV Mat: " + m);
Mat mr1 = m.row(1);
mr1.setTo(new Scalar(1));
Mat mc5 = m.col(3);
mc5.setTo(new Scalar(5));
post("OpenCV Mat data:\n" + m.dump());
}
}
當然,不過這是一個有點怪異,以便正確地構建項目我從保持了OpenCV的JAR在構建路徑:
正如你所看到的,我還添加了小小的類項目構建路徑。 經過所有這些修改後,mxj對象stille首次正確加載,並且bang()方法仍然有效,但問題仍然存在。事實上,它並沒有任何東西從過去的情況發生變化:如果我修改了Java代碼,刪除最大的對象,並創建一個新的,出現錯誤...
問題
有很多的SO問題涉及相同類型的概率,但上下文總是不同,並且很難弄清楚該怎麼做,特別是使用我對Java的基本知識。
解決方法應該是簡單地重用已加載的庫,否?但如何實現這一目標?因爲如果我檢查圖書館已經被加載,我使用Try/Catch來做,如果我什麼也不做。外部的行爲,如果圖書館從未被加載...
如何重用該本地庫? (當然,歡迎任何替代解決方案)
不幸的是,你的第一個解決方案是行不通的,我已經試過了,可能是這裏的解釋:https://cycling74.com/articles/mxj-class-loading。當我更改JAVA代碼時,它被重新編譯。因此,它有一個更新的類文件,MXJ檢測它並創建一個新的類加載器。我將閱讀您的替代解決方案,但我還沒有找到。我編輯帖子添加該鏈接並刪除了第二個OpenCVClassLoad.loadNativeLibrary();這是沒用的。 –
所以我嘗試了另一種解決方案,但似乎沒有幫助。事實上,我不明白它應該如何幫助,問題來自於類加載器。你的意思是通過設置本地庫的位置,我不再需要使用System.loadLibrary();或類加載器? –
是,或者設置本地庫位置(='-Djava.library.path = ...')或者在運行時通過'System.loadLibrary()'加載庫。在第二種情況下,您可以在代碼中添加新的Exception()。printStackTrace();來查找代碼執行的位置和頻率。 – howlger