支持Java 8

尽管Java到目前为止已经发布了版本13,但是有许多生产安装都与Java 8一起运行。作为专家,即使是最近几天,我也多次开发Java 8代码,我必须为这不是Java 6而感到高兴。另一方面,作为开放源代码开发人员,我可以自由使用Java 11、12甚至13开发Java代码。 确实如此。

但是,另一方面,我希望使用我的代码。 开发诸如License3j或Java :: Geci之类的工具,这是一种发布与Java 11兼容的字节代码的库,切断了所有可能使用这些库的基于Java 8的应用程序。

我希望这些库可以从Java 8获得。

一种解决方案是在Git存储库中保持两个分支平行,并拥有Java 11+和Java 8版本的代码。 这是我对Java :: Geci 1.2.0版本所做的工作。 这很麻烦,容易出错,并且需要很多工作。 我之所以拥有这些代码,是因为我的儿子也是Java开发人员,他的职业生涯始于他的志愿工作。

(不,我没有向他施加压力。他的英语说和写的都比我好。他会定期审阅这些文章,以解决我的语言破裂问题。如果他对压力有不同的看法,则可以在此处随意添加任何注释,直到结束为止。括号,我不会删除或修改它。注意:)

NOTE:)之间的任何内容都是他的意见。

另一种可能性是使用Jabel 。

在本文中,我将介绍如何在Java :: Geci项目中使用Jabel。 Jabel的文档很简短,但仍然很完整,对于更简单的项目,它的工作原理确实如此。 例如,对于Licenese3j项目,我实际上只需要向pom.xml添加几行。 对于一年来开发的更复杂的项目,而没有考虑对Java 8兼容性的任何妥协,则要复杂一些。

关于贾贝尔

Jabel是一个开源项目,可从https://github.com/bsideup/jabel获得 。 如果您有Java 9+项目源,则可以将Jabel配置为编译过程的一部分。 它是一种注释处理器,它可以参与编译过程,并且可以使编译器接受各种技巧,从而可以接受Java 9+特性(因为Java 8具有这些特性)。编译器可以工作并生成Java 8,Jabel不会干扰字节码的生成。 ,因此这是真实的,因为它可以新鲜而热情地出现在Java编译器之外。 它仅指示编译器在编译代码时不要迷恋Java 9+功能。

该项目的GitHub页面上很好地说明了它的工作方式以及为什么可以工作。 我在上面写的内容可能甚至不够精确。

移植问题

使用针对Java 8 JVM的Java 9+功能创建Java代码时,我们不仅要关注字节码版本。 使用Java 8 JVM执行的代码将使用Java 8版本的JDK,如果我们碰巧使用了某些在那里不可用的类或方法,则该代码将无法运行。 因此,我们有两个任务:

  • 配置构建以使用Jabel生成Java 8字节码
  • 消除Java 8中不可用的JDK调用。

配置构建

在这里我不会描述如何使用Maven将Jabel配置为构建的一部分。 它记录在网站上,非常简单。

在Java :: Geci的情况下,我想要一些不同的东西。 我想要一个可用于创建Java 8和Java 11目标的Maven项目。 我之所以这样,是因为我希望Java :: Geci像以前一样支持JPMS,并且还为在Java 11或更高版本上运行的那些项目创建最新的字节码(例如,类嵌套而不是桥接方法)。

第一步,我创建了一个名为JVM8的配置文件。 Jabel仅配置为仅在此配置文件处于活动状态时运行。

此配置文件还将发布设置为

 <release>8< /release > 

因此,当编译器第一次看到module-info.java文件时,吓坏了。 幸运的是,我可以排除JVM8概要文件中POM文件中的文件。 我还排除了javax0/geci/log/LoggerJDK9.java ,稍后再讨论。

我还尝试使用Maven自动将版本号配置为具有-JVM8后缀(如果它与JVM8配置文件一起运行),但无法实现。 Maven是一种多功能工具,可以完成许多事情,如果是一个简单的项目,则应该这样做。 对于Java :: Geci,我无法执行此操作,因为Java:Geci是一个多模块项目。

多模块项目相互引用。 至少子模块引用父模块。 子模块的版本可能与父模块的版本不同。 这是合乎逻辑的,因为它们的演变和发展并不一定要结合在一起。 但是,通常是这样。 在像Java :: Geci这样的项目中,它具有七个子模块,每个子模块的版本号与父模块相同,子模块可以从父类继承所有参数,依赖项,编译器选项等,但版本除外。 它不能继承版本,因为它不知道从哪个父版本继承。 这是一个陷阱22。

