簡體   English   中英

$CLASSPATH 和 -cp 與 Java

[英]$CLASSPATH and -cp with Java

  • 在這篇文章中,使用 -jar 選項會忽略所有 -cp 和 $CLASSPATH。
  • 在這篇文章中,使用 -cp 選項也會忽略 $CLASSPATH。

他們有什么好的理由嗎?

這是為了避免在分發應用程序以在不同環境中運行時類路徑中的沖突。 在大多數情況下,您希望您的應用程序獨立於特定於平台的配置。 如果$CLASSPATH包含對具有(無意或有意)相同包和類名的類的引用,則它會在類加載中優先於您包含在應用程序類路徑中的類。 這可能會導致意外的應用程序行為或潛在的安全漏洞。

jar 應該是具有自包含庫的獨立程序。 如果要包含其他類路徑,則可能需要執行以下操作

java -cp jar1:jar2:$CLASSPATH some.class.with.main

BalusC 回答了另一個問題。

在這兩種情況下,限制的原因是為了避免1意外或肆意/考慮不周地覆蓋有效類路徑。

如果您真的希望應用程序可以使用“-jar”啟動並通過用戶的 $CLASSPATH 環境變量獲取類,您應該能夠通過讓應用程序創建自己的類加載器或使用自定義啟動器來實現。 (您甚至可以讓您的應用程序在“-jar”參數之后查找“-cp”參數。)

同樣,您可以修改第一種情況下的行為。

但是,我認為這樣做是個壞主意。 可執行 JAR 文件的要點是將應用程序與用戶碰巧啟動應用程序的環境的變幻莫測隔離開來。

如果你想用你的應用程序類路徑做一些hacky的事情,一個更簡單的方法是創建一個包裝腳本來組裝有效的類路徑,然后用“-cp”選項啟動應用程序。 您甚至可以從各種 JAR 文件的清單中提取“類路徑”並將其合並...


1 - 顯然,它不會完全阻止某人更改類路徑。 但是停止這將是一個壞主意,如果我們假設用戶可以獲得本地管理員權限等,那么在技術上可能是不可能的。

環境變量 CLASSPATH 被(並且應該)忽略的原因有幾個:

  1. 所有項目的全局 CLASSPATH 完全沒有意義。 它不可能對所有項目都相同,並且您不希望將一個龐大的項目重新應用於所有項目。
  2. 你不能指望它被設置,所以依賴它是一個壞主意。 在一台機器上運行的代碼在移動時突然不起作用。 您如何傳達必要的環境設置? 最好不要使用它們。
  3. Java EE 應用程序服務器都有自己的約定(例如,WEB-INF/lib 中的所有 JAR 和 WEB-INF/classes 中的所有 .class 文件都自動位於 Web 應用程序的 CLASSPATH 中)。
  4. Java EE 應用服務器都忽略全局 CLASSPATH。 他們不指望它。
  5. Java IDE 都有自己的約定來設置項目 CLASSPATH。 學習它們。
  6. 所有 Java IDE 都會忽略全局 CLASSPATH。 他們不指望它。

我在我使用的任何機器上都沒有全局 CLASSPATH。 這不是必需的。 我建議學習 CLASSPATH 的工作原理並停止依賴環境變量。

正確與否,我渴望一個-jar-cp標志。 這將足夠明顯和直接,不會構成安全風險或破壞當前行為。

對於像java.util.ServiceLoader這樣的 API,希望從類路徑中添加/刪除服務是完全合理的。 您不必放棄該功能,因為您在清單中使用了Main-Class

用我的話來說,沒有足夠理智的理由來解釋這種明顯的“荒謬”。 Sun 錯誤數據庫中的錯誤之一,只能推斷開發人員沒有考慮到可以通過 CLASSPATH 環境變量或 -cp 選項指定類路徑的事實。 當問題被發現時,該版本或多或少是公開的,其結果是修復會導致向后兼容性問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM