2010-08-03 74 views
4
  • 在此post中,使用-jar選項會忽略所有的-cp和$ CLASSPATH。
  • 在此post中,使用-cp選項也會忽略$ CLASSPATH。

他們有什麼好的理由嗎?

回答

7

每當您將應用程序分發到不同的環境中運行時,就可以避免類路徑中發生衝突。在大多數情況下,您希望應用程序獨立於平臺特定的配置。如果$CLASSPATH包含對具有(不知道或意識到)相同的包和類名的類的引用,它將在包含在應用程序的類路徑中的類之前的類加載中優先。這可能會導致意外的應用程序行爲或潛在的安全漏洞。

4

jar應該是一個獨立的程序,包含自包含的庫。如果你想包括其他類路徑,你可能需要做一些像

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

BalusC回答其他問題。

0

用我的話來說,沒有足夠的理由來解釋這種明顯的「荒謬」。從one of the bugs in the Sun bug database開始,只能推斷開發人員沒有考慮到可以通過CLASSPATH環境變量或通過-cp選項指定類路徑的事實。發現問題時,發佈或多或少是公開的,其效果是修復會導致向後兼容性問題。

+1

您正試圖重寫歷史記錄。對這個錯誤報告的更全面的解讀是:1)這是一個故意設計的決定,有很好的理由,2)回顧起來,理由仍然有效。改變'-jar'語義的事實會破壞很多事情,這只是另一個不會改變的原因......不是主要原因。主要原因是Sun/Oracle認爲當前的行爲是正確的。 (FWIW,我同意) – 2010-08-03 23:19:45

+0

嗯,我不是。規範是不完整的,因爲它從來沒有解決通過環境繼承的用戶類路徑,所以它從來沒有故意好。回想起來,這可能聽起來不錯,但正如分析中的一個評論所指出的那樣,修復是微不足道的。 – 2010-08-03 23:23:50

+0

我不知道*你從哪裏得到的。該規範明確指出/使用「-jar」時忽略$ CLASSPATH。該錯誤報告甚至引用了在線文檔中的說明,以便說明這一點。 – 2010-08-04 00:00:12

1

有幾個原因,環境變量CLASSPATH是(也應該)忽略:

  1. 全局類路徑爲所有項目是沒有意義的。它對於所有項目來說都不一樣,而且你不希望爲所有項目重新應用一個龐大的項目。
  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的工作方式,並停止依賴環境變量。

+0

我運行了一個應用程序,該應用程序擁有自己的類路徑,在jar中進行了硬編碼。它調用我的另一個jython應用程序。我想爲jython提供額外的類。爲什麼選擇我的jython類的位置的主要Java應用程序是不好的?其次,我不明白如何證明CLASSPATH是完全廢話可以解釋,當沒有使用-cp選項時,它是可以的。 – Val 2013-10-12 16:36:33

1

如果您確實想要使用「-jar」啓動應用程序並通過用戶的$ CLASSPATH環境變量獲取類,則應該可以通過讓應用程序創建自己的類加載器來完成此操作。 (你甚至可以讓你的應用程序在「-jar」參數後尋找「-cp」參數)。可執行JAR文件的主要目的是將應用程序與用戶碰巧啓動應用程序的環境的變幻莫測分開。

如果你想用你的應用程序類路徑做黑客事情,更簡單的方法是創建一個包裝腳本,然後根據需要組裝有效的類路徑,然後用「-cp」選項啓動應用程序。你甚至可以從各種JAR文件的清單中拉出「類路徑」,並將其合併到一起...

1

正確與否,我長期爲-jar-cp標誌。這將是明顯而直接的,不會成爲安全風險或打破目前的行爲。

使用像java.util.ServiceLoader這樣的API,希望從類路徑添加/刪除服務是完全合理的。您不應該因爲在清單中使用Main-Class而失去該功能。