java在桌面软件的失利,很大程度上取决与她运行环境的陪着复杂度,还有随时带的一个庞大的jre环境。有时候我们并不需要jre中全部的类库支持,我们只需要一些对我们项目有用的类库,能否有一种通用的方法来抽取jre中的这些对我们有用的部分呢?google了下找到了几篇文章介绍这个的。主要就是用verbose参数运行jar,然后观察java载入了多少java类,然后手动或者写个程序自动的吧这些类打包和jvm打包为一个全新的jre环境。这种方法是可行的,但是却是不通用,而且这种方法还有一个很大的弊端,当有些类导入到我们项目中,但是在verbose的时候没有用到(比如一些异常类),我们就不会导入,最终可能在发布运行的时候就用到了,这样可不妙。那么是否还有其他方法来瘦身jre环境呢,然后通过随身附带jre发布java程序?答案一定是有的,我已经着手在开发这个应用,我把她起名为BuildJre。
一,可行性分析(我们加上在win系统下):
java.exe是java运行的一个入口程序,当我们键入明了 java className的时候,首先启动都是这个程序,然后这个程序回去查找可用的jre库,一般是先搜索本目录和父亲目录,如果接着搜索环境变量,判断是否为jre的依据是,首先java.exe查找怀疑目录(比如父目录)的bin下有没有java.dll,如果找到,那么他就判定这个是jre目录然后查找lib\i386下的jvm.cfg,最后更具这里面的参数去启动bin\client或者bin\server下的jvm.dll,这个才是真正的java虚拟机,到这里,java.exe把控制权全部交给jvm,然后jvm就初始化,分配内存等,运行程序了,运行程序期间导入的jdk包,都在jre目录下的lib\rt.jar下。
说道这里,我们发现,其实不用环境变量,只要有jre环境就能运行java程序,这使得我们更加坚定java程序也可以桌面化,因为他也是可以不用配置那么麻烦的环境变量直接运行的。再回到瘦身来,刚才说了,jdk中所有的以来包全部位于jre\lib\rt.jar下,我们要廋的就是这个,40多M的rt,我们通过类依赖抽取,对于一个普通的java程序,预计可以廋到小于10M,然后配合java.exe,java.dll,等几个小的程序,预计目标是平均廋身到15M以内。
二,实施思路,用verbose方法不通用,不能在程序内部抽取jre,而且还有可能遗漏依赖项,不足提倡。我们架设有一个标志的依赖说明库,比如ArrayList这个类依赖的所有包都一一对应,那么我们如果在程序里import ArrayList的话,那么我们可以迅速抽取相关的依赖包,然后在整个项目的所有import中去重复,不就ok了?现在的问题在于:
1,不是所有的jdk包都需要import的,比如java.lang下就不用import
2,有些jdk内部类在同一个包下不用写import也一样依赖。
3,计算jdk内部依赖估计要很长实践,因为文件很多,依赖很复杂。
这些问题基本上都有解决方法,我已经开始着手解决。
希望有一天,我们的java项目发布,只要带上10M的小型环境,也不用配置环境变量,双击,ok。。哈哈
--InstantMVC:j2ee轻量级mvc框架