整理JRE瘦身或精简JRE
前不久給朋友做了一個桌面程序,程序文件沒多大,但運行java程序需要jre,但jre足足有80M多,然后在網上搜了如何給給JRE瘦身或精簡JRE,整理如下:
打開JRE安裝目錄.目錄包括bin,lib二個文件夾,所以就是將這兩個文件進行瘦身了,
1. bin: 可以認為這是Java虛擬機.
2. lib: 執行class文件時,Java虛擬機需要用到的類庫及資源文件.
一、bin瘦身主要從兩方面考慮
① exe文件,最主要的工具是java.exe,它用來執行class文件,如果只是為了單純運行Java程序的話,其他可執行文件一般都是用不到的(可剔除).
② DLL文件,是java.exe執行class文件過程中調用的,執行class文件,java.exe需要哪個庫文件就加載哪個dll,不需用的可以剔除.
我們要做的就是找到哪些DLL文件是有用?我們運行一個Java文件看看,可以利用360安全衛士得到
1、準備java文件:
/* @author jarg @TODO 舉例查看當前程序必需的dll文件 */ import java.io.InputStreamReader; import java.io.IOException; public class Hello { public static void main(String[] args) throws IOException { InputStreamReader ir = new InputStreamReader(System.in); System.out.println("Hello"); ir.read(); } } 2、編譯、運行
3、360安全衛士 -> 功能大全 -> 進程管理器 右上角的顯示加載到當前選中進程中的dll
4、這樣我們留下java.exe、有用的dll文件和client目錄就行
到這里bin的瘦身成功!
二、lib的瘦身
① lib目錄最主要的類庫是rt.jar,是任意Java程序所必需的類庫.
lib目錄大約62MB,但是rt.jar類庫就占了47MB,可見精簡bin目錄,最主要是裁剪rt.jar.
② lib目錄下一個運行Java程序不可或缺的文件是位于i386下的虛擬機配置文件jvm.cfg.該配置文件用來管理不同版本的jvm.dll.其內容作為java.exe,javac.exe的全局變量,用來加載相應的動態鏈接庫文件.
③ lib目錄里面除了包含程序運行所需要的類庫及配置文件外,還包含有一些諸如: 鼠標光標,字體等系統資源.簡單程序如果未用到這部分資源的話,可以剔除.如果程序除去JRE部分,占用空間較大的話,為了避除資源加載錯誤帶來的麻煩,建議保留這不到20MB的配置文件內容.
主要步驟如下:
1、提取我們需要的類庫(jar),借助-verbose命令,查看虛擬機在運行Java程序時所加載的所有類,如:
@echo off C:/Java/jdk1.6.0_16/bin/java -jar -classpath lib/*.jar; -verbose:class printSoft.jar >> class.txt pause在class.txt文件中保存如下的信息:
[Loaded java.lang.Math from shared objects file] [Loaded java.nio.charset.Charset$3 from C:\Java\jdk1.6.0_16\jre\lib\rt.jar] [Opened C:\Java\jdk1.6.0_16\jre\lib\charsets.jar] [Loaded sun.nio.cs.AbstractCharsetProvider from C:\Java\jdk1.6.0_16\jre\lib\rt.jar] [Loaded sun.nio.cs.ext.ExtendedCharsets from C:\Java\jdk1.6.0_16\jre\lib\charsets.jar] [Loaded java.lang.Class$1 from shared objects file] [Loaded sun.reflect.ReflectionFactory$1 from shared objects file] [Loaded sun.reflect.NativeConstructorAccessorImpl from shared objects file]我們可以從class.txt中得到我們需要的jar文件和class文件,提交jar很簡單,我就不說了,下面我們在看看如何提交我們用到的class文件:
由于class.txt每行都是形同: [Loaded java.lang.System from shared objects file]的一串字符,修改文本以方便獲取類完整名java.lang.System,從而獲得類似類路徑java/lang/System的一串字符,方便后繼編寫類拷貝程序.
修改方法:
1. 查找并替換[Loaded 為空,達到刪除[Loaded 的目的.
2. 使用任意一個具有正則表達式查找替換功能的文本編輯器,查找并替換 from.*為空,達到刪除 from及其后面的字符串的目的.
3. 查找并替換.為/
4. 刪除以[Opened 開頭的行.
5. 刪除程序中System.out.println的輸出行.
提取之后class.txt就剩下如下信息:
java/lang/Object java/io/Serializable java/lang/Comparable java/lang/CharSequence java/lang/String java/lang/reflect/GenericDeclaration .......
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; public class CopyClass { private String source = "C:\\Users\\lzp\\Desktop\\printSoft\\jre6\\lib\\"; // 類源目錄 private String dest = "C:\\Users\\lzp\\Desktop\\printSoft\\jre6\\lib\\"; // 類拷貝目的目錄 String[] jarArr = new String[]{"rt","charsets"}; /*** * * @param source 類源目錄 * @param dest 類拷貝目的目錄 * @param jarArr 需要的提取的jar文件 */ public CopyClass(String source,String dest,String[] jarArr){ this.source=source; this.dest=dest; this.jarArr=jarArr; } public static void main(String[] args) { String[] jarArr = new String[]{"rt","charsets"}; CopyClass obj = new CopyClass("C:\\Users\\lzp\\Desktop\\printSoft\\jre6\\lib\\", "C:\\Users\\lzp\\Desktop\\printSoft\\jre6\\lib\\",jarArr); obj.readAndCopy("C:\\Users\\lzp\\Desktop\\printSoft\\class.txt"); } /*** * @param logName 提取class明細 */ public void readAndCopy(String logName) { int count = 0; // 用于記錄成功拷貝的類數 try { FileInputStream fi = new FileInputStream(logName); InputStreamReader ir = new InputStreamReader(fi); BufferedReader br = new BufferedReader(ir); String string = br.readLine(); while(string != null) { if(copyClass(string) == true) count++; else System.out.println("ERROR " + count + ": " + string); string = br.readLine(); } } catch (IOException e) { System.out.println("ERROR: " + e); } System.out.println("count: " + count); } /*** * 從原jar路徑提取相應的類到目標路徑,如將java/lang/CharSequence類從rt目錄提取到rt1目錄 * @param string 提取類的全路徑 * @return * @throws IOException */ public boolean copyClass(String string) throws IOException { String classDir = string.substring(0,string.lastIndexOf("/")); String className = string.substring(string.lastIndexOf("/")+1,string.length()) + ".class"; boolean result =false; for(String jar : jarArr){ File srcFile = new File(source + "/"+jar+"/" + classDir + "/" + className); if(!srcFile.exists()) { continue; } byte buf[] = new byte[256]; FileInputStream fin = new FileInputStream(srcFile); /* 目標目錄不存在,創建 */ File destDir = new File(dest + "/"+jar+"1/" + classDir); if(!destDir.exists()) destDir.mkdirs(); File destFile = new File(destDir + "/" + className); FileOutputStream fout = new FileOutputStream(destFile); int len = 0; while((len = fin.read(buf)) != -1) { fout.write(buf,0,len); } fout.flush(); result = true; break; } return result; } } 然后在將提取的class文件打包成jar文件,利用jar命令進行打包,然后替換以前的jar文件,這樣lib就從以前的六十多M到幾M多有,如圖:
這樣我們就完成了jre的瘦身!
總結
以上是生活随笔為你收集整理的整理JRE瘦身或精简JRE的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux服务器上的cad病毒,Linu
- 下一篇: 一、安卓系统源码下载