JVM 與 CLASSPATH


在完成 PATH 是什麼? 中HelloWorld.java的編譯之後,相同資料夾下就會出現HelloWorld.class,JVM、JRE 與 JDK 說過,JVM的可執行檔副檔名是.class,接下來要啟動JVM,要求JVM執行HelloWorld指令:

第一個Hello World出現了

啟動JVM的指令是java,而要求JVM執行HelloWorld時,只要指定類別名稱(就像執行javac.exe工具程式,只要鍵入javac就可以了),不用附加.class副檔名,附加.class反而會有錯誤訊息。


接下來,請你試著切換至C:\,想想看,如何執行HelloWorld?以下幾個方式都是行不通的:

怎麼執行HelloWorld呢?

你要知道java這個指令是作什麼用的?正如先前所言,執行java指令目的在於啟動JVM,之後接著類別名稱,表示要求JVM執行指定的可執行檔(.class)


PATH 是什麼? 中提過,實體作業系統下執行某個指令時,會依PATH中的路徑資訊,試圖找到可執行檔案(例如對Windows來說,就是.exe、.bat副檔名的檔案,對Linux等就是有執行權限的檔案)。


JVM是Java程式唯一認得的作業系統,對JVM來說,可執行檔就是副檔名為.class的檔案。想在JVM中執行某個可執行檔(.class),你就要告訴JVM這個虛擬作業系統到哪些路徑下尋找檔案,方式是透過CLASSPATH指定其可執行檔(.class)的路徑資訊。


用Windows與JVM作個簡單的對照,就可以很清楚地對照PATHCLASSPATH

作業系統
搜尋路徑
可執行檔
Windows PATH .exe、.bat
JVM CLASSPATH .class

PATHCLASSPATH根本就是不同層次的環境變數,實體作業系統搜尋可執行檔是看PATH,JVM搜尋可執行檔(.class)只看CLASSPATH

如何在啟動JVM時告知可執行檔(.class)的位置?可以使用-classpath引數來指定:

啟動JVM時指定CLASSPATH

-classpath有個縮寫形式-cp,這比較常用。如果有多個路徑資訊,則可以用分別區隔。例如:

java -cp C:\workspace;C:\classes HelloWorld


JVM會依CLASSPATH路徑順序,搜尋是否有對應的類別檔案,先找到先贏,先找到先載入。如果在JVM的CLASSPATH路徑資訊中都找不到指定的類別檔案,JDK7前的版本會出現java.lang.NoClassDefFoundError訊息,而JDK7之後的版本會有比較友善的中文錯誤訊息。


為什麼一開始的那張圖不用特別指定CLASSPATH呢?JVM預設的CLASSPATH就是讀取目前資料夾中的.class,如果自行指定CLASSPATH,則以你指定的為主。例如:

指定的CLASSPATH中找不到類別檔案


如上圖所示,雖然工作路徑是在C:\workspace(其中有HelloWorld.class),你啟動JVM時指定到C:\xyz中搜尋類別檔案,JVM還是老實地到指定的C:\xyz中找尋,結果當然就是找不到而顯示錯誤訊息。有的時候,希望也從目前資料夾開始尋找類別檔案,則可以使用.指定。例如:

指定.表示搜尋類別檔案時包括目前資料夾


如果使用Java開發了程式庫,這些程式庫中的類別檔案,會封裝為JAR(Java Archive)檔案,也就是副檔名為.jar的檔案。JAR檔案實際使用ZIP格式壓縮,當中包含一堆.class檔案,那麼,如果你有個JAR檔案,如何在CLASSPATH中設定?

答案是將JAR檔案當作特別的資料夾,例如,有abc.jar與xyz.jar放在C:\lib底下,執行時若要使用JAR檔案中的類別檔案,可以如下:

java -cp C:\workspace;C:\lib\abc.jar;C:\lib\xyz.jar SomeApp

如果有些類別路徑很常使用,其實也可以透過環境變數設定。例如:

SET CLASSPATH=C:\classes;C:\lib\abc.jar;C:\lib\xyz.jar

在啟動JVM時,也就是執行java時,若沒使用-cp-classpath指定CLASSPATH,就會讀取CLASSPATH環境變數。同樣地,文字模式中的設定在關閉文字模式之後就會失效。如果希望每次開啟文字模式都可以套用某個CLASSPATH,也可以設定在系統變數或使用者變數中。如果執行時,使用了-cp-classpath指定CLASSPATH,則以-cp或-classpath的指定為主。

如果某個資料夾中有許多.jar檔案,從Java SE 6開始,可以使用*表示使用資料夾中所有.jar檔案。例如指定使用C:\jars下所有JAR檔案:

java –cp .;C:\jars\* cc.openhome.JNotePad

Java SE 6中CLASSPATH新的指定方式,也適用在系統環境變數的設定上。