精简JRE的思路初探
引言: JRE是Java程序赖以执行的基础环境,眼下JRE已经很的庞大;即使为了执行一个简单的Hello World的程序。可能依旧须要依赖整个JRE,将近百兆大小的依赖性。
能否够对特定Java程序依赖的JRE进行精简呢? 当然是能够。依据当前代码的须要,动态精简JRE,仅仅依赖须要的class。而非所有。
1. 总体的思路
a. 首先找到当前Java程序依赖的全部class,包含自身类库/第三方类库,以及JRE中的类库。
b. 将JRE中不须要的类库文件移除掉,仅仅保留须要的类库。
C. 将保留下的类库又一次打包。替换已有的JRE文件
2. 寻找所需的JRE中的类库文件
在执行Java应用的过程中,能够针对JVM加入參数[-XX:+TraceClassLoading],则应用在启动过程中,会将全部的所需的class打印到控制台。
在上述的样例中,就列出全部依赖的类库。
2. 怎样提取须要的类库或者移除不须要的类库
这里我们採用前者,仅仅提取所需的类库。
jar xvf xxx.jar classname1 classname2 ....
这个命令就会把须要的class从jar中提取出来,拷贝到本地当前文件夹。
3. 将这些类库进行打包,替换掉JRE中相应的类库
jar cvf target.jar sourcefolder1 classfolder2 ...
打包命令,将classfolder中的类库,打包为target.jar.
4. 那代码上怎样。利用上述的仅仅是完毕自己主动化打包 JRE相应的类库呢?
方案例如以下:
4.1. 基于执行过程中的Java參数-XX:+TraceClassLoading,打印出所用在JRE中用到的java类
4.2. 捕获从控制台输出的class列表
4.3. 利用jar自带的功能。从rt.jar中提取对应的所须要的class
4.4. 将rt.jar中提取的class进行打包,就可以得到所需的jre核心jar包。
代码假定的前提:
1. Jre所在的路径
2. 目标java类已经编译成class.这里未考虑动态编译的情况
3. 将jre中的rt.jar打包在当前路径。
演示样例代码例如以下:
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List; public class RunClass { public static void main(String[] args) throws IOException {
List<String> classes = new ArrayList<String>(); String[] cmdB = { "java", "-XX:+TraceClassLoading", "MainTest" };
Runtime runtime = Runtime.getRuntime(); Process process = Runtime.getRuntime().exec(cmdB);
// /process = Runtime.getRuntime().exec(cmdB);
LineNumberReader br = new LineNumberReader(new InputStreamReader(
process.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
String className = RunClass.parseClass(line);
if (className.length() > 0) { sb.append(className.replace(".", "/")).append(" ");
classes.add(className.replace(".", "/"));
}
} System.out.println("classes to be packed in size:" + classes.size()); classes.add(0, "/opt/jdk7/jre/lib/rt.jar");
classes.add(0, "xvf");
classes.add(0, "jar"); Process jarClass = runtime.exec((String[]) classes
.toArray(new String[classes.size()]));
LineNumberReader br1 = new LineNumberReader(new InputStreamReader(
jarClass.getInputStream()));
StringBuffer sb1 = new StringBuffer();
String line1;
while ((line1 = br.readLine()) != null) {
System.out.println("extracting:" + line1);
}
System.out.println(classes.size()
+ " classes have been extracted successfully"); String[] cmdJarPackage = { "jar", "cvf", "rt.jar", "com", "java",
"javax", "META-INF", "org", "sun", "sunw" };
Process jarProcess = runtime.exec(cmdJarPackage); System.out
.println("Jar the classes into a package rt.jar successfully."); } public static String parseClass(String lineStr) {
String keyStr = ""; if (lineStr.startsWith("[Loaded")) {
String[] keys = lineStr.split(" "); if (keys.length == 4) {
keyStr = keys[1];
}
} return keyStr;
} }
5. 总结
JRE在jDK8中已经对其进行了模块化设计,从而使按需载入和定制JRE成为可能。这里的演示样例代码仅仅是简单示意了流程,离真正的工具化还有较大差距;基本的原因是大量使用了Runtime.exec方法来直接调用命令,这样不是非常灵活和可控;比方打包和解压能够利用JarOuputStream, JarInputStream等来进行等。会更加可控和灵活。
精简JRE的思路初探的更多相关文章
- Java 精简Jre jar打包成exe
#开始 最近几天都在忙一个事情,那就是尝试精简jre,我想不明白为什么甲骨文官方不出exe打包工具... 网络上精简jre的文章很多,但是原创的似乎没几个,绝大多数都是转发同一个博客, 这里借鉴了不少 ...
- 整理JRE瘦身或精简JRE
http://blog.csdn.net/xiaoping8411/article/details/6973887 版权声明:本文为博主原创文章,未经博主允许不得转载. 前不久给朋友做了一个桌面程序, ...
- PAT 1020 月饼 (25)(精简版代码+思路+推荐测试用例)
1020 月饼 (25)(25 分)提问 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是 ...
- PAT 1024 科学计数法 (20)(精简版代码+思路+推荐测试样例)
1024 科学计数法 (20)(20 分) 科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+, ...
- Java&.Net虚拟机精简(GreenJVM&GreenDotNet发布) .
精简JRE体积的小工具:http://blog.csdn.net/cping1982/archive/2008/09/02/2865198.aspx 项目地址:http://code.google.c ...
- 玩转BLE(3)_使用微信蓝牙精简协议伪造记步数据
1. 前言 在物联网时代,有一个问题肯定会让人头疼(现在已经初露端倪了): 物联网中的IOT设备有两个主要特点: 1)简单小巧(不具备复杂的人机交互接口,需要手机等终端设备辅助完成配置.控制等功能). ...
- [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- Java安装程序制作
对于Java桌面应用来说,比较烦琐的就是安装部署问题,如:客户端是否安装有jre.jre版本.jre在哪里下载.如何用jre启动 Java应用等等.不要说刚接触电脑的人,就算是比较熟悉电脑,如果没有接 ...
- 使用exe4j把JAVA GUI程序打包成exe文件时遇到的问题
1.把项目打包成jar文件时,只要勾选src目录就行了,其他的比如资源文件和jar包是不能添加进去的. 2.在D盘建一个文件夹,最好与项目同名,然后把打包好的jar包放进去,其他资源文件(图片之类的) ...
随机推荐
- android从网络获取图片
http://blog.csdn.net/wangjinyu501/article/details/8219317 http://www.cnblogs.com/JerryWang1991/archi ...
- 论山寨手机与Android 【13】SmartPhone AP系统
在第9章中我们提到,从功能上讲对于智能手机的一个粗略的概括是,智能手机 == 电脑 + 移动网卡,或者更准确地说,智能手机的硬件结构分为应用程序处理器AP,和基带处理器BP两个部分.这里隐含着两个问题 ...
- IIS7性能优化:启用浏览器本地缓存
原文地址:http://jingyan.baidu.com/article/597035521b96e88fc00740af.html
- Coursera-Neural Networks by Geoffrey Hinton
feed-forward networks symmetrically-connection neural networks
- [置顶] 自娱自乐6之Linux gadget驱动5(自编gadget驱动,包涵与之通讯的主机usb驱动,已调试通过)
这个代码调试,你首先要保证你的udc驱动没用问题,这个有些矛盾,应为我本来要用gadget驱动来调试udc驱动,结果反过来了. 这是在zero基础改的,大概的改动 1. 去掉loop. 2. sink ...
- 关于oracle的certview
前两天去参加oracle 11g 的两门考试(1Z0-051和1Z0-052),在家看了好几遍题库,我本来想着上午一门,下午考一门,但是我嫌着麻烦,就预约一下午考完两门.在考试完一门后,发现成绩不 ...
- html系列教程--DOCTYPE a area
<!DOCTYPE>标签:<!DOCTYPE> 声明不是 HTML 标签:它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令.在 HTML 4.01 中,& ...
- ASP.NET动态引用WebService接口
尊重原著作:本文转载自http://www.mhzg.net/a/20124/20124912180589.html 有经验的朋友都知道,通常我们在引用webservice的时候,是在项目中就添加了引 ...
- TCP/IP协议族
1.TCP(传输控制协议)/IP(网际协议)协议族是一个网络通讯模型,以及一整个网络传输协议家族,为互联网的基础通讯架构. TCP/IP四层协议的表示方法: 2.TCP/IP参考模型映射到OSI模型: ...
- FPGA开发(1)
`timescale ns / ns module system_ctrl ( //globol clock input clk, input rst_n, //synced signal outpu ...