精简JRE的思路初探「建议收藏」

精简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打印到控制台。  精简JRE的思路初探「建议收藏」

 在上述的样例中,就列出全部依赖的类库。

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等来进行等。会更加可控和灵活。

   

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115957.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux如何改sftp端口,CentOS如何更改SFTP端口[通俗易懂]

    linux如何改sftp端口,CentOS如何更改SFTP端口[通俗易懂]SFTP(SSH文件传输协议)是一种安全文件协议,用于通过加密连接在两个主机之间传输文件。本文介绍了如何在Linux中更改默认的SFTP端口。我们还将向您展示如何配置防火墙以允许在新端口上使用。SFTP(SSH文件传输协议)是一种安全文件协议,用于通过加密连接在两个主机之间传输文件。它还允许您对远程文件执行各种文件操作并恢复文件传输。SFTP可以替代旧版FTP协议。它具有FTP的所有功能,但连接更…

    2025年11月18日
    3
  • Idea激活码教程,永久有效激活码2024.3.5绝对有效2024.3.5

    Idea激活码教程,永久有效激活码2024.3.5绝对有效2024.3.5Idea 激活码教程永久有效 2024 3 5 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2024 3 5 成功激活

    2025年5月21日
    8
  • Linux查看MySQL版本的四种方法

    Linux查看MySQL版本的四种方法1在终端下执行mysql-V2在help中查找mysql–help|grepDistrib3在mysql里查看selectversion()4在mysql里查看status欢迎补充~转自:https://www.linuxidc.com/Linux/2016-10/136075.htm…

    2025年7月12日
    2
  • 《生物化学与分子生物学》—-绪论—-听课笔记(一)

    《生物化学与分子生物学》—-绪论—-听课笔记(一)[华中科技大学]生物化学与分子生物学绪论1.1生物化学与分子生物学绪论(1)生物化学(Biochemistry、Biologicalchemistry):研究生物体(微生物、植物、动物及人体)的化学组成和生命过程中的化学变化规律的科学。 分子生物学(MolecularBiology):生物化学有机地融合了微生物学、遗传学和细胞生物学的有关知识—-形成了现代的分子生物学。它…

    2022年7月11日
    13
  • C语言基础知识:函数指针&指针函数(定义格式、作用及用法说明)[通俗易懂]

    C语言基础知识:函数指针&指针函数(定义格式、作用及用法说明)[通俗易懂]版权声明:本文为博主原创文章,未经博主允许不得转载。https://mp.csdn.net/postedit/83150266一、函数指针的实质(还是指针变量)1、函数指针定义格式:类型名 (*函数名)(函数参数列表);int(*pfun)(int,int);2、函数指针的定义、赋值、调用voidfunc1(void)//定义一个函数,以方便下面定义函…

    2022年6月22日
    30
  • CentOS 7安装VMware Tools「建议收藏」

    CentOS 7安装VMware Tools「建议收藏」在终端中配置:[root@localhost桌面]#cd/opt///进入opt目录下[root@localhostopt]#ls//列出目录下的文件rhVMwareTools-10.0.5-3228253.tar.gz[root@localhostopt]#tar-zxvfVMwareTools-10.0.5-3228253.tar.gz…..解压过程略过[root@localhostopt]#ls//列出目录下的文件…

    2022年5月20日
    33

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号