Java :: Geci开发通过使用Jamal预处理程序来维护八个pom.xml文件来解决此问题。 每当构建配置发生更改时,都必须在pom.xml.jam文件之一或包含的*.jim文件之一中对其进行编辑,然后命令行mvn -f genpom.xml clean将重新生成所有新的pom.xml文件。 这也节省了一些重复的代码,因为预处理的Jamal文件不如相应的XML文件那么冗长。 这样做的代价是必须维护使用的宏。

Java :: Geci有一个version.jim文件,其中包含项目的版本作为宏。 以Java 8发行版为目标时,必须将此文件中的版本更改为xyz-JVM8并且必须执行命令mvn -f genpom.xml clean 。 不幸的是,这是我可能忘记的手动步骤。 创建Java 8目标后,我可能也忘记删除-JVM8后缀。

为了减轻这种人为错误的风险,我开发了一个单元测试,以检查版本号与编译配置文件是否一致。 它标识了读取/javax0/geci/compilation.properties文件的编译配置文件。 这是项目中由Maven过滤的资源文件,包含

 projectVersion=${project.version}  profile=${profile} 

测试运行时,属性将替换为项目中定义的实际值。 project.version是项目版本。 属性profile在两个配置文件(默认和JVM8 )中定义为该配置文件的名称。

如果版本和配置文件不匹配,则测试失败。 遵循Java :: Geci的理念,当测试本身也可以修复错误时,测试不仅命令程序员修复“错误”。 它将修改version.jim文件,使其包含正确的版本。 但是,它不会运行生成Jamal宏的pom文件。

因此,在第二次构建之后,我将通过一些手动编辑工作获得xyz版本以及xyz-JVM8版本的发行文件。

消除Java 8+ JDK调用

简单的通话

乍看之下,这是一项简单的任务。 您不得使用Java 8 JDK中没有的方法。 我们可以使用Java 8进行任何操作,因此这绝对是可能的任务。

例如每个

 " " .repeat(tab) 

必须消除。 为此,我创建了一个包含静态方法的类JVM8Tools 。 例如:

 public static String space( int n){ final StringBuilder sb = new StringBuilder( /*20 spaces*/ "                   " ); while ( sb.length() < n){ sb.append(sb); } return sb.substring( 0 ,n).toString();  } 

被定义在那里,使用这种方法我可以写

 space(tab) 

而不是调用String::repeat方法。 这部分很简单。

模仿

更加困难的是实现getNestHost()方法。 Java 8中没有这样的东西,但是Java :: Geci的工具模块中包含的选择器表达式使您可以使用表达式,例如

 Selector.compile( "nestHost -> (!null & simpleName ~ /^Map/)" ).match(Map.Entry. class ) 

检查是否在Map内声明了Entry类,这很简单。 即使在有人选择这样做的Java 8环境中使用此表达式也是有意义的,但我不想执行截肢手术以从Java :: Geci删除此功能。 它必须被实施。

该实现检查实际的运行时,并且如果该方法在JDK中存在,则它通过反射进行调用。 在其他情况下,它使用类的名称并尝试查找分隔内部类名称和封闭类名称的$字符来模仿功能。 当使用不同的类加载器加载同一类结构的多个实例时,在极少数情况下,这可能导致错误的结果。 我认为像Java :: Geci这样的工具可以使用它,在执行单元测试时几乎不会发生这种情况。

Class#getNestHost反射方式调用Class#getNestHost方法还有一个速度缺陷。 如果有真正的需求,我决定修复它。

记录支持

最后一个问题是日志记录。 Java 9引入了一个日志外观,强烈建议库使用它。 在Java环境中,日志记录是一个长期存在的问题。 问题不在于没有任何东西。 恰恰相反。 太多了 有Apache Commons Logging,Log4j,Logback和JDK内置的Java util日志记录。 一个独立的应用程序可以选择它使用的日志记录框架,但是如果一个库使用了一个不同的库,那么即使不是不可能,也很难将不同的日志消息集中到同一流中。

Java 9因此引入了一个新的Facade,库可以使用它发送日志,应用程序可以将输出通过Facade传递到所需的任何日志框架。 Java :: Geci使用此外观,并通过它为生成器提供日志记录API。 如果是JVM8环境,则不可能。 在这种情况下,Java :: Geci将日志消息传递到标准Java记录器中。 要做到这一点有一个新的界面LoggerJDK由两个类实现LoggerJVM8LoggerJDK9 。 如果目标是Java 8,则后者的源代码将从编译中排除。

