posts - 54,  comments - 1,  trackbacks - 0
            用Java開發(fā)程序,發(fā)布時(shí)總要考慮的問題就是怎么在使用者的機(jī)器上裝好JRE。要考慮的問題很多:使用者有沒有能力獨(dú)自安裝JRE,使用者已有的JRE和我們需要的版本是不是一致,會(huì)不會(huì)出現(xiàn)版本問題,等等。

          使用.NET要考慮的問題就少些。現(xiàn)在.NET CLR似乎已經(jīng)很普及了,看好多D版的Win XP都會(huì)自己安裝最新的.NET CLR,而且似乎它的安裝界面也比JRE友好些。徹底解決安裝JRE的問題的方案,就是讓我們的應(yīng)用程序自己背著JRE!這樣,我們的程序就像傳統(tǒng)的Win32應(yīng)用程序一樣,雙擊就可以執(zhí)行,不用管所在的機(jī)器上是否有JRE,是什么版本的JRE,無論怎樣,我有我自己的!要做到這一點(diǎn),其實(shí)非常容易。

          王森在他的《Java深度歷險(xiǎn)》(強(qiáng)力推薦這本書,內(nèi)容少而精)的第一章就解釋了JDK,JRE,JVM之間的關(guān)系。解釋了我們執(zhí)行java.exe時(shí)發(fā)生的事情。其中提到,java.exe依照一套邏輯來尋找可以用的JRE,首先查找自己所在的目錄下有沒有JRE(據(jù)王森講這樣說不確切,我沒有JDK全部的源代碼,在此無從考證);其次查找自己的父目錄下有沒有JRE;最后才是查詢Windows的注冊表。

          通常我們在安裝好了JRE的機(jī)器上的任何一個(gè)目錄下都可以執(zhí)行java.exe。因?yàn)樗诎惭b時(shí)被復(fù)制到了windows的system32目錄下,而后者無論如何都會(huì)在path環(huán)境變量中。這個(gè)java.exe最終必然會(huì)訪問注冊表來確定真正的JRE的所在地。若我們要求每一個(gè)應(yīng)用程序都自帶JRE,必然不能走這條路。但,邏輯的第二條講,java.exe會(huì)在它的父目錄下查找JRE,解決方案就在這一條中。

          假設(shè)我們的應(yīng)用程序打好了包,叫做MyApp.jar,放在MyApp的目錄下。我們在MyApp目錄下,可以執(zhí)行java –jar MyApp.jar來運(yùn)行我們的程序。我們安裝的是JRE 1.5,在C:\Program Files\Java\jre1.5.0下?,F(xiàn)在,我們只需要簡單的將jre1.5.0目錄搬到MyApp目錄下,順便改個(gè)容易寫的名字比如叫jre?,F(xiàn)在,我們的應(yīng)用程序就象這樣:

          MyApp
          MyApp.jar
          Jre
          Jre1.5.0目錄下的全部內(nèi)容

          Java.exe就在jre目錄下的bin目錄中。根據(jù)第二條邏輯,java.exe會(huì)在它的父目錄中查找jre,實(shí)驗(yàn)證實(shí),它會(huì)查找lib目錄,而lib就在jre目錄下。因此,這樣java.exe就會(huì)確定jre的所在然后正常執(zhí)行java程序,不會(huì)去管我們是否安裝了JRE,注冊表中是否有注冊項(xiàng)這些雜事了。

          試一下,在命令行下進(jìn)入MyApp的目錄下,假設(shè)它在C盤,將path指向MyApp下的JRE:
          set path=c:\MyApp\jre\bin

          然后運(yùn)行:
          java –verbose –jar MyApp.jar

          加上verbose參數(shù)以確定我們確實(shí)用了這一套被搬出了家的JRE。

          程序可以運(yùn)行,并且在命令行輸出的前幾行,可以看到:

          [Opened C:\MyApp\jre\lib\rt.jar]
          [Opened C:\MyApp\jre\lib\jsse.jar]
          [Opened C:\MyApp\jre\lib\jce.jar]
          [Opened C:\MyApp\jre\lib\charsets.jar]

          因此程序讀取的確實(shí)是它的私有的JRE。

          至此,我們似乎完成了任務(wù)。但是現(xiàn)在我們的私有JRE仍不完美,缺點(diǎn)是太大。JRE 1.5有接近70MB,作為我們的私有的JRE,好多內(nèi)容都是可以拋棄的。Jre目錄下的license都可以不要,bin下的執(zhí)行文件只需要保留java.exe或者javaw.exe,lib下只要保留rt,jsse,jce,charsets幾個(gè)庫就可以了。除了i386和zi兩個(gè)子目錄外,其余的子目錄都可以不要。Zi下只需要保留自己地區(qū)的子目錄和其下的一些文件就可以。Lib下除了庫之外的屬性文件等等都要保留。這樣清理一番,JRE仍然有接近50MB。還可以繼續(xù)清理幾個(gè)庫文件里面不需要的內(nèi)容,這需要仔細(xì)的整理,會(huì)很費(fèi)功夫。最好能寫出一個(gè)自動(dòng)工具幫助我們整理它們。從Sun公司上下到的JMF里面附帶的用Java寫的媒體播放器就自帶了JRE,只有幾個(gè)MB。

          清理過后需要運(yùn)行幾遍我們的應(yīng)用程序,以確保我們的JRE不缺少東西。

          如果我們希望能有一個(gè)程序直接啟動(dòng)我們的應(yīng)用程序,那就還要費(fèi)些功夫。最簡單的方法是弄出一個(gè)快捷方式來,但是快捷方式的路徑不能是相對的,不方便我們安裝。我想到的方案就是用Win32程序包裝一下。在VS.NET下寫一個(gè)Win32小程序:

          int PASCAL WinMain( HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          LPSTR lpszCmdLine,
          int nCmdShow ){  STARTUPINFO si;
          PROCESS_INFORMATION pi;
          ZeroMemory( &si, sizeof(si) );
          si.cb = sizeof(si);
          ZeroMemory( &pi, sizeof(pi) );
          // Start the child process.
          if( !CreateProcess( "jre\\bin\\javaw.exe",//執(zhí)行的程序名
          "jre\\bin\\javaw.exe -jar MyApp.jar", // 帶參數(shù)的執(zhí)行程序
          NULL,
          // Process handle not inheritable.
          NULL,
          // Thread handle not inheritable.
          FALSE,
          // Set handle inheritance to FALSE.
          0,
          // No creation flags.
          NULL,
          // Use parent's environment block.
          NULL,
          // Use parent's starting directory.
          &si,
          // Pointer to STARTUPINFO structure.
          &pi )
          // Pointer to PROCESS_INFORMATION structure.  )
          {      ErrorExit( "CreateProcess failed." );
          }   // Wait until child process exits.  WaitForSingleObject( pi.hProcess, INFINITE );
          // Close process and thread handles.
          CloseHandle( pi.hProcess );
          CloseHandle( pi.hThread );}

          基本上是按照MSDN文檔中的例子照搬的。將它編譯成一個(gè)EXE文件,我們的任務(wù)才全部完成。雙擊這個(gè)EXE文件,我們的程序啟動(dòng)了,看起來和傳統(tǒng)的Win32程序沒有兩樣,JRE完全被隱藏在底層。

          P.S. 使用了這個(gè)方案后,我用Wise Installation System制作安裝程序,發(fā)現(xiàn)一個(gè)非常奇怪的問題,安裝結(jié)束后,安裝程序似乎非要運(yùn)行一個(gè)叫做GLJ什么什么,后綴是TMP的程序,還需要JVM,結(jié)果就報(bào)錯(cuò)JVM.DLL找不到。安裝總是不成功。我已經(jīng)禁掉了OCX / DLL / EXE自注冊和卸載支持,為什么還不對?有誰知道是為什么嗎?
          posted on 2005-12-06 20:40 ZhuJun 閱讀(510) 評論(0)  編輯  收藏 所屬分類: 他山の玉

          蜀中人氏,躬耕于珠海

          <2005年12月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(2)

          隨筆分類(71)

          隨筆檔案(54)

          博客

          文檔

          站點(diǎn)

          論壇

          搜索

          •  

          積分與排名

          • 積分 - 51009
          • 排名 - 976

          最新評論

          閱讀排行榜

          主站蜘蛛池模板: 黔南| 门头沟区| 禄劝| 南丰县| 和政县| 修武县| 旬邑县| 瑞安市| 兴国县| 仪陇县| 沙河市| 平山县| 山东| 玛沁县| 罗平县| 醴陵市| 抚州市| 阿尔山市| 新丰县| 瓦房店市| 大名县| 贵州省| 武义县| 塔城市| 洪江市| 阳曲县| 什邡市| 灵寿县| 奉化市| 神木县| 北辰区| 杨浦区| 汉阴县| 长阳| 漠河县| 舞钢市| 永顺县| 龙山县| 织金县| 阳山县| 柘城县|