1. 程式人生 > >使用命令列對java程式的編譯執行和打包

使用命令列對java程式的編譯執行和打包

0x00 背景

我們平時使用了在有IDE的環境下編寫程式碼,編譯的工作會由IDE自動完成,這樣方便了我們工作,但是卻使我們忽略了程式碼是如何執行的本質,或者當電腦上只有jre環境,沒有開發環境,就需要在cmd環境下進行java程式的編譯和執行,本文詳細介紹瞭如何在cmd環境下使用命令列執行java程式。

0x01 使用javac和java編譯和執行java程式

1、Java源程式經過編譯器編譯後編成位元組碼,即class檔案中的內容,位元組碼由虛擬機器解釋執行,虛擬機器將每一條要執行的位元組碼送給直譯器,直譯器將其翻譯成特定機器上的機器碼,然後在特定的機器上執行。程式碼開頭是可以不帶有包名的,比如在D:\workspace\src中建立Demo.java,程式碼如下:

public class Demo
{
    public static void main(String[] args)
    {
        System.out.println("Hello World");
    }
}

方法一:進入檔案所在碟符,輸入d:,再輸入cd workspace/src進入java源程式的根目錄,輸入命令javac Demo.java對Demo.java程式進行編譯,生成Demo.class檔案,再輸入命令java Demo執行Demo.class檔案,隨後即可看到程式執行的結果。注意:程式的編譯和執行最好在專案的根目錄下,比如此例進入src這個目錄進行編譯和執行

。如圖所示:
這裡寫圖片描述
方法二:因為在Windows系統中碟符是以反斜槓分隔的,即“\”,所以編譯的時候在windows系統中也可以使用反斜槓作為分隔符,進入檔案所在碟符,輸入d:,然後輸入命令javac workspace\src\Demo.java ,這種方法可以在Linux系統中是不能使用的,這裡寫出只是為了告訴讀者Windows下可以使用,但是不建議使用。
如圖所示:
這裡寫圖片描述

2、一般程式碼的開頭都是帶有包名的,例如程式如下:

package com.hh;
public class Demo
{
    public static void main(String[] args)
    {
        System.out
.println("Hello World"); } }

那麼相應的應該在路徑D:\workspace\src\com\hh下儲存Demo.java檔案,然後使用如下方式編譯和執行,注意一定要在包路徑外的路徑下使用java命令執行,分隔符可以使用"/"或者".",如圖所示:
這裡寫圖片描述
在Windows系統中可以使用反斜槓作為分隔符。如圖所示: 這裡寫圖片描述

0x02 java在cmd環境下編譯引用第三方jar包的類

很多時候一個程式碼都不是獨立完成的,而是需要呼叫第三方包的,設定classpath的目的,在於告訴Java執行環境,在哪些目錄下可以找到您所要執行的Java程式所需要的類或者包。
為了方便演示,我引用了poi-3.8-20120326.jar這個第三方jar包
編寫呼叫第三包的類檔案,程式碼如下:

package com.hh;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;

public class Demo 
{

    public static void main(String[] args)
    {       
        Workbook wb = new HSSFWorkbook();
        System.out.println(wb.getNumberOfSheets());
    }

}

從上面呼叫程式碼中我們可以看出,呼叫程式碼的類名為:Demo,功能是新建一個excel,顯示出sheet的數目,將jar包和呼叫程式都放在D:\workspace下,目錄結構如圖所示:
這裡寫圖片描述
執行命令如下:
這裡寫圖片描述
當要使用的第三方jar包很多時,如果要一個一個寫入classpath會很麻煩,這樣可以用“*”來代替,比如:把要使用的jar包都放在D:\workspace\lib下,
那麼在編譯時命令為:javac -cp lib/* src/com/hh/Demo.java
執行時的命令為:java -cp src;lib/*.jar com.hh.Demo
這裡寫圖片描述

0x03 將引用了第三方jar包的Java專案打包成jar檔案

由於是打包引用了第三方jar包的Java專案,故需要自定義配置檔案MANIFEST.MF,在該專案下建立檔案MANIFEST.MF,內容如下:
Manifest-Version: 1.0
Main-Class: main.KillCheatFans
Class-Path: lib/commons-codec.jar lib/commons-httpclient-3.1.jar lib/commons-logging-1.1.jar lib/log4j-1.2.16.jar lib/jackson-all-1.8.5.jar
第一行是MAINIFEST的版本,第二行指定我們要執行的MAIN java檔案,第三行Class-Path就指定了外來jar包的位置。
這裡要注意幾點:
1、Class-Path: 和Main-Class: 後邊都有一個空格,必須加上,否則會打包失敗,錯誤提示為:Invalid header field;

2、假設我們的專案打包後為KillCheatFans.jar,那麼按照上面的定義,應該在 KillCheatFans.jar的同層目錄下建立一個lib資料夾(即lib檔案和打包的jar檔案
在同一個目錄下),並將相關的jar包放在裡面。否則將會出現“Exception in thread “main” java.lang.NoClassDefFoundError”的錯誤;

3、Main-Class後面是類的全地址,比如你的主檔案是KillCheatFans.java,檔案裡打包為package com.main; 那麼這裡就寫com.main.KillCheatFans,
不要加.java字尾,主檔案地址寫錯將會出現“找不到或無法載入主類”的錯誤;