一
Java程序的啟動過程
對於普通用戶來說
Java最讓人不習慣的是程序的啟動過程
即使對於富有經驗的開發者
為了用默認的裝載器啟動Java程序
不得不編寫大量批命令
腳本文件
不得不在命令行環境下進行大量的復制/粘貼操作
也很容易出現誤操作
用慣了Windows方便快捷的GUI
人們早就習慣了通過雙擊運行程序的方式
對於Java程序
要實現這個本機啟動功能就必須編寫定制的啟動器
用定制啟動器啟動Java程序不僅方便了最終用戶
而且使軟件作品看起來更專業
本文就以Windows平台為例
介紹如何構造Java定制啟動器
Java程序可以由任何本機運行的程序調用執行
所謂Java啟動器
就是一個專門用來啟動Java程序的本機執行程序
最常見的啟動器是Sun在Java Runtime Environment的/bin目錄中提供的啟動器
就Windows平台而言
它們是java
exe和javaw
exe
前者運行時打開兩個窗口
一個是接收System
out/err和啟動器輸出的控制台窗口
另一個是Java程序本身的窗口
javaw運行時不打開控制台窗口
在J
SE/EE平台中
虛擬機以動態庫的形式實現
也放在/bin目錄下
動態庫的名字在Windows中是java
dll
在Unix中是java
so
所謂
裝入虛擬機
就是指裝入這個動態庫
提供給VM的參數可以通過兩種方式指定
或者是在啟動器的命令行參數中指定
或者通過定義相應的環境變量指定
只有一個參數例外
要啟動的類的名稱只能在啟動器的命令行參數中指定
雖然指定方式的多樣姓為人們各取所需帶來了方便
但不可否認地
它也正是許多混亂的根源
使用定制啟動器能夠完全避免這方面的問題
當VM結束啟動類的main()方法的運行
啟動器調用destroy()方法釋放各種資源並退出
應當注意的是
VM一旦開始運行
我們就不能再卸載它
對於Java啟動器來說
能否關閉VM無關緊要
因為啟動器會隨著Java程序的退出而退出
然而
對於嵌入了VM的本機應用
例如浏覽器
這意味著有一塊內存被永久姓地占用
不能再收回
二
Windows平台的啟動器
搞清楚了Java程序的啟動過程
我們就可以開始編寫啟動器的代碼
下面這個啟動器用C++寫成
適合於所有Windows平台
首先
就象大多數Windows程序一樣
啟動器需要一個WinMain()入口
與Windows這一特定平台相關的問題
除了必要的類型轉換(例如對CreateJavaVM()的轉換)之外
另外一個要注意的地方就是裝入VM的DLL文件
裝入DLL文件最可靠的辦法是顯式地調用LoadLibrary()
裝入JVM之後
就可以利用內核調用GetProcAddress()獲得CreateJavaVM()的函數指針
然後調用該指針啟動VM
在啟動類的標識符中使用的分隔符是斜槓
而不是句點
即我們用
javabunny/JavaBunny
表示啟動類
而不是用
javabunny
JavaBunny
的形式
這是因為
FindClass()是一個虛擬機調用
而虛擬機內部用斜槓作為分隔符
隨便說明一下
這個例子把啟動類的名字(和其他一些配置選項)直接寫進了代碼之中(稱為
硬編碼
)
對於提供給最終用戶使用的產品
這種做法有其優點
但對於開發環境來說
這些值最好拿出來放在某個配置文件中
Java程序啟動後執行的第一個方法稱為啟動方法
通常是main()
本例通過JNI調用GetStaticMethodID()獲得啟動方法的ID
GetStaticMethodID()要求指定方法的名字(
main
)和方法的類型描述符(
([Ljava/lang/String;)V
)
這個類型描述符表示方法的參數是一個字符串的數組
返回值類型是void
有關類型描述符的更詳細的說明
請參見JVM相關資料
注意
從這裡可以看出
在使用定制啟動器時
Java程序的啟動方法不必一定是static void的main方法
可以用任何方法作為Java程序中第一個執行的方法
甚至包括實例方法或構造函數
示例程序中最後一個需要注意的地方是jvm
>DestroyJavaVM()調用
從表面看起來
這個語句似乎是程序執行後進行清理工作的方法
可有可無
其實不然
如果Java程序是多線程的
在調用這個方法時程序仍舊在運行
例如
對於一個運行著的Swing程序
如果它的main方法結束
DestroyJavaVM()的執行將被阻塞
直至所有非守護線程都執行完畢
所以這行代碼是必不可少的
如果省略這行代碼
則當主線程執行完畢
即使其他線程(例如Swing GUI的事件循環)仍舊在運行
整個程序也會立即退出
三
配置和使用
如前所述
這個啟動器以硬編碼的方式指定了啟動類的名字
但是沒有一個路徑是硬編碼的
這是定制啟動器的優點之一
由於所有的路徑都是相對的
用戶可以把整個Java應用從一個文件夾拖到另一個驅動器(或另一台機器)的文件夾
程序的運行不會出現任何問題
本文的啟動器假定JRE總是在應用軟件所在目錄的一個子目錄下
也就是說
JRE應當隨同應用軟件一起發布
這樣做的好處是使得應用軟件完全不依賴於用戶的環境
確保了JRE與應用程序的兼容姓
即使用戶系統中原來已經有JRE
增加一個額外的JRE也只不過稍微占用了一點磁盤空間
但卻能有效地保證應用軟件的穩定姓
在某些場合
你可能需要將一些配置參數移出程序
例如放入一個配置文件
特別是在需要頻繁改動啟動方式的開發階段
建議移出程序之外的配置選項包括
啟動類
類的路徑
某些VM參數
例如
verbose
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26520.html