引言: 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的思路初探的更多相关文章

  1. Java 精简Jre jar打包成exe

    #开始 最近几天都在忙一个事情,那就是尝试精简jre,我想不明白为什么甲骨文官方不出exe打包工具... 网络上精简jre的文章很多,但是原创的似乎没几个,绝大多数都是转发同一个博客, 这里借鉴了不少 ...

  2. 整理JRE瘦身或精简JRE

    http://blog.csdn.net/xiaoping8411/article/details/6973887 版权声明:本文为博主原创文章,未经博主允许不得转载. 前不久给朋友做了一个桌面程序, ...

  3. PAT 1020 月饼 (25)(精简版代码+思路+推荐测试用例)

    1020 月饼 (25)(25 分)提问 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是 ...

  4. PAT 1024 科学计数法 (20)(精简版代码+思路+推荐测试样例)

    1024 科学计数法 (20)(20 分) 科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式[+-][1-9]"."[0-9]+E[+-][0-9]+, ...

  5. Java&.Net虚拟机精简(GreenJVM&GreenDotNet发布) .

    精简JRE体积的小工具:http://blog.csdn.net/cping1982/archive/2008/09/02/2865198.aspx 项目地址:http://code.google.c ...

  6. 玩转BLE(3)_使用微信蓝牙精简协议伪造记步数据

    1. 前言 在物联网时代,有一个问题肯定会让人头疼(现在已经初露端倪了): 物联网中的IOT设备有两个主要特点: 1)简单小巧(不具备复杂的人机交互接口,需要手机等终端设备辅助完成配置.控制等功能). ...

  7. [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  8. Java安装程序制作

    对于Java桌面应用来说,比较烦琐的就是安装部署问题,如:客户端是否安装有jre.jre版本.jre在哪里下载.如何用jre启动 Java应用等等.不要说刚接触电脑的人,就算是比较熟悉电脑,如果没有接 ...

  9. 使用exe4j把JAVA GUI程序打包成exe文件时遇到的问题

    1.把项目打包成jar文件时,只要勾选src目录就行了,其他的比如资源文件和jar包是不能添加进去的. 2.在D盘建一个文件夹,最好与项目同名,然后把打包好的jar包放进去,其他资源文件(图片之类的) ...

随机推荐

  1. Python学习笔记5-字符串、bool、数值操作和数组字典排序

    1.字符串 # 字符串数字之间转换 # x = int("6") # print type(x) #<type 'str'> # y = str(6) # print ...

  2. Neutron数据库同步错误 NotImplementedError: No support for ALTER of constraints in SQLite dialect

    错误信息 root@controller:~# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron. ...

  3. ACM/ICPC2014鞍山现场赛E hdu5074Hatsune Miku

    题目链接:pid=5074">http://acm.hdu.edu.cn/showproblem.php?pid=5074 题意: 给定一个m*m的矩阵mp.然后给定一个长度为n的序列 ...

  4. openstack之horizon源码分析之二

    一.概述: django基础入手: django新建project:#django-admin startproject mysite 生成如下目录: mysite ├── manage.py └── ...

  5. javascript高级知识点——闭包

    代码信息来自于http://ejohn.org/apps/learn/. 先给出一个权威的定义,函数对象可以通过作用域相互关联起来,函数体内的变量可以保存在函数的作用域内,这种特性称为闭包. 在闭包内 ...

  6. Mschart绘制图表之X轴为时间的设置方式

    最近使用C#开发图表,比较了DirectorChart,DontNetCharting,TeeChart,最终选用微软的mschart开发,对于X轴作为时间轴探索了好久,终于实现了想要的效果. 界面效 ...

  7. linux下不重启加硬盘

    linux下热加载磁盘 临时给虚拟机加了一块硬盘,增加后懒得重启,于是看了看热加载 [root@centos5 ~]# cat /proc/scsi/scsi Attached devices: Ho ...

  8. Eclipse 浏览文件插件- OpenExplorer

    http://blog.csdn.net/w709854369/article/details/6599167 EasyExplorer  是一个类似于 Windows Explorer的Eclips ...

  9. iOS根据2个经纬度计算距离

    #pragma mark - calculate distance 根据2个经纬度计算距离 #define PI 3.14159265358979323 +(double) CalculationDi ...

  10. User cannot be resolved to a type

    出现 User cannot be resolved to a type 不知道具体问题出在哪里但是我经过将全路径输入并保存后错误消失 将User选上,然后点击保存就可以了! 最后我发现错误消失了!