文/陳剛 from www.chengang.com.cn
最近由于工作關(guān)系,老大囑咐我看一下Java Web Start。以前安裝JDK時(shí),會(huì)在“開始”菜單加一個(gè)快捷菜單“Java Web Start”,也不知是做什么用的,我一般都是刪除。今天從網(wǎng)上查了一下資料,不看不知道,一看嚇一跳,覺得這JWS(Java Web Start簡稱)很象傳說中的“服務(wù)器端小程序下載運(yùn)行”。而且JWS很早就有了,我看有些文章資料已經(jīng)是2002年發(fā)的,自己竟然全然不知它的存在,實(shí)在是愚昧呀。
1. JWS有什么用
B/S風(fēng)行的一個(gè)很大原因就是它有部署方便的優(yōu)勢(shì),這是C/S的Application所無法比擬的。現(xiàn)在,JWS讓用戶可以下載服務(wù)器端的Java Application到本機(jī)運(yùn)行,并且沒有安裝、配置等繁瑣的操作。SUN網(wǎng)站上有Demo,大家可以體驗(yàn)一下效果:http://java.sun.com/products/javawebstart/demos.html 。
2. JWS的運(yùn)行原理
瀏覽器的運(yùn)行Java Applica ton的鏈接指向的不是程序本身,而是一個(gè)*.jnlp文件,這個(gè)文件包含了Java Application的一些配置信息。然后JWS解讀這個(gè)文件的信息,將服務(wù)器端的Java Application下載到本機(jī)上,并運(yùn)行。
當(dāng)然第一次運(yùn)行程序時(shí),由于要下載所以速度會(huì)稍微慢一些,不過第二次運(yùn)行時(shí),JWS會(huì)自動(dòng)去服務(wù)器上檢查是否有新的程序版本發(fā)布,如果沒有就會(huì)直接運(yùn)行本機(jī)已經(jīng)下載的程序,這就和運(yùn)行本機(jī)Java Application沒什么區(qū)別了。運(yùn)行程序之初,JWS還會(huì)提示你是否創(chuàng)建一個(gè)相應(yīng)的快捷菜單。
程序下載到本機(jī)的默認(rèn)位置是:“C:\Documents and Settings\admin\Application Data\Sun\Java\Deployment\javaws\cache\indirect\indirect12423.ind”,你可以在本機(jī)的“JWS應(yīng)用程序管理器”的里重新設(shè)置此存放目錄。

JWS無疑要比Applet的應(yīng)用范圍更廣(據(jù)說還得過**的最佳創(chuàng)意獎(jiǎng)),它對(duì)于布署一些小型的程序應(yīng)用是非常方便的,但我以為現(xiàn)在還主要適用于局域網(wǎng)。因?yàn)橐粋€(gè)程序一般約有幾十M,如果是Internet用戶第一次的下載速度會(huì)很慢。
3. 安全性問題
但和Applet一樣,JWS也面臨安全性問題,默認(rèn)情況下JWS對(duì)本機(jī)磁盤和本地網(wǎng)絡(luò)的訪問是有限制的。如果該程序要越權(quán)訪問,這時(shí)會(huì)彈出一個(gè)警告框(類似于ActivX的數(shù)字簽名),用戶可以自已決定是否信任該軟件,而對(duì)其放開限制。
4. JWS的優(yōu)缺點(diǎn)
JWS的優(yōu)點(diǎn)就是讓程序的布署更簡單,而且用戶端的應(yīng)用可以時(shí)刻保持和服務(wù)器端的最新版本同步,這為升級(jí)版本提供了很大的方便。缺點(diǎn)也是明顯的,由于要運(yùn)行應(yīng)用必須一次下載所有的程序文件(JWS的jnlp配置文件有個(gè)lazy選項(xiàng),但作用不明顯),所以第一次下載速度很慢,不適用于互聯(lián)網(wǎng)。從這一點(diǎn)來看B/S形式的應(yīng)用還是有優(yōu)勢(shì)的。
5. 參考資料
http://www.chinaitlab.com/www/news/article_show.asp?id=25239
http://blog.csdn.net/emag_java/archive/2005/01/13/252047.aspx
Java Web Start實(shí)例
1、示例說明
由于本BLOG現(xiàn)主要以Eclipse和SWT為內(nèi)容,所以Java Web Start(簡稱JWS)也以一個(gè)SWT應(yīng)用程序來做為示例。本文用<Eclipse從入門到精通>書中打包一章的打包結(jié)果為示例,該示例為一個(gè)SWT/JFace程序,其打包后的文件結(jié)構(gòu)如下:

說明:
- myswt是主包,里面含有自己寫的程序代碼
- swt-win32-3063.dll是本地化文件
- lib子目錄下還有三個(gè)jar文件:jface.jar、runtime.jar、swt.jar,這三個(gè)文件是SWT程序的支持庫
如果是在本地運(yùn)行此程序,雙擊myswt.jar即可(要求Windows中jar格式的文件默認(rèn)用javaw.exe打開,如下圖所示:
現(xiàn)在我們要將這個(gè)程序用JWS部署到服務(wù)器端,然后編寫一個(gè)網(wǎng)頁,讓用戶單擊網(wǎng)頁上的鏈接就可以下載該SWT程序并運(yùn)行。
2、準(zhǔn)備工作
本人的開發(fā)環(huán)境為:WinodwsXP SP2 + JDK1.4.2 + Tomcat 5.0.28
(1)首先得先安裝Tomcat,這一步的操作方法本文省略
(2)在Tomcat的webapps\ROOT路徑下創(chuàng)建一個(gè)“myswt”目錄。在我的電腦上,其絕對(duì)路徑如下:E:\Program Files\Apache Software Foundation\Tomcat 5.0\webapps\ROOT\myswt。
(3)將前面所述的SWT程序的文件復(fù)制到webapps\ROOT\myswt目錄中。
3、生成證書
創(chuàng)建一個(gè)批處理文件:key.bat
c:\jdk\bin\keytool -genkey -keystore myKeystore -alias myself
c:\jdk\bin\keytool -list -keystore myKeystore
pause
說明:
- keytool是JDK自帶的一個(gè)工具,用于數(shù)字簽名。在我的電腦,它是位于c:\jdk\bin\路徑下,由于我沒有設(shè)置環(huán)境變量path,所以在批處理文件中硬性指定keytool的路徑。如果是自己用或者公司內(nèi)部用,象本文這樣用keytool生成一個(gè)自簽名的證書也就可以了。但如果你想讓簽名更正式一些,以獲得其他用戶的信任,最好去認(rèn)證中心(如 Thawte 或 VeriSign)獲取一個(gè)證書。
- 第一句將生成一個(gè)證書,文件名:myKeystore
- 第二句是列出密鑰證書中的所有入口。(這一句是可選的,只是為了顯示出來看一下,不要也行)
- 最后一句是暫停pause,以便批處理完成后,我們可以回顧一下全過程。
運(yùn)行批處理key.bat后的全部輸入過程如下圖所示:

4、用證用為應(yīng)用程序簽名
(1)因?yàn)楹灻徽J(rèn)jar包,所以先將swt-win32-3063.dll文件用WinRAR或c:\jdk\bin\jar打一個(gè)jar包(swt-win32-3063.jar)。客戶端下載后,會(huì)自動(dòng)解開此包,將swt-win32-3063.dll還原到客戶端。
注意:如果你用WinRAR打包,在壓縮時(shí)必須選ZIP格式,不能選RAR格式。
(2)創(chuàng)建一個(gè)用于簽名的批處理文件:jarsigner.bat,其內(nèi)容如下:
c:\jdk\bin\jarsigner -keystore myKeystore myswt.jar myself
c:\jdk\bin\jarsigner -keystore myKeystore lib\jface.jar myself
c:\jdk\bin\jarsigner -keystore myKeystore lib\runtime.jar myself
c:\jdk\bin\jarsigner -keystore myKeystore lib\swt.jar myself
c:\jdk\bin\jarsigner -keystore myKeystore swt-win32-3063.jar myself
pause
這里每一條命令都要求你輸入密碼,它就是在創(chuàng)建證書myKeystore時(shí)設(shè)置的那個(gè)密碼。至此,簽名證書部份完成了,下一步是創(chuàng)建jnlp文件。
5、創(chuàng)建jnlp文件
(1)創(chuàng)建一個(gè)名為myswt.jnlp的jnlp文件,這個(gè)文件是Java Web Start的核心配置文件,其內(nèi)容如下:
<?xml version="1.0" encoding="GBK"?>
<jnlp codebase="http://localhost:8080/myswt">
<information>
<title>子在川曰(http://blog.csdn.net/glchengang)</title>
<vendor>陳剛</vendor>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.4+"/>
<jar href="myswt.jar"/>
<jar href="lib/jface.jar"/>
<jar href="lib/runtime.jar"/>
<jar href="lib/swt.jar"/>
<nativelib href="swt-win32-3063.jar"/>
</resources>
<application-desc main-class="jface.dialog.wizard.WizardDialog1"/>
</jnlp>
說明:
- encoding="GBK" 本文選擇了GBK,一般來說應(yīng)該用UTF-8。我在這里之所以選擇GBK字符集,主要是為了演示示例方便,如果是正式應(yīng)用,還是應(yīng)該改為UTF-8。如果用UTF-8,則該文件的中文要轉(zhuǎn)換成UNICODE碼,否則實(shí)際運(yùn)行時(shí)將顯示亂碼,你可以用c:\jdk\bin\native2ascii.exe來進(jìn)行“漢字->UNICODE”的轉(zhuǎn)換。
- codebase="http://localhost:8080/myswt" 本應(yīng)用程序的URL
- <information>項(xiàng),是一些顯示信息,<title>、<vendor>都是必選的。<offline-allowed/>是可選的,它表示允許應(yīng)用程序脫機(jī)運(yùn)行(不和服務(wù)器聯(lián)網(wǎng))。
- <security>項(xiàng)是指開放用戶本機(jī)的所有權(quán)限給應(yīng)用程序,這一項(xiàng)會(huì)導(dǎo)致彈出一個(gè)數(shù)字簽名對(duì)話框。
- <resources>列出了用戶需要下載的資源。<j2se version="1.4+"/>是指,要求用戶本機(jī)安裝Java1.4以上版本。<nativelib>是指此包含有本地文件,這時(shí)JWS下載后會(huì)將此包解開。
- <application-desc>指定了程序的入口類,你也可以指定其他的入口類,它不受限制。jface.dialog.wizard.WizardDialog1是myswt.jar包中的一個(gè)向?qū)綄?duì)話框,這是我自己編寫的一個(gè)SWT程序。
(2)創(chuàng)建一個(gè)HTML網(wǎng)頁,網(wǎng)頁指向jnlp文件。我們給此HTML網(wǎng)頁取名:test.html,其內(nèi)容如下:
<A HREF="myswt.jnlp">啟動(dòng)</A>
6、最后效果
(1)最后的服務(wù)器的目錄結(jié)構(gòu)如下圖所示:

(2)用瀏覽器瀏覽:http://localhost:8080/myswt/test.html

單擊“啟動(dòng)”后出現(xiàn)下圖,開始從服務(wù)器上下載SWT應(yīng)用程序:

下載完成后,出現(xiàn)如下圖,提示用戶是否向應(yīng)用程序開放本機(jī)所有權(quán)限(彈出這個(gè)對(duì)話框是由jnlp文件中的<security>項(xiàng)設(shè)置決定的)。
單擊“啟動(dòng)”按鈕,將運(yùn)行程序,出現(xiàn)下圖。(附注:這里沒有彈出提示你添加快捷菜單的對(duì)話框)

7、其他注意事項(xiàng)
(1)如果單擊網(wǎng)頁的“啟動(dòng)”鏈接時(shí),顯示的是jnlp文件的內(nèi)容,還非下載服務(wù)器的應(yīng)用程序。這時(shí)你需要做如下檢查:
-
在Windows中,jnlp格式的文件應(yīng)該默認(rèn)用javaw打開。如果你把它改變成了用記事本或其他程序打開,就也會(huì)出錯(cuò)。
-
WEB服務(wù)器是否能否辨識(shí)jnlp、jar、class文件的格式。如果你是用Tomcat,可以打開conf目錄的WEB.XML文件檢查一下。一般來說,較新的WEB服務(wù)器都支持jnlp,如果Tomcat、WebLogic等(微軟的IIS不支持Java,當(dāng)然也不可能支持jnlp,我是這么想的沒去測(cè)試過)。如果不支持,就在WEB服務(wù)器的配置文件里加上下面的內(nèi)容。
<mime-mapping>
<extension>class</extension>
<mime-type>application/java</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jar</extension>
<mime-type>application/java-archive</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jnlp</extension>
<mime-type>application/x-java-jnlp-file</mime-type>
</mime-mapping>
(2)在使用Java Web Start的時(shí)候可能會(huì)出現(xiàn)"下載資源錯(cuò)誤",大致的出錯(cuò)信息如下:
JNLPException[category: Download Error : Exception:
java.io.IOException:
rename failed in cache : LaunchDesc: null ] at.....
這個(gè)錯(cuò)誤的原因是因?yàn)槊看握{(diào)用Java Web Start都會(huì)到server上查找程序是否更新,然后將程序下載到本地的java web start目錄下的cache目錄中,如果cache中已經(jīng)有同名文件,而且該文件正在被使用,那么新下載的文件就會(huì)出現(xiàn) rename failed錯(cuò)誤,而且手工去刪除本地的文件還會(huì)報(bào)錯(cuò):文件正被使用!
這里涉及到Java Web Start中的sign機(jī)制,可能對(duì)每個(gè)jar文件都需要標(biāo)記,有的時(shí)候會(huì)在任務(wù)管理器中看到j(luò)avaw.exe在運(yùn)行,將該程序終止后就可以將本地的jar文件刪除掉,說明這些本地文件可能還保留著文件鎖定吧!有時(shí)即使將Task Manager中將所有的java程序都kill掉還是會(huì)出錯(cuò),必須要注銷windows才可以,不知道是不是Java Web Start
(3)如果需要給*.jar文件傳遞參數(shù),可以用如下代碼:
<application-desc main-class="XBFrame"/>
<argument>-port</argument>
<argument>1008</argument> "注意-port和1008是兩個(gè)參數(shù),要分開寫
</application-desc>
(4)有的時(shí)候還需要看到*.jar中System.out.print語句輸出的信息,就要打開jws的console,可以在jws manager 中的首選項(xiàng)中設(shè)置(附注:(2)、(3)、(4)照抄<<java web start實(shí)現(xiàn)關(guān)鍵問題(二)>>一文)
(5)如果出現(xiàn)失敗,最基本的查錯(cuò)手段就是看看出錯(cuò)的“詳細(xì)信息”,如下圖所示。
單擊“詳細(xì)信息”按鈕,出現(xiàn)下圖
參考資料
作者簡介