存在这样的情况:
写一个Java程序,然后交付别人使用,但别人的机器上不一定安装了jre(也就是Java 运行环境)
处理:
将程序打包为jar包,同时交付一份jre
再次发现的问题是jre体积太大:
我写的程序,例如程序导出的jar包或者再将jar包转成的.exe程序,体积并不大,但jre的体积却很大。
例如:
我的其他内容不到30M(包括程序导出的jar包不到0.2M,程序用到的第三方jar包一共是27M左右,一个配置文件大小可以不计)
上面可以看出一般我们写程序导出的jar包不会很大
但jre文件夹下的内容一共有150M还要多。
处理:所以我们要将jre精简一下,主要分为三个步骤
- 删去jre中bin目录下没有用到的dll文件和exe文件,或者说只保留有用的文件
- 删除jre中lib目录下没有用到的jar包
- lib目录下最大的jar包是rt.jar,大约50M,我们写程序所用到的基础类都在这里面,要精简rt.jar
具体方法:
首先记得要备份jre
在网上搜索”精简jre”,看了很多博客,有些不太详细。
有的是手动方法,要一点一点删,然后再运行,如果有问题,那就把删除的那一点再恢复…
下面要推荐我前两天看到了一个非常详细的博客,主要讲jre的精简
https://www.cnblogs.com/cjdty/p/9057845.html 亲测有效,过程就是前面提到的三个步骤,很详细
原博在精简rt.jar部分用到了另一条博客的代码,在这里也记录一下
https://blog.csdn.net/kkkwewewaqsdfas/article/details/11829349?t=1489849302000
我遇到的问题
1.就是第一步使用软件观察不到java.exe进程使用了哪些.dll文件。只有一次成功观察到了,并且成功精简了bin目录。然后其他时候就没观察到,不知道是什么问题
2.处理class.txt时,原作者提出用Notepad(这是一个文本编辑工具,比记事本的功能强大)删除不是以“[loaded” 开头的行,并且进一步获得每一行中的类,即下方标红的部分。
[Loaded java.lang.Object from D:\File\analysisPDF\analyse\jre1.8.0_66\lib\rt.jar]
我不是很会使用Notepad,原作者也没有具体说怎么操作的。
我是写程序处理每一行的字符串,很简单
将class.txt中以“[loaded” 开头的行写到另外一个文本文件中,我这里是output.txt
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test1 {
/**
* 读取a文件内容,将有"[Loaded"这个前缀的行,写入b文件中
*
*/
public static void read2writeFile() {
String pathname = "C:\\Users\\yc\\Desktop\\jre\\class.txt";
File writeName = new File("C:\\Users\\yc\\Desktop\\jre\\output.txt");
FileReader reader = null;
BufferedReader br = null;
FileWriter writer = null;
BufferedWriter out = null;
try {
reader = new FileReader(pathname);
br = new BufferedReader(reader);
writer = new FileWriter(writeName);
out = new BufferedWriter(writer);
String line = null;
int i = 0;
while ((line = br.readLine()) != null) {
//只需要有"[Loaded"这个前缀
if(line.startsWith("[Loaded")) {
i++;
out.write(line+"\r\n");
}
}
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(out != null)
out.close();
if(writer != null)
writer.close();
if(br != null)
br.close();
if(reader != null)
reader.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public static void main(String[] args) {
read2writeFile();
}
}
将output.txt文件中,每行中的类名单独取出来(标红部分),写到文件calss_name.txt中
[Loaded java.lang.Object from D:\File\analysisPDF\analyse\jre1.8.0_66\lib\rt.jar]
/**
* 将每一行按空白分割,然后取每行分割后的第二个字符串,存入class_name.txt中
*/
public static void test() {
String pathname = "C:\\Users\\yc\\Desktop\\jre\\output.txt";
File writeName = new File("C:\\Users\\yc\\Desktop\\jre\\class_name.txt");
FileReader reader = null;
BufferedReader br = null;
FileWriter writer = null;
BufferedWriter out = null;
try {
reader = new FileReader(pathname);
br = new BufferedReader(reader);
writer = new FileWriter(writeName);
out = new BufferedWriter(writer);
String line = null;
int i = 0;
while ((line = br.readLine()) != null) {
//按空白分割该行
String[] strs = line.trim().split("\\s+");
//因为每行的形式为双引号内的内容:"[Loaded java.io.Serializable from D:\\File\\analysisPDF\\analyse\\jre1.8.0_66\\lib\\rt.jar]"
//我们只需要分割后的第二个字符串:java.io.Serializable
out.write(strs[1]+"\r\n");
i++;
}
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(out != null)
out.close();
if(writer != null)
writer.close();
if(br != null)
br.close();
if(reader != null)
reader.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}