实际的记录器尝试通过反射获取javax0.geci.log.LoggerJDK9#factory 。 如果存在,则可以使用Java 9日志记录。 如果不存在,则记录器将返回工厂到javax0.geci.log.LoggerJVM8#factory 。 这样,通过反射仅调用记录器工厂,每个反射器仅发生一次。 日志记录本身已简化,并使用目标日志记录而没有任何反射,因此不会影响速度。

带走

可以在大多数库项目中支持Java 8,而不会做出无法接受的妥协。 我们可以从同一源创建两个不同的二进制文件,这些二进制文件支持两个不同的版本,而支持Java 9及更高版本的版本不会“受苦”旧的字节码。 有一些妥协。 您必须避免调用Java 9+ API,并且在绝对需要的情况下,您可以提供一个后备解决方案,并且可以提供基于反射的运行时检测解决方案。

翻译自: https://www.javacodegeeks.com/2019/11/supporting-java-8.html

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

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

相关文章

mooc作业怎么上传附件_怎么以最低价格入门hifi音响?

方案一&#xff1a;音源 用电脑某宝一个 DIY的DAC 大概200-300元某宝一个迷你的DIY前级功放 大概200-300元某宝一个后级小甲类功放 1969小甲 大概600-1500音箱 5寸或者6寸书架箱 品牌的可以考虑 q牌 2000左右 或者某宝DIY组装的惠威 惠威m1 也是20…

java把一段英文拆成单词_java编程题,输入一段英文文章,单词之间都已经用空格分隔,本人想以每5个单词为一行输出,怎么写?请指教...

