jre帶的很多文件可能在你的程序裏並不需要,或者你的程序只需要某個幾兆大的jar裏面的一個class。所以,理論上我們可以對jre進行減肥運動。把你不需要的jar和文件刪掉,剩下的跟你的程序一起打個包。
下面以jdk5.0開發的一個HelloWorld爲例來簡單做個試驗。
開發我們的Hello軟件:
public static void main(String[] args){
System.out.println("Hello World!");
}
}
用java -verbose Hello 執行程序就能看到所有用到的class。當然,如果你的程序比較複雜,中間有條件跳轉的話,一次執行可能並不能將所有的可能用到的class打印出來。這個不是大問題,你可以嘗試別的辦法來找出所有用到的文件。
1。把這些class找出來。java -verbose Hello>G:/jdkfit/Hello.list
當然,用Runtime.exec("java -verbose Hello").getInputStream()來獲得輸出結果直接使用更好。
2。打個包。我們來寫個程序來完成這個任務吧。執行下邊這個Packager 程序。
3。拷貝一個jre,把我們自己打的jar覆蓋jre的rt.jar,用這個jre執行java Hello。最好做個bat文件(我做了個run.bat)。 試着刪除jre下的文件,看能不能run。直到最後,呵呵,只剩下這麼幾個了:
bin/java
bin/run.bat
bin/client/jvm.dll
lib/rt.jar (我們自己打的那個包)
lib/i386/jvm.cfg
共計大小:2.11兆
再來rar一下:1.123兆
呵呵 1.1兆的一個小程序包更加容易分發吧。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
public class Packager {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
File f = new File("G:/jdkfit/Hello.list");
Packager pkger = new Packager();
List ret = pkger.parseOutput(new FileInputStream(f));
pkger.debugEnabled = true;
pkger.pkgResources(ret, "G:/jdkfit/jar/Hello.jar");
}
private boolean debugEnabled;
public List parseOutput(InputStream in) throws IOException {
ArrayList ret = new ArrayList();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
while (line != null) {
if (line.matches("/[Loaded .* from .*")) {
if (debugEnabled)
System.out.println("Matches:" + line);
ret.add(line.substring(8, line.indexOf(" from ")));
} else{
if (debugEnabled)
System.out.println("UnMatches:" + line);
}
line = reader.readLine();
}
return ret;
}
public void pkgResources(List res, String fileName)
throws IOException {
File f = new File(fileName);
if (!f.exists()) {
f.createNewFile();
}
byte[] buf = new byte[1024];
JarOutputStream out = new JarOutputStream(
new FileOutputStream(fileName));
for (String s : res) {
s = s.replace('.', '/') + ".class";
if (debugEnabled) {
System.out.println("adding: " + s);
}
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream(s);
out.putNextEntry(new ZipEntry(s));
int w = in.read(buf);
while (w >= 0) {
out.write(buf, 0, w);
w = in.read(buf);
}
in.close();
}
out.finish();
out.close();
}
}
文章來源:http://www.javaresearch.org/article/99402.htm