作者: 邊城狂人
常常在網上看到有人詢問
如何把 java 程序編譯成
exe 文件
通常回答只有兩種
一種是
說
制作一個可執行的 JAR 文件包
就可以像
chm 文檔一樣雙擊運行了
而另一種回答
則是
使用 JET 來進行編譯
但是 JET 是要用錢買的
而且
據說 JET 也不是能把所有的 Java 程序
都編譯成執行文件
性能也要打些折扣
所以
使用制作可執行 JAR 文件包的方法就是最佳選擇
了
何況它還能保持 Java 的跨平台特性
先來看看什麼是 JAR 文件包
JAR 文件包
JAR 文件就是 Java Archive File
顧名思意
它的應用是與 Java 息息相關的
是 Java
的一種文檔格式
JAR 文件非常類似 ZIP 文件——准確的說
它就是 ZIP 文件
所以叫它文件
包
JAR 文件與 ZIP 文件唯一的區別就是在 JAR 文件的內容中
包含了一個 META
INF/MANIFEST
MF 文件
這個文件是在生成 JAR 文件的時候自動創建的
舉個例子
如果我們具
有如下目錄結構的一些文件
==
`
test
`
Test
class
把它壓縮成 ZIP 文件 test
zip
則這個 ZIP 文件的內部目錄結構為
test
zp
`
test
`
Test
class
如果我們使用 JDK 的 jar 命令把它打成 JAR 文件包 test
jar
則這個 JAR 文件的內部目
錄結構為
test
jar
|
META
INF
| `
MANIFEST
MF
`
test
`
Test
class
創建可執行的 JAR 文件包
制作一個可執行的 JAR 文件包來發布你的程序是 JAR 文件包最典型的用法
Java 程序是由若干個
class 文件組成的
這些
class 文件必須根據它們所屬的包不同而
分級分目錄存放
運行前需要把所有用到的包的根目錄指定給 CLASSPATH 環境變量或者 java 命
令的
cp 參數
運行時還要到控制台下去使用 java 命令來運行
如果需要直接雙擊運行必須
寫 Windows 的批處理文件 (
bat) 或者 Linux 的 Shell 程序
因此
許多人說
Java 是一種
方便開發者苦了用戶的程序設計語言
其實不然
如果開發者能夠制作一個可執行的 JAR 文件包交給用戶
那麼用戶使用起來就需
要方便了
在 Windows 下安裝 JRE (Java Runtime Environment) 的時候
安裝文件會將
jar
文件映射給 javaw
exe 打開
那麼
對於一個可執行的 JAR 文件包
用戶只需要雙擊它就可以
運行程序了
和閱讀
chm 文檔一樣方便 (
chm 文檔默認是由 hh
exe 打開的)
那麼
現在的
關鍵
就是如何來創建這個可執行的 JAR 文件包
創建可執行的 JAR 文件包
需要使用帶 cvfm 參數的 jar 命令
同樣以上述 test 目錄為
例
命令如下
jar cvfm test
jar manifest
mf test
這裡 test
jar 和 manifest
mf 兩個文件
分別是對應的參數 f 和 m
其重頭戲在
manifest
mf
因為要創建可執行的 JAR 文件包
光靠指定一個 manifest
mf 文件是不夠的
因
為 MANIFEST 是 JAR 文件包的特征
可執行的 JAR 文件包和不可執行的 JAR 文件包都包含
MANIFEST
關鍵在於可執行 JAR 文件包的 MANIFEST
其內容包含了 Main
Class 一項
這在
MANIFEST 中書寫格式如下
Main
Class: 可執行主類全名(包含包名)
例如
假設上例中的 Test
class 是屬於 test 包的
而且是可執行的類 (定義了 public
static void main(String[]) 方法)
那麼這個 manifest
mf 可以編輯如下
Main
Class: test
Test <回車>
這個 manifest
mf 可以放在任何位置
也可以是其它的文件名
只需要有 Main
Class:
test
Test 一行
且該行以一個回車符結束即可
創建了 manifest
mf 文件之後
我們的目錄結
構變為
==
|
test
| `
Test
class
`
manifest
mf
這時候
需要到 test 目錄的上級目錄中去使用 jar 命令來創建 JAR 文件包
也就是在目
錄樹中使用
==
表示的那個目錄中
使用如下命令
jar cvfm test
jar manifest
mf test
之後在
==
目錄中創建了 test
jar
這個 test
jar 就是執行的 JAR 文件包
運行時只
需要使用 java
jar test
jar 命令即可
需要注意的是
創建的 JAR 文件包中需要包含完整的
與 Java 程序的包結構對應的目錄結
構
就像上例一樣
而 Main
Class 指定的類
也必須是完整的
包含包路徑的類名
如上例的
test
Test
而且在沒有打成 JAR 文件包之前可以使用 java <類名> 來運行這個類
即在上例
中 java test
Test 是可以正確運行的 (當然要在 CLASSPATH 正確的情況下)
jar 命令詳解
jar 是隨 JDK 安裝的
在 JDK 安裝目錄下的 bin 目錄中
Windows 下文件名為 jar
exe
Linux 下文件名為 jar
它的運行需要用到 JDK 安裝目錄下 lib 目錄中的 tools
jar 文件
不
過我們除了安裝 JDK 什麼也不需要做
因為 SUM 已經幫我們做好了
我們甚至不需要將
tools
jar 放到 CLASSPATH 中
使用不帶任何的 jar 命令我們可以看到 jar 命令的用法如下
jar {ctxu}[vfm
M] [jar
文件] [manifest
文件] [
C 目錄] 文件名
其中 {ctxu} 是 jar 命令的子命令
每次 jar 命令只能包含 ctxu 中的一個
它們分別表
示
c 創建新的 JAR 文件包
t 列出 JAR 文件包的內容列表
x 展開 JAR 文件包的指定文件或者所有文件
u 更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中)
[vfm
M] 中的選項可以任選
也可以不選
它們是 jar 命令的選項參數
v 生成詳細報告並打印到標准輸出
f 指定 JAR 文件名
通常這個參數是必須的
m 指定需要包含的 MANIFEST 清單文件
只存儲
不壓縮
這樣產生的 JAR 文件包會比不用該參數產生的體積大
但速度更快
M 不產生所有項的清單(MANIFEST〕文件
此參數會忽略
m 參數
[jar
文件] 即需要生成
查看
更新或者解開的 JAR 文件包
它是
f 參數的附屬參數
[manifest
文件] 即 MANIFEST 清單文件
它是
m 參數的附屬參數
[
C 目錄] 表示轉到指定目錄下去執行這個 jar 命令的操作
它相當於先使用 cd 命令轉該
目錄下再執行不帶
C 參數的 jar 命令
它只能在創建和更新 JAR 文件包的時候可用
文件名
指定一個文件/目錄列表
這些文件/目錄就是要添加到 JAR 文件包中的文件/目
錄
如果指定了目錄
那麼 jar 命令打包的時候會自動把該目錄中的所有文件和子目錄打入包
中
下面舉一些例子來說明 jar 命令的用法
) jar cf test
jar test
該命令沒有執行過程的顯示
執行結果是在當前目錄生成了 test
jar 文件
如果當前目錄
已經存在 test
jar
那麼該文件將被覆蓋
) jar cvf test
jar test
該命令與上例中的結果相同
但是由於 v 參數的作用
顯示出了打包過程
如下
標明清單(manifest)
增加
test/(讀入=
) (寫出=
)(存儲了
%)
增加
test/Test
class(讀入=
) (寫出=
)(壓縮了
%)
) jar cvfM test
jar test
該命令與
) 結果類似
但在生成的 test
jar 中沒有包含 META
INF/MANIFEST 文件
打包
過程的信息也略有差別
增加
test/(讀入=
) (寫出=
)(存儲了
%)
增加
test/Test
class(讀入=
) (寫出=
)(壓縮了
%)
) jar cvfm test
jar manifest
mf test
運行結果與
) 相似
顯示信息也相同
只是生成 JAR 包中的 META
INF/MANIFEST 內容不
同
是包含了 manifest
mf 的內容
) jar tf test
jar
在 test
jar 已經存在的情況下
可以查看 test
jar 中的內容
如對於
) 和
) 生成的
test
jar 分別應該此命令
結果如下
對於
)
META
INF/
META
INF/MANIFEST
MF
test/
test/Test
class
對於
)
test/
test/Test
class
) jar tvf test
jar
除顯示
) 中顯示的內容外
還包括包內文件的詳細信息
如
Wed Jun
:
:
GMT
META
INF/
Wed Jun
:
:
GMT
META
INF/MANIFEST
MF
Wed Jun
:
:
GMT
test/
Wed Jun
:
:
GMT
test/Test
class
) jar xf test
jar
解開 test
jar 到當前目錄
不顯示任何信息
對於
) 生成的 test
jar
解開後的目錄結
構如下
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19151.html