我的问题是不会输出5个单词为一行.求指导!!我的代码是以下:importjava.io.*;importjava.util.*;publicclassTest2{publicstaticvoidmain(String[]args)throwsIOException{InputStreamR...我的问题是不会输出5个单词为一行.求指导!! 我的代码是以下:import java.io.* ;import ja…

jsp标签 判断 余数_舟山铝箔纸不干胶标签制作-雷宝实业

卷筒纸不干胶印刷时&#xff0c;纸张的走向与一般印刷方法不同&#xff0c;它是以轴向跳格移动实现套印的&#xff0c;即在印版滚筒上同时装上几套印版&#xff0c;当不干胶在压印平台上每跳移一次&#xff0c;印版滚筒水平方向作往复旋转一次&#xff0c;就可实现印刷一个颜色…

java input是什么意思_java中的【...】表示什么意思

...表示可变长参数&#xff0c;就是说这个位置可以传入任意个该类型参数&#xff0c;简单来说就是个数组。(视频教程推荐&#xff1a;java课程)代码示例&#xff1a;1. testPoints(7);2. testPoints(7,9,11);3. testPoints(new Integer[]{7,9,11});1. public static void testP…

jstat –分析

jstat是一个简单的实用工具&#xff0c;在JDK中存在&#xff0c;用于提供与JVM性能相关的统计信息&#xff0c;例如垃圾收集&#xff0c;编译活动。 jstat的主要优势在于&#xff0c;它可以在运行JVM且无需任何先决条件的情况下动态捕获这些指标。 这是什么意思&#xff1f; 例…

微软电脑适合什么人用_#微软surface pro使用心得# 大学生挑电脑参考/平板与电脑二合一到底买的是什么...

surface pro6 使用一年体验。可以作为如果要买pro7 的一个参考。&#xff08;全是我个人的使用体验与心得&#xff0c;非科普与专业&#xff0c;问我专业的问了我也不知道怎么回答&#xff09;&#xff08;pro7更加具体的可以去B站看大佬们的开箱&#xff09;以下是我的个人想法…

linux 运行java jar_linux运行jar包、查看jar包进程、停止jar包

要运行java的项目需要先将项目打包成war包或者jar包&#xff0c;打包成war包需要将war包部署到tomcat服务器上才能运行。而打包成jar包可以直接使用java命令执行。在linux系统中运行jar包主要有以下四种方式。一、java -jar XXX.jar这是最基本的jar包执行方式&#xff0c;但是当…

et超排真正免狗能用版 真正好用的东西_真正合格小户型,收纳都特别能“装”...

原标题&#xff1a;真正合格小户型&#xff0c;收纳都特别能“装”说起来&#xff0c;小户型的生活在近些年来才流行起来&#xff0c;毕竟&#xff0c;房价的日益升高&#xff0c;想在城市有个家的青年们&#xff0c;只能选择小户型。其实&#xff0c;房子虽小&#xff0c;收纳…

java读取文件并显示_JAVA读取本地文件并显示到页面中

javaweb图片的显示RequestMapping(value"showImg")ResponseBodypublic void ShowImg(HttpServletRequest request,HttpServletResponse response) throws IOException{//String imgFile request.getParameter("imgFile"); //文件名// String path UrlUtil…

javafx html5_JavaFX技巧5:可观察

javafx html5即使在整个NSA监视的这段时间&#xff0c;实现JavaFX控件时也要牢记可观察性&#xff0c;这仍然是一个好主意。 与Swing相比&#xff0c;这在JavaFX中很容易实现。 旧时光 来自Swing&#xff0c;我习惯于花费大量精力和时间来使自定义控件变得可观察。 通常需要添…

苹果电脑怎么投屏到电视_tcl电视怎么投屏

除了看电视&#xff0c;现在的智能电视产品还支持手机投屏功能&#xff0c;如果在使用TCL电视&#xff0c;可以借助第三方软件实现手机投屏的功能&#xff0c;下面就为大家介绍一下&#xff0c;tcl电视怎么投屏。tcl电视怎么投屏步骤1、打开电视自带的应用商店。步骤2、搜索LBT…

重复码

介绍 在我们的Java应用程序中复制/粘贴代码通常不好&#xff0c;但是有时这是不可避免的。 例如&#xff0c;项目License3j在Feature类中为其支持的每种XXX类型提供了一个isXXX方法。 在这种情况下&#xff0c;我们要做的就是写 public boolean isBinary() { return type Type…

sap tcode 功能对照表_Python for Ev3练习amp;Minstorms对照表02

大家好。我是欧文今天给大家分享python for Ev3的练习代码以及python中对应的Ev3Minstorms软件模块对照表。这个练习题都相对基础。主要是用来练习用的。给大家分享的代码也是比较简单的&#xff0c;不过实现方法都是不唯一的。主要的目的是练习和学习。练习代码如下&#xff1…

大楼通信综合布线系统_某办公大楼综合布线系统设计实例,小白可以借鉴一下,大神请绕路...

xxx办公大楼综合布线系统是一个包括内部数据语音通信、外线电话线路接入管理系统、办公用强电电气配电系统、电缆电视系统等内部的复合布线系统&#xff0c;在会议室还有一个小型的供音响系统设备使用的专用布线系统。各子系统的基本情况及主功能如下&#xff1a;强电配电系统&…

java8日期_Java8日期与时间

我们知道Java8一个比较大的改动就是引入了新的表示日期和时间的API&#xff0c;还是很有必要抽点时间了解一下基本的用法。Java8之前的问题在讨论Java8的API之前&#xff0c;我们先看看原来API的问题。我们知道Java8之前只有java.util.Date和java.util.Calendar来表示和处理时间…

javaone_为JavaOne 2014做好准备!

javaone保持那个想法&#xff01; 是的&#xff0c;我希望我能在Java One 2014上做演讲-但我现在只值得在梦里做到这一点&#xff01; 但是&#xff0c;没有什么阻止我遵循Java One并跟踪有关我最喜欢的主题的会话/对话。 我希望Oracle能够像我们2013年版那样&#xff0c;像我…

代码逻辑分析_双11模块79.34%的前端代码是怎样智能生成的?

作者&#xff5c;妙净、波本最近几年&#xff0c;AI 渗透到开发领域的方方面面。在前端领域&#xff0c;设计稿生成代码(简称 D2C)就是一个例子。其目标在于通过 AI 助力前端提效升级&#xff0c;杜绝简单重复性的工作内容。今年“双十一”&#xff0c;阿里的 D2C 覆盖了天猫淘…

datax导入MySQL报错_导入MySQL方法对比

使用datax导入1、使用自增id记录数耗时(秒)TPS42488823471224433404813403882722、不使用自增id&#xff0c;使用雪花算法生成id后导入记录数耗时(秒)TPS424888268062483340481365555096使用MySQL命令load导入1、csv带雪花id> select * from l_wish_log_snow_copy into outf…

项目织机

为什么为什么&#xff1f; Java 8流背后的驱动程序之一是并发编程。 在流管道中&#xff0c;指定要完成的工作&#xff0c;然后任务将自动分发到可用处理器上&#xff1a; var result myData.parallelStream().map(someBusyOperation).reduce(someAssociativeBinOp).orElse(…

java mybatis 教程_(整理)MyBatis入门教程(一)

本文转载&#xff1a;本人文笔不行&#xff0c;根据上面博客内容引导&#xff0c;自己整理了一些东西首先给大家推荐几个网页&#xff1a;MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code&#xff0c;并且改名为MyBa…