你的程序有多大?

你經常寫一些有趣的小程序麼?你想分發你的程序麼? 你怎麼保證目標機上有jre呢? 你打包一個? 一個jre幾十兆,若是大工程,帶個jdk也無所謂,如果你自己的類文件一共還沒有1兆,就要帶個幾十兆的jre,你能接受麼? 如果你想分發你的小程序,那麼我們來進行jre瘦身吧! 看看我們的HelloWorld最小能多小。

    jre帶的很多文件可能在你的程序裏並不需要,或者你的程序只需要某個幾兆大的jar裏面的一個class。所以,理論上我們可以對jre進行減肥運動。把你不需要的jar和文件刪掉,剩下的跟你的程序一起打個包。

下面以jdk5.0開發的一個HelloWorld爲例來簡單做個試驗。

開發我們的Hello軟件:
class 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兆的一個小程序包更加容易分發吧。

package cn.javadoc.jfit;

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

發佈了33 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章