問題
因為修Bug,碰到和load dll路徑有關的議題。這個問題是: 在class path中加入Native的dll位置,但程式卻去找system32中的dll檔。
經過多個試驗,發現將dll放在jre的bin與java執行檔同目錄,就可以比system32中的提早搜尋到。於是我想到: 即使dll沒放在java執行檔的路徑下,但我是有在工作目錄下放過dll,為何還是去讀取system32呢? (在這的java執行檔指的是jre/bin/java.exe)
實驗
我透過下面的實驗去確認找尋dll的順序。
Artifact
名稱 | 關係 | 用途 |
---|---|---|
HelloWorld.exe | Load Dll1 | |
HelloWorldDLL1.dll | Load Dll2 | 輸出分別為DLL1-local、DLL1-work、DLL1-system |
HelloWorldDLL2.dll | 輸出分別為DLL2-local、DLL2-work、DLL2-system |
其中工作目錄為C:,執行檔放置路徑為C:/Debug 。
輸出為DLL$-local的與執行檔放在一起;DLL$-work放置於工作目錄;DLL$-system放置於system32中。
測試案例
以下為我們測試的5種case:
案例 | 動作 | 結果 |
---|---|---|
Case1 | 於工作目錄執行Debug/HelloWorld.exe | DLL1-local |
DLL2-local | ||
Case2 | 刪除DLL2(local) | DLL1-local |
DLL2-system | ||
Case3 | 刪除DLL2(system) | DLL1-local |
DLL2-work | ||
Case4 | 還原所有DLL,刪除DLL1(local) | DLL1-system |
DLL2-local | ||
Case5 | 刪除DLL1(system) | DLL1-work |
DLL2-local |
結論
由以上五個case可以發現:dll的搜尋路徑是由執行檔路徑開始,接著是system32,最後是工作目錄。對Java而言,啟動jvm都是透過java指令,也就是java_home/bin/java.exe執行檔。因此放在java_home/bin中的dll,會比system32中的優先找到。後來我透過batch檔去執行Debug/HelloWorld.exe,結果發現搜尋的依據,是根據HelloWorld.exe而非batch檔。不管怎樣包裝,如果是A要去Load B,優先找尋的是A所在的目錄。
留言
張貼留言