在Gradle中为JPMS构建Java 6-8库

通过提供Java 9 module-info.class来了解如何使用Gradle构建支持JPMS( Java平台模块系统 )的Java 6-8库。

介绍

如果您需要JPMS本身的介绍,请查看此概述 。

这篇文章主要针对Java库维护者。

任何此类维护者都必须选择要针对的JDK:

  • 针对最新的JDK( JDK 11或刚刚发布的JDK 12 ),开发人员和用户可以使用新的API和更多功能。
  • 但是,这会阻止所有使用较旧JDK的用户使用该库。
    • 那些较老的JDK仍然受欢迎, 在2018年约占95%的份额 ,并预计在2019年将约90%的 份额 。

因此,对于许多图书馆维护者而言,后者无疑是一个决定性因素 。 例如, vavr 1.0 旨在以JDK 11为目标 ,但最终将以JDK 8为目标 。

尽管如此,还是建议为JPMS添加一些支持,以期将来会被广泛采用(我想从现在起5年以上)。 Stephen Colebourne在这里描述了三个选项:

  1. 不执行任何操作(不建议)。
  2. 最低要求:在MANIFEST.MF文件中添加一个“ Automatic-Module-Name条目。
  3. 最佳:添加一个针对JDK 9+的module-info.class同时提供所有其余针对JDK 6-8 *的类。

在这里,我们将深入研究如何实现选项3(最佳选择)。

*我写的是JDK 6-8(而不是JDK 5-8),因为在JDK 11中, javac--release选项限制为6-11。

理由

不过,在深入研究“如何”之前,让我们先略过“为什么”。

为什么JPMS完全值得打扰? 主要是因为JPMS:

  • 提供强大的封装 ,
  • 防止引入拆分包 ,
  • 确保更快的类加载 。

综上所述,JPMS 非常酷 (更多信息请参见此处 ),鼓励我们采用JPMS是我们的最大利益!

因此,我鼓励Java 6-8库的维护者充分利用JPMS:

  • 自己针对模块的JDK 6-8类和其他模块编译module-info.java
  • 对于他们的用户,通过提供module-info.class来使库在module-path上正常工作。

可能的行为

可以在两个位置找到module-info.java

  1. 与其他所有类,在src/main/java
  2. 在单独的“源集”中,例如src/main/java9

我喜欢选项1,因为它看起来更自然。

module-info.class可以在两个地方结束:

  1. 在根输出目录以及所有其他类中,
  2. META-INF/versions/9 (多发行版JAR,又名MRJAR )

阅读了塞德里克·尚波( CédricChampeau)关于MRJAR的帖子后 ,我对MRJAR颇为怀疑,因此我更喜欢选项1。

但是请注意, Gunnar Morling报告说选项1存在一些问题。另一方面,我希望距JDK 9发行1.5年后,所有主要库都已打补丁以正确处理module-info.class

每个构建工具的示例库

本节包含一些在针对JDK 6-8时提供module-info.class的库示例。

