北方站长站
客服热线:0632-5117766

J2SE综合:浅谈java程序发布之 jre 篇

[2008-01-03 00:00:00] 作者:Northz.com 来源:北方站长站

Tags:发布 程序 综合 我们 JRE 目录 可以 安装 执行 一个 应用程序

  

NET CLR似乎已经很普及了,看好多D版的 Win XP都会自己安装最新的。NET CLR,而且似乎它的安装界面也比JRE友好些。彻底解决安装JRE的问题的方案,就是让我们的应用程序自己背着JRE!这样,我们的程序就像传统的Win32应用程序一样,双击就可以执行,不用管所在的机器上是否有JRE,是什么版本的JRE,无论怎样,我有我自己的!要做到这一点,其实非常容易。uJF北方站长站

  王森在他的《Java深度历险》(强力推荐这本书,内容少而精)的第一章就解释了JDK,JRE,JVM之间的关系。解释了我们执行java.exe时发生的事情。其中提到,java.exe依照一套逻辑来寻找可以用的JRE,首先查找自己所在的目录下有没有 JRE(据王森讲这样说不确切,我没有JDK全部的源代码,在此无从考证);其次查找自己的父目录下有没有JRE;最后才是查询Windows的注册表。uJF北方站长站

  通常我们在安装好了JRE的机器上的任何一个目录下都可以执行java.exe.因为它在安装时被复制到了windows的system32目录下,而后者无论如何都会在path环境变量中。这个java.exe最终必然会访问注册表来确定真正的JRE的所在地。若我们要求每一个应用程序都自带JRE,必然不能走这条路。但,逻辑的第二条讲,java.exe会在它的父目录下查找JRE,解决方案就在这一条中。uJF北方站长站

  假设我们的应用程序打好了包,叫做 MyApp.jar,放在MyApp的目录下。我们在MyApp目录下,可以执行java ?jar MyApp.jar来运行我们的程序。我们安装的是 JRE 1.5,在C:/Program Files/Java/jre1.5.0下。现在,我们只需要简单的将jre1.5.0目录搬到MyApp目录下,顺便改个容易写的名字比如叫jre.现在,我们的应用程序就象这样:uJF北方站长站

  MyAppuJF北方站长站

  MyApp.jaruJF北方站长站

  JreuJF北方站长站

  Jre1.5.0目录下的全部内容uJF北方站长站

  Java.exe 就在jre目录下的bin目录中。根据第二条逻辑,java.exe会在它的父目录中查找jre,实验证实,它会查找lib目录,而lib就在jre目录下。因此,这样java.exe就会确定jre的所在然后正常执行java程序,不会去管我们是否安装了JRE,注册表中是否有注册项这些杂事了。uJF北方站长站

  试一下,在命令行下进入MyApp的目录下,假设它在C盘,将path指向MyApp下的JRE:uJF北方站长站

  set path=c:/MyApp/jre/binuJF北方站长站

  然后运行:uJF北方站长站

  java ?verbose ?jar MyApp.jaruJF北方站长站

  加上verbose参数以确定我们确实用了这一套被搬出了家的JRE.uJF北方站长站

  程序可以运行,并且在命令行输出的前几行,可以看到:uJF北方站长站

  [Opened C:/MyApp/jre/lib/rt.jar]uJF北方站长站

  [Opened C:/MyApp/jre/lib/jsse.jar]uJF北方站长站

  [Opened C:/MyApp/jre/lib/jce.jar]uJF北方站长站

  [Opened C:/MyApp/jre/lib/charsets.jar]uJF北方站长站

  因此程序读取的确实是它的私有的JRE.uJF北方站长站

  至此,我们似乎完成了任务。但是现在我们的私有JRE仍不完美,缺点是太大。JRE 1.5有接近70MB,作为我们的私有的JRE,好多内容都是可以抛弃的。Jre目录下的license都可以不要,bin下的执行文件只需要保留java.exe或者javaw.exe,lib下只要保留rt,jsse, jce,charsets几个库就可以了。除了i386和zi两个子目录外,其余的子目录都可以不要。Zi下只需要保留自己地区的子目录和其下的一些文件就可以。Lib下除了库之外的属性文件等等都要保留。这样清理一番,JRE仍然有接近50MB.还可以继续清理几个库文件里面不需要的内容,这需要仔细的整理,会很费功夫。最好能写出一个自动工具帮助我们整理它们。从Sun公司上下到的JMF里面附带的用Java写的媒体播放器就自带了JRE,只有几个 MB.uJF北方站长站

  清理过后需要运行几遍我们的应用程序,以确保我们的JRE不缺少东西。uJF北方站长站

  如果我们希望能有一个程序直接启动我们的应用程序,那就还要费些功夫。最简单的方法是弄出一个快捷方式来,但是快捷方式的路径不能是相对的,不方便我们安装。我想到的方案就是用Win32程序包装一下。在VS.NET下写一个Win32小程序uJF北方站长站

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

  基本上是按照MSDN文档中的例子照搬的。将它编译成一个EXE文件,我们的任务才全部完成。双击这个EXE文件,我们的程序启动了,看起来和传统的Win32程序没有两样,JRE完全被隐藏在底层。uJF北方站长站

uJF北方站长站

 

News

 

info

 

down

出售手机裁听器,手机跟踪定位系统    企业网站,网城,购物网,都市导购,校园网    网上书店系统    上海电信机房服务器托管,双线主机托管    美女图片馆    15G 高清晰图片资源 无水印    室内装潢材料新产品杰威尔艺术漆    收一万ip的美女图片    大量收购个人网址导航网站    出售网址站PR=4alexa=119,764    

下一篇链接:Java JVM设置对性能的影响

上一篇链接:JAVA代码中使用魔法数值

评论】 【打印】 【加入收藏】 【关闭→论坛 →博客 →数据中心

 共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面