[英]Location of currently running class or JAR file
我有一個Lotus Notes數據庫,它正在與遠程 web 服務進行一些交互。 我編寫了一個自定義 Java class 來執行交互。
class 方法可以從三個位置之一執行,具體取決於用戶的設置:
在我的 class 中,我只想能夠返回當前 class 正在執行的位置。 因此,如果它從選項 2 或選項 3 執行,則返回 JAR 文件路徑。 如果它從選項 1 執行,則返回我可以處理的其他內容。
我試過以下。
getClass().getProtectionDomain().getCodeSource().getLocation()
結果是:
java.security.AccessControlException: Access denied (java.lang.RuntimePermission getProtectionDomain)
沒有選項可以更改運行此設置的任何客戶端上的任何安全設置。
String myName = "/" + getClass().getName().replace('.', '/') + ".class";
URL myResourceURL = getClass().getResource(myName);
結果: myResourceURL 始終為 null。
String myName2 = getClass().getName().replace('.', '/') + ".class";
ClassLoader myCL = getClass().getClassLoader();
URL myResourceURL2 = myCL.getResource(myName);
結果: myResourceURL2 始終為 null。
a)我在上面哪里出錯了?
和
b) 如何使用不同的方法獲取當前正在執行的 class 的位置?
我已經設法通過將我的代碼包裝在“AccessController.doPrivileged”塊中來克服這個問題,即:
final String[] myLocationViaProtectionDomain = {null};
AccessController.doPrivileged(new PrivilegedAction(){
public Object run(){
myLocationViaProtectionDomain[0] = getClass().getProtectionDomain().getCodeSource().getLocation().toString();
debug("myLocationViaProtectionDomain: " + myLocationViaProtectionDomain[0]);
return null;
}
});
有趣的是,當 JAR 文件位於客戶端的 JVM 目錄(即我原來的帖子中的第 2 點和第 3 點)中時,這種方法完全符合我的要求。 但是,當從 Java 腳本庫中執行代碼時運行相同的代碼時,將引發以下異常:
java.security.AccessControlException: Access denied (java.lang.RuntimePermission getProtectionDomain)
這很好,因為至少在 1 和 (2 & 3) 之間存在差異,然后我可以正確處理。
來自 lekkimworld.com(Twitter:@lekkim)的優秀 Mikkel 向我指出了這個解決方案,非常感謝 go 給他。
我不確定這是否有幫助,但我們“切換”我們的user.dir
(系統屬性)以確保我們為我們的應用程序“運行”某個目錄。 在我們的例子中,我們有一個 web 啟動應用程序,我們通過 Lotus Notes 啟動它(它調用一個 BAT 文件,它調用Java Web 啟動(JAWS)...)
但無論如何,我們要做的是以下。
//Normally you don't ever want to do this......
Class clazz = ClassLoader.class;
Field field = clazz.getDeclaredField("sys_paths");
field.setAccessible(true);
field.setClass(clazz, null);
try {
//Basically we read in the path and then loop through and remove our current
//directory which is where we tend to "kick off from" rather than where we want
//to run from.
String minusCurrentDir = removeCurrentDirectoryFromPath(System.getProperty("java.library.path");
System.setProperty("java.library.path", minusCurrentDir);
}
finally {
field.setAccessible(true);
}
現在稍后您可以訪問和修改user.dir
屬性或詢問它在哪里。 這可能使您可以訪問所需的內容(?),或者至少頂級代碼可能會有所幫助。
您的最后一行代碼有myCL.getResouce(myName)
,它應該使用myName2
代替。 這可能會導致問題。 如果它使用帶有前導“/”的名稱版本,那么您將不會從 ClassLoader.getResource() 調用中獲得任何信息。 它必須沒有前導斜杠。 如果這沒有幫助,您也可以嘗試:
ClassLoader.getSystemResource(myName2); // name without leading slash
如果這仍然不起作用,則可能是安全問題。 根據ClassLoader.getResource() 文檔,如果“調用者沒有足夠的權限來獲取資源”,它可以返回 null。 我只知道Java,不是Lotus,所以不知道它運行代碼的安全環境是什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.