0%

Hello Jlink

概览

Java9在package之上引入了一个module(Java Platform Module System)的概念,一些相关的package和resources以及一个描述module的文件就构成了一个module。

假如我这里有一个简单的java程序:

1
2
3
4
5
6
7
8
9
10
import java.util.logging.Logger;

public class Main {
private static final Logger LOG = Logger.getLogger(Main.class.getName());

public static void main(String[] args) {
LOG.info("Hello JLINK and the fucking Modules!");
}
}

它只包含4个类:Logger,Main,String和Object,但是在java9之前,要想运行这个程序我们需要JRE的全部,即使是不需要的部分。这是一种浪费。

所以,一个可以自定义的JRE是最好的选择。

Demo

准备两个module:hello.modules和main.app

目录结构

─simple-module
├─hello.modules
│ └─module-info.java
│ └─eternal
│ └─fire
│ └─hello
└─main.app
│ └─module-info.java
└─eternal
└─fire
└─main

hello.modules

1
2
3
4
5
6
7
package eternal.fire.hello;

public class HelloModules {
public static void func() {
System.out.println("Hello, modules!");
}
}
1
2
3
module hello.modules {
exports eternal.fire.hello;
}

main.app

1
2
3
4
5
6
7
8
9
package eternal.fire.main;

import eternal.fire.hello.HelloModules;

public class MainApp{
public static void main(String[] args) {
HelloModules.func();
}
}
1
2
3
module main.app {
requires hello.modules;
}

编译

1
2
3
javac -d outDir --module-source-path simple-module simple-module/hello.modules/eternal/fire/hello/HelloModules.java

javac -d outDir --module-source-path simple-module simple-module/main.app/eternal/fire/main/MainApp.java

运行

1
2
java --module-path outDir --module main.app/eternal.fire.main.MainApp
Hello, modules!

查看依赖关系

1
2
3
4
5
6
7
8
9
jdeps --module-path outDir --module main.app
main.app
[file:///C:/Users/67460/Desktop/module-project/outDir/main.app/]
requires hello.modules
requires mandated java.base (@15)
main.app -> hello.modules
main.app -> java.base
eternal.fire.main -> eternal.fire.hello hello.modules
eternal.fire.main -> java.lang java.base

使用Jlink生成自定义JRE

1
2
3
jlink --module-path outDir --add-modules hello.modules,main.app --output jre

jlink --launcher jreLaucher=main.app/eternal.fire.main.MainApp --module-path outDir --add-modules main.app,hello.modules --output jreLauncher

两者的区别在于,后者可以自动生成运行的脚本。

运行自定义JRE

在jre/bin目录下和jreLauncher/bin目录下,分别运行

1
2
3
4
5
PS C:\Users\67460\Desktop\module-project\jre\bin> ./java --module main.app/eternal.fire.main.MainApp
Hello, modules!

PS C:\Users\67460\Desktop\module-project\jreLauncher\bin> .\jreLaucher
Hello, modules!