蚂蚁

  • Lombok (JDK 6 main + JDK 9 module-info.class

马文

  • ThreeTen-extra (JDK 8 main + JDK 9 module-info.class
  • Google Gson –尚未发布(JDK 6 main + JDK 9 module-info.class
  • SLF4J –尚未发布( META-INF/versions/9 JDK 6 main + JDK 9 module-info.class

请注意, Maven编译器插件提供了如何提供这种支持的示例 。

摇篮

我还没有找到任何流行的库使用Gradle提供这种支持(请注释,如果您知道的话)。 我只知道vavr试图这样做( #2230 )。

Gradle中的现有方法

修改

ModiTect (由Gunnar Morling编写 )及其Gradle插件 (由Serban Iordache编写 )具有一些非常酷的功能 。 本质上,ModiTect基于特殊符号或直接从module-info.java 生成 module-info.class -info.class, 而无需使用javac

但是,在从module-info.java直接生成的情况下,ModiTect有效地复制了javac所做的操作,同时引入了自己的问题(例如#90 )。 这就是为什么我觉得它不是最好的工具。

Badass Jar插件

Serban Iordache还创建了一个Gradle插件 ,该插件可以“无缝创建针对9之前的Java版本的模块化jar”。

看起来不错,但是:

  • 为了构建适当的JAR并验证module-info.java ,Gradle构建必须运行两次,
  • 它不使用javac--release选项,该选项保证仅引用正确的API,
  • 它不使用javac来编译module-info.java

同样,我觉得这里不是正确的工具。

JpmsGradlePlugin

这是我最近的发现: JpmsGradlePlugin由阿克塞尔Howind 。

该插件可以做一些不错的事情(例如,从javadoc任务中排除module-info.java ),但是:

  • 它也不使用javac--release选项,
  • 它不完全支持Java模块化(例如,模块修补),
  • 感觉还不够成熟( 难以遵循的代码,非标准行为,例如直接调用javac )。

Gradle中的拟议方法

摇篮脚本

最初,我想通过添加自定义源集来做到这一点 。 但是,事实证明,这种方法会引入不必要的配置和任务 ,而我们真正需要的只是一个额外的任务,它正确地“钩住”了构建生命周期 。

结果,我想到了以下几点:

  1. compileJava配置为:
    • 排除 module-info.java
    • 使用--release 6/7/8选项。
  2. 添加一个名为compileModuleInfoJava的新JavaCompile任务,并将compileModuleInfoJava配置为:
    • 仅包含 module-info.java
    • 使用--release 9选项,
    • 使用compileJava的类路径作为--module-path *
    • 使用compileJava *的目标目录 ,
    • 取决于 compileJava *

  3. 配置classes任务以依赖于compileModuleInfoJava

以上内容在Groovy DSL中表示为Gradle脚本,可以在我的Stack Overflow答案中找到。

*这三个步骤对于compileModuleInfoJava查看由compileJava编译的类是compileJava 否则,由于未解析的引用, javac将无法编译module-info.java 请注意,在这种配置中,每个类编译一次 (与推荐的Maven Compiler Plugin配置不同 )。

不幸的是,这样的配置:

  • 在存储库之间不容易重用,
  • 不完全支持Java模块化。

Gradle模块插件

最后,有一个插件( Gradle Modules Plugin ),它为Gradle添加了对JPMS的完全支持(由Java 9 Modularity的作者Sander Mak和Paul Bekker创建 )。

该插件仅不支持本文所述的方案。 因此,我决定:

  • 通过此插件提交功能请求: #72
  • 提供具有#72的完整实现的“拉取请求”(作为“概念证明”): #73

我尽力做出这些高质量的贡献。 最初的反馈意见非常受欢迎 (甚至Mark Reinhold都喜欢!)。 谢谢!

现在,我正在耐心地等待进一步的反馈 (以及潜在的改进要求),然后才能(希望)合并PR。

摘要

在本文中,我展示了如何使用Gradle构建Java 6-8库,以便将module-info.java编译为JDK 9格式(JPMS支持),而将所有其他类编译为JDK 6-8格式。

我还建议对这种配置使用Gradle Modules插件 (一旦我的PR合并并且发布了新的插件版本)。

翻译自: https://www.javacodegeeks.com/2019/03/building-java-6-8-libraries-jpms-gradle.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/343601.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql5.7.24怎么打开_mysql-5.7.24-winx64安装教程

5.2 配置环境右击此电脑-->点击属性-->点击高级系统设置-->点击环境变量(N)...-->点击系统变量(S)下面的新建-->1).第一行写MYSQL_HOME第二行写C:\Program Files\mysql-5.7.17-win322).点击系统变量中的path点击新建-->写入%MYSQL_HOME$\bin5.3进入cmd命令行…

如何解决光端机的开关量问题?

光端机开关量问题可以说是光端机的常见问题之一,对监控效果有比较大的影响,那么,我们应该如何解决光端机的开关量问题呢?接下来就由杭州飞畅科技的小编来为大家详细讲解下吧,感兴趣的朋友就一起来了解下! …

qq群发信息显示服务器检测到,关于如何突破QQ群发消息屏蔽或限制经验总结

文章导读:本文主要介绍关于如何突破QQ群发消息屏蔽或限制经验总结 ,包括:WebQQ发送消息很多人反映说消息收不到啊,发布多久就屏蔽了。其实我还是那句老话。当你短时间在同一个IP段之内发送这么多消息,明眼人都知道你这…

mysql 授权访问_windows开启3306端口并用可视化工具访问远程mysql(授权访问)

开启 MySQL 的远程登陆帐号有两大步:1、确定服务器上的防火墙没有阻止 3306 端口。MySQL 默认的端口是 3306 ,需要确定防火墙没有阻止 3306 端口,否则远程是无法通过 3306 端口连接到 MySQL 的。如果您在安装 MySQL 时指定了其他端口&#xf…

微信小程序服务器请求post,微信小程序使用HTTP请求_绕过HTTPS_云函数 request-promise get、post...

request-promise GET 请求1、云函数中> 云函数的console.log();只能在云函数的日志中查看,不会打印到控制台上,以为云函数不是本地// 云函数入口文件const cloud require(wx-server-sdk)//引入request-promise用于做网络请求var rp require(request-promise);c…

什么是电视光端机?电视光端机是怎么分类的?

现如今,随着国内通信网络的发展,电视光端机应用的监控范围也越来越广。在高速公路、银行、电力、电信等的监控领域都要求对视频信号进行远程的传输,目前主要的解决方法是利用光端机将视频信号转化为数字信号通过光纤进行传输。那么&#xff0…

q7goodies事例_Java 8 Friday Goodies:Lambda和排序

q7goodies事例在Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 ,现在我们觉得是时候开始一个…

mysql存储过程语法 if_mysql存储过程语法 if

MySql存储过程MySQL 存储过程是从 MySQL 5.0 开始增加的新功能。存储过程的优点有一箩筐。不过最主要的还是执行效率和SQL 代码封装。特别是 SQL 代码封装功能,如果没有存储过程,在外部程序访问数据库时(例如 PHP),要组织很多 SQL 语句。特别…

服务器突然关机的操作系统日志,一台R410 服务器不定时宕机,系统日志只有“上一次系统是意外关闭”...

R410环境操作系统 windows server 2008 r2 (一开始是windows server 2003)两个CPU:E5504内存:64G (4条16GB)故障现象:一开始运行windows server 2003也是不定时宕机,后由于业务需要更换为windows server 2008 r2还是不定时宕机&am…

什么是模拟量光端机?模拟光端机品牌有哪些?

模拟光端机采用了 PFM 调制技术实时传输图象信号。发射端将模拟视频信号先进行 PFM 调制后,再进行电-光转换,光信号传到接收端后,进行光电转换,然后进行 PFM 解调,恢复出视频信号。由于采用了PFM 调制技术,…

使用Spring Boot 2通过OAuth2和JWT进行集中授权

本指南逐步介绍了使用Spring Boot 2创建集中式身份验证和授权服务器的过程,还将提供演示资源服务器。 如果您不熟悉OAuth2,建议您阅读此书。 先决条件 JDK 1.8 文本编辑器或您喜欢的IDE Maven 3.0 实施概述 对于这个项目,我们将通过Sprin…

什么是物理隔离?物理隔离光端机是什么?

什么是物理隔离? 物理隔离,是指采用物理方法将内网与外网隔离从而避免入侵或信息泄露的风险的技术手段。物理隔离主要用来解决网络安全问题的,尤其是在那些需要绝对保证安全的保密网,专网和特种网络与互联网进行连接时&#xff0c…

linux mysql make_二、linux-mysql -cmake方式安装mysql 5.5

1.安装解压cmake包cmake软件cd /home/oldboy/tools/tar xf cmake-2.8.8.tar.gzcd cmake-2.8.8./configure#CMake has bootstrapped. Now run gmake.gmakegmake installcd ../2.依赖包yum install ncurses-devel -y3.安装mysql创建用户和组groupadd mysqluseradd mysql -s /sbi…

【渝粤教育】国家开放大学2018年春季 7405-21T面向对象程序设计(本) 参考试题

科目编号:7405 座位号 2018-2019学年度第二学期期末考试 面向对象程序设计(本) 试题 2018年 7 月 一、单选题(本大题共10小题,每小题3分,共计30分) (★请考生务必将答案填入到下面对…

太极虚拟服务器,太极 中标 云服务器

太极 中标 云服务器 内容精选换一换华为云帮助中心,为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档,帮助您快速上手使用华为云服务。云服务器组是对云服务器的一种逻辑划分,云服务器组…

【渝粤教育】国家开放大学2018年春季 8617-21T燃气仪表与自动化 参考试题

科目编号:8617 座位号 2017-2018学年度第二学期期末考试 燃气仪表与自动化 试题 2018年 7月 一、填空题(本大题共10空,每空3分,共计30分) 1.目前市场上比较著名的软件系统集成平台有 、 、及 。 2&#xf…

什么是自愈环网光端机?

对于光端机这块,相信大家都有所了解。但是,什么是自愈环网光端机呢?想必很多朋友对此不是很了解,相信大家可能会很感兴趣了解下自愈环网光端机吧。接下来就由飞畅科技的小编来为大家详细介绍下什么是自愈环网光端机吧,…

gui界面怎么分页_什么是用户界面和体验设计

本文译自 Mikos Philips 的 UI vs UX  —  A Guide to UI Design因为发现仍然有小伙伴跑来问我比较基础的专业划分问题,所以翻译了这篇科普文。——用户界面(UI, User Interface)设计是设计软件产品所涉及到的几个交叉学科之一。不论是用户…

【渝粤教育】国家开放大学2018年春季 8638-22T薪酬制度与薪酬管理 参考试题

科目编号:8638 座位号 2017-2018学年度第二学期期末考试 薪酬制度与薪酬管理 试题 2018年 7 月 一、单选题(本大题共10小题,每小题3分,共计30分) (★请考生务必将答案填入到下面对应序号的答题框中★&…

无忧无盘服务器,无忧网维无盘系统新手快速部署.doc

无忧网维无盘系统新手快速部署新手上路之无忧无盘系统快速部署无忧无盘系统支持控制台管理多台无盘服务器,进行远程操作统一管理。与其他的无盘系统不同,第一步需要新添加无盘服务器具体步骤:1) 添加无盘服务器??操作步骤1)? ?…