ModiTect - 用于 Java 9模块系统的工具

版本 1.0.0. Beta1 - 2018-03-18

ModiTect项目旨在为使用 Java 9模块系统("") 提供高效工具。

目前支持以下任务:

手工编写模块描述符相比,使用ModiTect可以根据项目依赖项定义依赖项,描述导出和打开的包,并使用模式( 而不是单独列出所有软件包) 。自动检测服务用法和更多的功能来保存。 你还可以使用ModiTect在project上添加模块描述符,同时使用自己的构建来添加 Java 。

在未来的版本功能中,可以添加功能和其他工具,比如 Maven 和其他依赖管理工具,以舒适的方式使用。

用法

moditect的功能目前仅通过 Maven 插件公开。 核心实现是单独的模块,因此可以编写其他构建系统( 比如 Gradle )的Plug-Ins 。

生成 module-info.java-描述符

要为给定工件创建 module-info.java 描述符,请按如下所示配置 generate-module-info 目标:


...


<plugin>


 <groupId>org.moditect</groupId>


 <artifactId>moditect-maven-plugin</artifactId>


 <version>1.0.0.Beta1</version>


 <executions>


 <execution>


 <id>generate-module-info</id>


 <phase>generate-sources</phase>


 <goals>


 <goal>generate-module-info</goal>


 </goals>


 <configuration>


 <modules>


 <module>


 <artifact>


 <groupId>com.example</groupId>


 <artifactId>example-core</artifactId>


 <version>1.0.0.Final</version>


 </artifact>


 <additionalDependencies>


 <dependency>


 <groupId>com.example</groupId>


 <artifactId>example-extended</artifactId>


 <version>1.0.0.Final</version>


 </dependency>


 </additionalDependencies>


 <moduleInfo>


 <name>com.example.core</name>


 <exports>


!com.example.core.internal*;


 *;


 </exports>


 <requires>


 static com.some.optional.dependency;


!com.excluded.dependency;


 *;


 </requires>


 <uses>


 com.example.SomeService;


 </uses>


 <addServiceUses>true</addServiceUses>


 </moduleInfo>


 </module>


 <module>


. . .


 </module>


 </modules>


 </configuration>


 </execution>


 </executions>


</plugin>


...

这将在 target/generated-sources/com.example.core/module-info.java 生成一个模块描述符。

对于要处理的每个模块,存在以下配置选项:

还可以直接运行这里目标,以如下方式指定不同的选项作为JVM参数:



mvn moditect:generate-module-info 


 -Dmoditect.artifact=com.example:example-core:1.0.0.Final 


 -Dmoditect.moduleName=com.example.core 


 -Dmoditect.additionalDependencies=com.example:example-extended:1.0.0.Final -Dmoditect.exportExcludes=com.example.core.internal..* 


 -Dmoditect.addServiceUses=true





将模块描述符添加到项目 jar

要向当前 Maven 项目生成的jar 添加模块描述符,请按如下所示配置 add-module-info 目标:


...


<plugin>


 <groupId>org.moditect</groupId>


 <artifactId>moditect-maven-plugin</artifactId>


 <version>1.0.0.Beta1</version>


 <executions>


 <execution>


 <id>add-module-infos</id>


 <phase>package</phase>


 <goals>


 <goal>add-module-info</goal>


 </goals>


 <configuration>


 <jvmVersion>9</jvmVersion>


 <module>


 <moduleInfo>


 <name>com.example</name>


 <exports>


!com.example.internal.*;


 *;


 </exports>


 </moduleInfo>


 </module>


 </configuration>


 </execution>


 </executions>


</plugin>


...

可选 jvmVersion 元素允许定义模块描述符应该创建哪个JVM版本。 定义时,模块描述符将被放入 META-INF/versions/${jvmVersion},否则将放入 final jar的root 中。

<module> 配置元素存在以下配置选项:

注意,如果没有将 Java 9模块迁移到自己的版本中,那么可以在 Java 8上使用 moduleInfoSourcemoduleInfoFile 来添加Java模块描述符。 moduleInfo 只能在 Java 9或者更高版本上使用。

向现有 jar-文件添加模块描述符

要为给定的依赖项添加模块描述符,请按如下所示配置 add-module-info 目标:


...


<plugin>


 <groupId>org.moditect</groupId>


 <artifactId>moditect-maven-plugin</artifactId>


 <version>1.0.0.Beta1</version>


 <executions>


 <execution>


 <id>add-module-infos</id>


 <phase>generate-resources</phase>


 <goals>


 <goal>add-module-info</goal>


 </goals>


 <configuration>


 <outputDirectory>${project.build.directory}/modules</outputDirectory>


 <modules>


 <module>


 <artifact>


 <groupId>com.example</groupId>


 <artifactId>example-core</artifactId>


 <version>1.0.0.Final</version>


 </artifact>


 <moduleInfoSource>


 module com.example.core {


 requires java.logging;


 exports com.example.api;


 provides com.example.api.SomeService


 with com.example.internal.SomeServiceImpl;


 }


 </moduleInfoSource>


 </module>


 <module>


. . .


 </module>


 </modules>


 </configuration>


 </execution>


 </executions>


</plugin>


...

对于要处理的每个模块,存在以下配置选项:

模块化 jars 可以在 outputDirectory 提供的文件夹中找到。

创建模块运行时映像

要创建模块运行时映像( 请参见 JEP 220 ),请按如下所示配置 create-runtime-image 目标:


...


<plugin>


 <groupId>org.moditect</groupId>


 <artifactId>moditect-maven-plugin</artifactId>


 <version>1.0.0.Beta1</version>


 <executions>


 <execution>


 <id>create-runtime-image</id>


 <phase>package</phase>


 <goals>


 <goal>create-runtime-image</goal>


 </goals>


 <configuration>


 <modulePath>


 <path>${project.build.directory}/modules</path>


 </modulePath>


 <modules>


 <module>com.example.module1</module>


 <module>com.example.module2</module>


 </modules>


 <excludedResources>


 <pattern>glob:/com.example/**</pattern>


 </excludedResources>


 <baseJdk>version=9,vendor=openjdk,platform=linux-x64</baseJdk>


 <launcher>


 <name>helloWorld</name>


 <module>com.example.module1</module>


 </launcher>


 <outputDirectory>


 ${project.build.directory}/jlink-image


 </outputDirectory>


 </configuration>


 </execution>


 </executions>


</plugin>


...

存在以下配置选项:

创建映像后,可以通过运行以下命令执行该映像:



./<outputDirectory>/bin/java --module com.example





或者,如果已经配置启动器:



./<outputDirectory>/bin/<launcherName>





示例

Undertow

IntegrationTest/undertow 中的POM文件显示了更完整的示例。 Undertow内核中添加了模块描述符,并对它的进行了依赖,使之能够基于 Java 9模块运行 Undertow web服务器。

运行



cd integrationtest/undertow


mvn clean install





来生成该示例。然后可以通过执行以下命令启动 Undertow



java --module-path target/modules --module com.example





或者,可以运行由示例创建的模块运行时映像:



./target/jlink-image/bin/helloWorld





然后访问浏览器中的 http://localhost:8080/?name=YourName 插件,以获取规范的。

Vert.x

IntegrationTest/vertx 中的POM文件显示了更完整的示例。 它为 Vert.x 添加模块描述符for它的依赖关系( 联网的Jackson ),并使用"Hello World"verticle创建一个模块运行时映像。

执行



cd integrationtest/vert.x


mvn clean install -Pjlink





生成示例。

然后,你可以像这样运行模块化运行时映像:



./target/jlink-image/bin/helloWorld





然后访问浏览器中的 http://localhost:8080/?name=YourName 插件,以获取规范的。

运行时映像的大小为 45 MB,可以以通过几个调整相关的库进一步改进。 在数据转换器 unconditionally 比如 databind pulls pulls unconditionally java.sql databind pulls unconditionally unconditionally数据转换器与 java.sql 类型 optional optional 。

使用 Docker

Vert.x 示例也可以在 Docker 上运行。 为此,请使用"docker基础"配置文件运行生成:



mvn clean install -Pdocker-base





这将创建一个名为 moditect/vertx-helloworld-base的图像,其中包含jlink图像。 运行映像执行



docker run --rm -t -i -p 8080:8080 moditect/vertx-helloworld-base





对应用程序的更改将需要重建整个jlink映像,如果应用程序本身更改但不是依赖项( 。使用的JDK模块或者 3 rd模块) 。 因此,可以使用"Docker"配置文件生成另一个映像:



mvn clean install -Pdocker





这将创建名为 _moditect/vertx-helloworld的图像,扩展基础映像,并在升级模块路径中添加应用程序模块( com.example ) 。 因此,一旦基础图像到位,就可以快速生成( 和分布式) 。 运行映像执行



docker run --rm -t -i -p 8080:8080 moditect/vertx-helloworld





状态

ModiTect处于开发的早期阶段,它仍然有一些粗糙的边缘。 用你自己的风险。

进一步计划的功能

将模块描述符添加到现有 jars 是ModiTect中实现的第一个功能。 潜在的未来发展包括:

相关工作

使用 Remi Forax的ModuleTools 演示如何使用ASM来组装模块描述符。

许可证

ModiTect是在Apache许可版本 2.0下许可的。 ASM ( 它包含在 org/moditect/internal/shaded/asm/ 包中的ModiTect jar 中) 是在 3子句BSD许可证( 请参见 etc etc/license_asm 。txt ) 下许可的。