Kotlin与Java之争


Kotlin

Kotlin是一门相对比较新的JVM语言,JetBrains自2011年以来一直在积极地开发。

多年来,该语言在Android社区受到的关注度越来越高,并在Google IO 2017大会之后成为Android开发领域最热门的话题。这次大会宣布,Android正式支持Kotlin。

遗憾的是,虽然已经有许多关于Kotlin的文章,但并没有多少客观信息,许多开发人员仍然在苦思冥想,迁移到Kotlin是否是一条正确的道路。

在本文的剩余部分,我将尝试提供一个在将Kotlin作为Java的替代项进行评估时需要考虑的更完善的事项清单。

Kotlin与Java的主观比较

“Kotlin比Java好”,“Kotlin可读性比Java强”,“Kotlin开发速度比Java快”,类似这样的陈述缺少相关准确数据的支持,所以都归为主观看法一类。

主观看法是个体开发人员在对与Kotlin或Java相关的主题作出一个或多个主观判断时形成。

开发人员的主观判断存在如下问题:

  1. 没有与主观判断相关联的量化指标。
  2. 主观判断存在很大的偏见。
  3. 主观判断的偏见在开发人员之间存在很大的差异。

由于没有与主观判断相关联的量化指标,建立在这些判断基础上的观点只是反映出了开发人员之前就有的偏见。不同的开发人员可能有着截然不同的偏见,因此,有开发人员认为Kotlin是不错(或糟糕)的Java替代者并不意味着其他开发人员也这么认为。

而且,由于没有客观指标,主观分歧就无法客观地消除,这经常会导致“口水战”。

主观判断的谬误

为了说明主观判断可能导致的误解,让我们仔细审视一个非常常见的主观看法:

Kotlin可读性比Java强

——Web上无数的文章

理论上讲,可以设法设计一个度量Kotlin和Java之间可读性差异的实验,但据我所知,没有任何人真正地开展这样一个实验。因此,截至目前,这个看法没有任何数据支撑。

Kotlin的语法是许多开发人员称赞其可读性的一个原因。他们的逻辑如下:

Kotlin有更好的语法,因此它的可读性更强

——Web上无数的文章

在这句话中,“更好的语法”又是一个主观判断,本身就值得商榷,但为了避免争论,我们假设Kotlin的语法确实更好。但是,这就能说明Kotlin的可读性更强吗?

为了观察语法对可读性的影响,请阅读下这段“文本”:

Kotlin与Java之争

开始的时候,这段“文本”很难理解,但慢慢地,读起来会越来越容易。如果你再读个两三遍,那么你根本就不会再注意它是由非标准的字母组成的。准确地说,字母的替换不是句法变化,但这确实可以说明,对于熟练的读者而言,外观很少会成为可读性的障碍。

我们也可以把这个例子扩展到自然语言。我了解三门截然不同的语言。虽然它们之间差别很大,但我发现,当我不理解文本中使用的单词时,阅读任何一种语言的文本都非常困难。一旦我认识构成文本的单词并熟悉上下文——无论它使用了哪一种语言,我读起来都不困难。

因此,对我而言,语言的选择并不会影响可读性,只要理解内容和上下文就可以了。

编程语言同样如此。

当我们开始使用一门新语言,我们会有一段时间很难理解源代码,需要认真领会每个句法结构。但是,随着我们阅读和编写特定语言的代码越来越多,我们逐渐就熟悉了那门语言的语法,到某个时候,我们就不会再注意句法结构了。

我自己在多门语言上有过这种体验:Verilog、Bash、Perl、Tcl、Lisp、Java。

根据我使用上述语言的经验,我可以告诉你:如果一个人适应了Lisp的代码,并且不会再注意到小括号,那么跟Java比起来,Kotlin的语法完全不能对可读性产生不可忽视的影响,即使它“更好”。

既然我们在讨论这个话题,我就分享下自己对于影响源代码可读性因素的主观判断。

在读过其他开发人员使用许多语言编写的代码后(上面只罗列了我在某个阶段精通的语言;我用过的所有语言比这个多),我得出如下结论:如果开发人员使用某一门语言可以编写出可读性和可理解性都很好的代码,那么他们通常也可以使用其他语言编写出可读性和可理解性都很好的代码。

因此,我根据自己的经验作出的主观判断是,源代码的可读性和选择的语言无关,那取决于代码编写者的技能和读者的技能(编写者的技能更重要)。

如果你仍然认为主观看法具有代表性,那么至少阅读并思考下Robert “Uncle Bob” Martin在这篇博文中的观点。

Kotlin与Java的客观比较

与主观比较相反,客观比较使用量化指标来度量或评估Kotlin比Java有优势的地方。

用一套标准客观地证明一门编程语言是否强过另一门,这种想法非常有吸引力,但是有个问题:据我所知,没有与编程语言相关的通用客观指标。

考虑到我们无法进行精确的直接比较,那我们能否客观地比较Kotlin和Java呢?能!我们仍然能评估从Java切换到Kotlin所带来的积极和消息影响的程度,然后比较结果,并讨论它们的影响。

为了评估Kotlin所能带来的最好结果,我们将做如下假设:

  1. 开发人员可以立即切换到Kotlin;
  2. 切换到Kotlin后,开发人员不会损失任何技能(例如,有两年Java开发经验的开发人员可以神奇地获得两年的Kotlin开发经验);
  3. Kotlin和Java一样稳定;
  4. Kotlin工具和Java工具一样成熟。

事实上,上述假设没有一个是合理的,但在开始的时候,有一个理想化的设定便于说明。然后,我们会抛开这些假设,讨论真实世界的效应所带来的影响。

Kotlin最佳结果估计

遵循Steve McConnell在Code Complete一书中提出的模式,我们可以将软件构建活动分解成三个子活动:详细设计、编码与调试、开发测试。

Kotlin对于详细设计子活动没什么影响(这项活动通常独立于选用的特定的面向对象编程语言),因此,在这一部分,Kotlin和Java需要付出同样的努力。

据我所知,对于开发测试子活动,Kotlin也没有提出什么革命性的东西。因此,开发测试需要付出的努力也一样。

就剩编码与调试子活动了。

如果我们用Kotlin替换Java,那么我在编码与调试活动中可以节省多少工作量?这个问题很难回答,不同程序员之间这一数值会有很大差异(有些程序员使用Java更高效)。不过,既然我们在评估最好的情况,我们不妨假设从Java切换到Kotlin可以将开发人员在编码与调试阶段的生产力平均提高10%。

10%的生产力提升是一个不现实到令人吃惊的数值。即使我们在文本编辑器中手工输入所有代码,那也是不现实的。考虑到现如今IDE的功能,这一数值更是不现实。考虑到有些开发人员使用Java更高效,这个数值就毫无道理了。

我不介意使用这样一个既不现实又对Kotlin评估有利的数值,因为我知道,不管它对评估结果产生了怎样不切实际的积极影响,一旦我们抛开其中部分“理想的假设”,由此带来的负面影响会抵消掉那些积极影响。

那么,在编码与调试方面提升了10%——我们把产品交付给客户的速度快了多少?

下面这张图片来自Code Complete一书,展示了软件项目的各种活动所占的比例:

Kotlin与Java之争

 小项目以构建活动为主。大点的项目需要更多架构、集成和系统测试工作来保证项目成功。这张图没有显示需求,因为和其它活动不一样,需求工作不是直接的程序功能。(Albrecht 1979; Glass 1982; Boehm, Gray, and Seewaldt 1984; Boddie 1987; Card 1987; McGarry, Waligora, and McDermott 1989; Brooks 1995; Jones 1998; Jones 2000; Boehm et al. 2000)
Code Complete,第二版

根据来自Code Complete的这张图片,在一个较大的软件项目中(多于10K行),编码和调试只占项目总工作量的不足20%。

因此,在一个较大的软件项目中,我们所假设的编码和调试效率提升10%,只能将完成项目所需的总工作量缩减2%。

例如,一个需要5人年才可以完成的项目(这是相对比较大的Android项目),总工作量的2%为:

5人-年 * 12 * 4 * 5 * 0.02 = 24(人-天)

如果我们真得能够把项目工作量减少24人-天,这会是一个从Java切换到Kotlin的很好的理由。然而,我们应该还记得,上述积极评估是在理想情况下得出的,其基础是不切实际的假设。

在真实世界里,切换到另外一门编程语言会产生不可避免的影响,我们将评估这种影响,并与上述理想化评估作个比较。

开发人员准备

为了评估最好的情况,我们假设开发人员可以立即从Java切换到Kotlin。

实际上,虽然Kotlin和Java非常类似,但开发人员仍然需要花一些时间来学习,然后再花一些时间来调整开发实践和工具。准备时间因人而异:有些开发人员可以三四天完成切换,其他人则需要10天甚至更多的时间。

让我们乐观一点,平均每个开发人员只要5天就可以从Java切换到Kotlin。

一个需要5人年才能完成的项目会有3到5名开发人员(最好的情况下)。平均每个开发人员的切换时间为5天,这样,一个项目总计就需要15到25个人天的切换时间。

切换到Kotlin所节省的工作量(乐观估计)与切换所需的总工作量似乎差不多。

开发人员技能损失

使用一门特定的编程语言高效工作的能力是一项技能。

我们已经讨论了这项技能的其中一个方面(代码可读性),但还有许多其他方面。当从一门语言切换到另一门时,与旧编程语言相关的部分技能可以运用到新语言上,但该技能的其他部分会损失掉。

为了评估编程语言技能损失对项目工作量的影响,我们将使用源自Cocomo2评估模型的“语言与工具体验”因子:

语言与工具经验(LTEX)
该指标用于衡量开发软件系统或子系统的项目团队使用编程语言和软件工具的经验。软件开发包括借助工具完成需求、表现形式设计与分析、配置管理、文档提取、库管理、程序样式与格式化、一致性检查、计划与控制等等。除了项目编程语言经验外,项目支持工具集的经验也会影响开发工作。经验低于2个月会获得一个很低的评级,有6个月或多年的经验则会获得一个很高的评级,见下表:

Kotlin与Java之争

Cocomo 2模型定义手册

例如,假设我们有一个Java开发团队,团队成员平均有一年的经验,我们想迁移到Kotlin。

由于Kotlin和Java非常像,与许多Java工具兼容。我们可以乐观地假设,在经过初步的准备后,开发人员就可以归为有6个月开发经验这一类(而不是低于2个月)。根据这个假设,为了评估技能损失所导致的额外工作,项目的额定工作总量应该乘以1.09。

一个需要5人年完成的项目,配备了平均具有1年Java经验的开发人员,切换到Kotlin所导致的额外工作达到了令人咂舌的108人天。

技能损失所导致的额外工作是切换到Kotlin所缩减的工作的四倍。

语言和工具的稳定性和成熟度

有个普遍的说法,就是Kotlin是一门生产就绪的语言。这种说法也许是有道理的,因为Kotlin已经用在了若干项目里。

不过,与Java相比,Kotlin是一门并不稳定的年轻语言。

有些开发人员认为,Kotlin的不稳定性是个优势——语言在演进,可以更快地提供新特性,更快地改进。在我看来,他们对于这件事的看法过于简单。

下面是Kotlin 1.1.4发布说明里的第一句话(写这篇文章时的最新版本):

修复IntelliJ IDEA的一项重大性能衰退
——Kotlin 1.1.4发布说明

我不知道这是什么样的衰退,有多少项目受到了影响,但我的大脑自动将“重大性能衰退”这个搭配翻译成了“浪费了许多小时的开发时间。”

此外,如果你读一遍发布说明的评论,你就会注意到,许多人遇到了迁移问题。在1.1.2版本的评论里,甚至有人指出,这个“补丁”发布引入了破坏性(向后不兼容)的修改。

相比之下,如果你读一遍Oracle JDK8的发布说明,你就会发现,它比较稳定。大多数修改都是安全改进方面的。

因此,与Java相比,Kotlin是一门不稳定且不成熟的语言——迁移到Kotlin会对项目产生怎样的影响?为了回答这个问题,我将使用来自Cocomo 2评估模型的“平台波动性”工作因子:

平台波动性(PVOL)

这里使用“平台”一词指代软件产品执行任务时调用的复杂硬件和软件(OS、DBMS等)。如果开发的软件是一个操作系统,那么平台就是计算机硬件。如果开发的是数据库管理系统,那么平台就是硬件和操作系统。如果开发的是网络文本浏览器,那么平台就是网络、计算机硬件、操作系统和分布式信息库。平台包括支撑软件系统开发所需的编译器或装配器。如下表所示,如果平台每12个月才有一次重大变更,则评级就会很低,如果每2周有一次重大变更,则评级就会很高:

Kotlin与Java之争

Cocomo 2模型定义手册

你可能已经注意到,编程语言并没有直接出现在该工作因子的描述里,但出现了编译器和装配器。在我看来,这段描述没有显式包含编程语言,是因为得出Cocomo 2模型的所有项目都使用了稳定的语言。

由于编译器和装配器属于这个工作因子,所以我们也可以推断出编程语言及相关工具。

根据平台波动性的这种评级范围,Java的评级应该是“very low”,而Kotlin的评级应该是“low”或更高。Kotlin的评级可能会更高,因为它内部依赖于其它工具,增加了出现兼容性问题的风险。

由于“very low”没有提供工作因子,所以我们需要估计。

看下该因子从“very high”到“low”的评分递减规律,我认为,我们可以放心的假设,“very low”的评分不高于0.82。

基于这些假设(有利于Kotlin),如果一个项目需要5人年的额定工作量,那么使用Kotlin,工作量就变成了1044人天,而使用Java的总工作量是984人天。

选择使用Kotlin而不是Java实现这样一个项目会使总工作量增加60人天。

语言和工具不稳定所导致的额外工作是切换到Kotlin所缩减的工作的2倍多。

综合所有因素

我当成例子来讨论的项目需要5人年的额定工作量。

根据上述评估,如果该项目由平均具备1年Java开发经验的开发人员使用Java实现,则总工作量为:

5 人-年 * LTEX(Java) * PVOL(Java) = 984 (人-天)

如果同样的项目由几乎没有Kotlin开发经验的开发人员使用Kotlin实现,则总工作量为:

5 人-年 * LTEX(Kotlin) * PVOL(Kotlin) * 0.98 + T_ramp_up = 1115 + 5 * N_developers (人-天)

据估计,选择Kotlin替换Java所导致的额外工作量为131 + 5 * N_developers (人-天)

评估注意事项

在评估讨论的过程中,我们得出了与Kotlin和Java相关的、便利的工作量单点值。

但实际上,单点值根本不是估计——它们只是猜测。真正的估计必须有一个相关联的不确定性。换句话说,估计表示可能性的范围,而不是单点值。

我们最终使用单点值代替了范围,那是因为我从估算范围里选择了最有利于Kotlin的值,将所有的估计都转换成了单点值。

例如,当讨论Kotlin对编码与调试活动的影响时,我从估计出的可能性范围[-5%,10%]中选择了最大的生产力提升值10%。在其他情况下,当我们讨论开发人员切换到Kotlin的平均时间时,我从估计的可能性范围[5天,21天]中选择了最小的5天。

此外,我们使用了Cocomo 2估计模型专用的工作因子。这些因子并不是放之四海而皆准的真理,在最一般的情况下,应该也有相关联的不确定性。我赋给Kotlin的评级高于我实际上认为它应得的评级,我希望通过这种方式消除这种不确定性。

不用说,我们获得的单点值并不是百分百正确。为了得出更完整的估计,我们可以利用真正的估计进行Monte Carlo仿真。通过这项技术,我们可以观察可能结果的分布,弄清楚哪种结果最可能出现。

请记住,由于我们将估计压缩成了对Kotlin而言最为有利的单点值,所以其他可能的结果会显示出更大的Kotlin切换开销。因此,在所有可能的结果中,我们在上文描述的单点值是最有利于Kotlin的。

小结

在文章开头部分,我们展示了一些可能会对开发人员比较编程语言造成误导的主观判断。

接下来,我们讨论了客观比较编程语言存在的困难,并进行了一系列的估计,以便弄清楚Kotlin栈与Java栈完成软件项目所需的总工作量。在执行估计时,我们一直使用估计范围里最有利于Kotlin的值。

通过我们的分析,从Java切换到Kotlin似乎会导致完成软件项目所需的总工作量增加。

更多的工作意味着企业切换到Kotlin需要花更多的钱才能获得同样的功能,而用户需要等待更长的时间才能获得产品。

有些开发人员可能会吃惊,觉得这个结果不容易接受。

在考虑了所有的情况之后,谷歌最终决定支持Kotlin Anroid开发。对此,谷歌可能需要相当大的投入——谷歌云平台团队是不是没有人可以做类似的分析,从而弄清楚切换到一门新语言所带来的负面影响?

我认为,谷歌员工都是非常聪明的人,我相信他们在决定支持Kotlin之前已经进行了非常深入的分析。

在下一篇博文中,我们将讨论谷歌为什么要支持Kotlin,即使是在通过简单的分析就可以知道那不利于Android社区的情况下。

查看英文原文Kotlin vs Java The Whole Story


感谢覃云对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/Kotlin-Java-debate?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Oracle将Java EE移交Eclipse基金会

在Oracle宣布正试图将Java EE技术迁移到开放源码的基金会之后,该公司现在表示他们已经选择Eclipse基金会作为该平台的接管人。

Oracle称“Eclipse在Java EE和相关技术方面的丰富经验和积极参与”是他们选择Eclipse的一个重要因素。

据InfoQ报道,该公告是在Java EE即将开源的公告出现几周后发布的。这一行动之迅速受到了许多人的欢迎,特别是考虑到Java EE的开发缺乏敏捷性以及其发布速度之低这一情况,而这正是Oracle饱受诟病的原因,也是导致Oracle采取行动的原因之一。Oracle在原来的公告中接受了这一批评,并指出Java EE的开发过程不够敏捷、灵活或开放。Red Hat也欢迎这一举动,表示“看到Oracle快速进步”是令人鼓舞的,并补充说,他们完全支持Oracle选择Eclipse基金会的决定。IBM杰出工程师Ian Robinson也称赞了这一公告,并称IBM团队期待参与Eclipse的新项目。

选择Eclipse的其中一个因素是它已经接手MicroProfile了,MicroProfile是一个旨在优化企业级Java以用于微服务和云架构的项目。在宣布选择Eclipse的博文中,Oracle提到他们希望“利用诸如MicroProfile之类的互补类项目”。MicroProfile原始协作者之一的Red Hat表示,他们希望将Java EE交给Eclipse以便IBM能够更容易调和Java EE和MicroProfile,这一态度同样也得到了IBM的回应。

作为MicroProfile的贡献者和 Java EE Guardians 组的成员,OndroMihályi表示,Eclipse可以说是“Java EE非常自然的选择,并且Eclipse也受到了Java EE和MicroProfile社区的欢迎”。

Oracle表示,在做出该行动前,首先向Red Hat和IBM寻求了帮助和支持,因为他们是三个组织中对Java EE的贡献最大的。完成此事后,Oracle接下来的工作就是细化将Java EE迁移到开源基金会的实际意义。他们最终得到了一项全面的战略,其中涵盖了技术细节、许可、品牌和过程定义,从而支持平台可以在未来继续演进。更多详细信息可以在博文链接中找到。最后,Oracle与几个开源基金会讨论了该提案。这些谈话之后,Oracle即宣布了由Eclipse基金会来接手Java EE平台的决定。

查看英文原文Oracle Chooses Eclipse Foundation as New Home for Java EE


感谢罗远航对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/JavaEEtoEclipse?utm_source=news_about_java&utm_medium=link&utm_campaign=java

期待已久的Java 9 今日发布

人们期待已久的Java SE 9.0将在2017年9月21日发布,它会带来一些重要的变化。

JDK 9的核心变化就是引入了一种新的Java编程组件,也就是模块,按照Oracle的说法,它是一个可命名的、自描述的代码和数据集合。模块技术的核心目标是减少Java应用和Java核心运行时环境的大小与复杂性。为此,JDK本身进行了模块化,Oracle希望通过这种方式提升性能、安全性和可维护性。

为了支持Java 9的模块,引入一种新的模块化JAR文件形式,按照这种形式会在其根目录中包含一个module-info.class文件。Oracle同时提供了工具,允许我们组合和优化一组模块,形成自定义的运行时镜像(image),这样的镜像不必将整个Java运行时包含进来。模块化所带来的其他变化包括从Java运行时镜像中移除了rt.jar和tools.jar。

InfoQ与Ben Evans进行了交流,以了解他对Java 9.0模块系统的看法,他是Java社区进程(JCP)执行委员会的成员。

Evans:我认为最急需重构的应用恰好就是最适合进行模块化的应用。如果你已经备受Lava Flow / God Class / Stovepipe System地狱的折磨,而且你的利益相关方明确知道这一点,那么你可能更容易说服他们进行一次完整的底层重构,通过渐进式的努力形成一个完成的模块解决方案(而不是简单重构并迁移至Java 8)是值得去做的。

Oracle宣布Java 8会是一个长期支持的发布版本,会一直支持到2022年,因此Evans认为很多的应用将会停留在Java 8上,根本不会升级到Java 9。Evans补充说,有些应用可能会让开发和构建工具链使用Java 8版本,而在生产环境使用Java 9的运行时。

对特定类型的应用来说,这是很有帮助的。例如,我曾经见到有的电子商务网站具有非常大的堆空间,其中包含了大约40G的字符串数据。Java 9的ompact Strings技术能够将这种类型的内存使用减半。这反过来又会对GC的性能带来积极的影响。对于有些应用来说(这可能就包括大型的Solr安装环境及类似场景),单单这一项收益就值得将运行时升级到Java 9。

Java 9使用G1作为默认的垃圾收集器,替代了之前默认使用的Parallel GC。Evans对这项变化的评论:

这项变更是很重要的,因为相对于Parallel来说,G1会在应用线程上做更多的事情,而Parallel几乎没有在应用线程上做任何事情,它基本上完全依赖GC线程完成所有的内存管理。这意味着切换到G1将会为应用线程带来额外的工作,从而直接影响到应用的性能。

在很多(甚至可以说大多数)场景中,这种额外的性能损耗都不是什么问题。但是,在这方面,我确实也曾经见过从Parallel切换到G1时,有一定比例的工作负载会引起性能的下降。对于这些应用来说,这种性能下降是无法接受的,所以他们无法切换至G1收集器。随着G1成为默认的收集器,这将会影响到升级至Java 9的每个应用。

对于大型的代码库是否需要重构为模块的形式,InfoQ询问了Martijn Verburg的意见,他是JClarity的CEO,也是伦敦Java用户组(Java User Group)的联合组织者。

Verburg:需要这样做,另外,我还希望你要处理的大型代码库已经按照一定的模块化结构语义进行了拆分,不管你采用的是OSGi、Maven模块、JBoss模块,还是采用简单的内部规则,将包和接口的结构划分出清晰的边界都可以。

Verburg给出了一些通用的模块化建议,并且指出了开发人员在采用Java 9模块系统时,需要注意的一些事情:

  • 阅读Paul和Sander的图书“Java 9 modularity”:它是本权威指南,提到了所有需要注意的地方,阐述了模块、包以及JAR之间如何运行的关联关系;
  • 在模块边界的地方,使用定义良好的接口并且针对这些接口编程;
  • 不要拆分包(split package),也就是说一个包不要分散到两个模块中。Adopt OpenJDK有个探测工具,我们可以用它来探测已有的代码;
  • 确保不要存在循环依赖(Jigsaw不允许这样);
  • 模块在源码的布局上与我们已习惯的方式有所不同,需要确保构建工具能够进行对应的处理;
  • Jigsaw不支持多版本。

按照Verburg的说法,核心要点在于处理循环依赖、拆分包的问题,并确保针对接口进行编码。在尝试使用Jigsaw模块化重构之前,针对已有的代码库,这些工作需要预先完成。他还澄清了一个误解,那就是只有模块化的应用才能在Java 9上运行。

由于误解,在这方面有一种FUD(恐惧、不确定和怀疑)情绪,有人误认为在Java 9上运行的必须是模块化的应用。事实并非如此,我们可以将已有的基于类路径的应用直接在Java 9上运行。这里会有一些新的安全限制,因此我们需要设置一些特定的运行时标记(除非你重构代码,使用更安全的方式来访问Java的内部资源),即便如此,默认的行为也只是警告,而不是完全阻止我们(Java 10的限制会更严格)。

Verburg认为Jigsaw会是一个基石,会让Java的演进更快,这要归功于Mark Reinhold、Alan Bateman、Mandy Chung以及Jigsaw团队的其他成员多年来不知疲倦的工作,正是他们的努力使这一切得以实现。

Java 9还引入了jshell工具。这个命令行环境为Java平台带来了读入-求值-打印-循环(Read-Eval-Print-Loop,REPL)功能。它的目的在于以即时结果和反馈的形式,简化原型的实现并帮助我们探索语言在编码时的可选项。

Verburg和Evans看到Java 9中包含了jShell都非常兴奋,但令他们失望的是,HTTP/2只是作为Java 9的一个孵化模块(incubator module)提供的。鉴于社区对这项特性的兴趣和提供的帮助,Evans认为Oracle应该投入足够的工程资源,将HTTP/2交付为GA版本。

JDK 9完整的变更列表可以在Oracle的站点上查阅。Oracle宣布会按照每六个月一次的节奏进行发布,意味着Java 9是最后一次“keystone”特性驱动的版本发布,这反映出了Oracle目前管理Java的特点。Java下一阶段的演化将会按照更短的发布周期并且会按照更加面向特性的方式来发布。Java是否依然能够在服务端技术中占据领导者地位尚有待观察。

查看英文原文Long Awaited Java 9.0 Releasing This Week

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/Java-9-release-sept-21?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Eclipse更新了Eclipse公共许可(EPL)

Eclipse基金会发布了新版的Eclipse公共许可(Eclipse Public License,EPL),简称EPLv2。EPL是Eclipse基金会默认使用的软件许可。此次更改涉及了部分特性,但主要目的是为了在保持和开放源代码促进会(Open Source Initiative)指南相兼容的同时,兼容GPL及更早期的许可,使其可在美国之外使用。EPLv2将替代EPLv1,而EPLv1已具有13年的历史,很大程度上基于以前的通用公共许可证(CPL,Common Public License)。

为深度解读新版许可,InfoQ采访了Eclipse基金会的执行董事Mike Milinkovich,他也是开放源代码促进会的前董事会成员。Milinkovich指出:

Eclipse社区开始在物联网领域启动大量运行时项目,因此必须要链接采用GPL许可的代码并做互操作。

但是Milinkovich还补充道,EPLv2兼容GPL并不意味着所有的项目也应遵守GPL。项目牵头人可以决定一个新项目是否与GPL兼容,并有权在得到所有贡献者明确同意的条件下,后期更改在许可上的决策。

EPLv1的一个主要问题在于它是和美国立法明确关联的。确切地说,就是纽约州法律和美国版权法案(US Copyright Act)。一方面,与特定管辖区的关联,增加了对美国以外侵权行为提出诉讼的难度,因此可能会妨碍美国以外的开发商使用EPLv1。另一方面,要将这两个许可应用到其它相关的软件上,还存在着一些微妙的问题。

EPLv1的应用受限于先前已得到许可的代码,以及“衍生作品”(Derivative Work)。“衍生作品”是一个法律术语,简而言之,根据美国版权法案的解释,“衍生作品”被定义为“采用了重映射、转换和采纳形式的所有工作”。EPLv1明确表明,“衍生作品”并不适用于与EPLv1许可的代码一并分发但是采用了不同软件许可的其它软件模块。

GPLv2GPLv3许可所提供的权利和义务,已经扩展到那些“基于”GPL许可程序的工作,或是与GPL许可的程序“一并分发”的工作。如果要链接使用不同许可发布的代码,这一差别非常重要。

根据自由软件基金会(Free Software Foundation)的主张,如果代码A链接到由GPL许可的代码B(静态或动态皆可),意味着代码A是基于代码B的;如果代码C链接到由EPLv1许可的代码D,并不会使代码C成为代码D的“衍生作品”。这就意味着,GPL的权利和义务可从代码B扩展到代码A,而EPLv1的权利和义务将不会从代码D扩展到代码C。这导致了两种许可在行为上的差异,进而也不相互兼容。

在EPLv2推出之前,项目可以通过EPLv1和Eclipse分发许可(EDL,Eclipse Distribution License)(EDL是New BSD License的一个变体)的双重许可克服这一局限。New BSD License是一种宽松软件许可(Permissive License),兼容GPL。正如Milinkovich所说:

BSD许可实质上移除了EPL许可的社区友好著佐权(Copyleft)特性。EPLv2在维护了EPL著佐权规的同时,允许对GPL许可的兼容。

Milinkovich希望那些目前依然采用EPLv1许可的项目,尤其是Eclipse基金会所管理的项目,能逐渐迁移到EPLv2许可。JUnit 5等一些项目已经使用了EPLv2许可。但是Milinkovich指出,对于那些在Eclipse基金会管理下但当前仍未采用EPLv1许可的项目,例如Eclipse CeylonEclipse MicroProfile,可根据项目自身的需要继续使用当前的软件许可。

鉴于EPLv2许可是新近推出的,因此开发人员、项目和企业依然处于适应阶段。Eclipse基金会正在创建了一个FAQ页面,但是截至本文发稿时为止,FAQ依然在完善中。此外,虽然EPLv2宣称是OSI兼容的,但它并未出现在OSI的官方网站上。这些问题有望在不远的将来得到解决。

查看英文原文: Eclipse Foundation Renews the Eclipse Public License

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/eclipse-public-license-2?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Struts官方再次公布4个安全漏洞,建议尽快修复

美国征信巨头Equifax近日公开披露,其公司数据遭到黑客攻击并泄露,并且可能会涉及1.43亿用户。而本次泄露信息的内容包括个人信息,例如姓名、住址、出生日期、社会保障号、驾照信息等。受此消息影响,Equifax本周一股价下跌10.11美元,跌幅8.2%,收于113.12美元。自披露消息之后,其股价已累计下跌逾20%,市值蒸发35亿多美元。

从Equifax官方发布的网络安全事件更新公告中可以确认,引起此次数据泄露的原因是Web框架Apache Struts的一个漏洞(CVE-2017-5638)。CVE-2017-5638是一个RCE的远程代码执行漏洞,最初是被安恒信息的Nike Zheng发现的,并于3月7日上报。这个漏洞被官方鉴定为严重级别,同时,在披露的当天,Apache 也发布了新的Struts版本进行修复。但 Equifax 在漏洞出现的两个月内都没有修复,导致 5 月份黑客利用这个漏洞进行攻击,泄露其敏感数据。

而在9月初,Struts官方又连续发布了两份安全公告。第一份安全公告于9月5日发布,涉及的三个安全漏洞分别是CVE-2017-9804CVE-2017-9805CVE-2017-9793。其中CVE-2017-9805被定性为严重级别,根据版本迭代历史推断,该漏洞已有九年历史,但直到最近才被发现,也就是说,自 2008 年以来的所有版本 Struts2 都会受到影响,用户需要尽快升级。简单来说,漏洞是由于Struts2的REST插件引起的,其XStream组件存在反序列化漏洞,但Struts2使用带有XStream实例的XStreamHandler进行反序列化操作时,没有进行任何类型过滤。

第二份安全公告于9月7日发布,涉及的漏洞是CVE-2017-12611,漏洞等级是中危,漏洞根因是由于Freemarker标签,当用户在Freemarker标签中使用表达式常量或强制表达式时使用请求值就可能会导致远程代码执行漏洞。该漏洞的报告作者之一是京东安全团队的Lupin。

受这些漏洞的影响,思科也在上周连续发布了两个安全公告,并着手进行自身主要产品的安全性审查。据了解,世界上约65%的财富100强公司都有使用Struts作为基础设施,这其中包括美国国税局、花旗集团、Equifax等。而根据绿盟科技威胁情报中心的数据得知,中国又是世界上使用Struts框架最多的国家之一,甚至在今年7月,国家信息安全漏洞共享平台还发布过关于做好Apache Struts2高危漏洞管理和应急工作的安全公告

关于Equifax数据泄露的具体详情可以阅读这篇新闻,关于Struts2漏洞的详细信息读者可以在这里进一步了解

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/Struts-Security-Bulletins?utm_source=news_about_java&utm_medium=link&utm_campaign=java

美征信巨头Equifax因Struts漏洞导致数据大规模泄露

各新闻机构和在线新闻网站都报道了黑客从征信企业Equifax窃取了1.43亿美国人的详细个人信息,这一事件表明Apache Struts框架存在安全缺陷。Struts是一种开源的MVC框架,用于创建基于Java的Web应用。作为这一框架管理者,Apache软件基金会发布声明对此指责做出了回应。

据媒体最初报道表明,漏洞可能是由Struts的一个未公开漏洞所导致。但是,Equifax已经确认在攻击中所使用的Structs漏洞是CVE-2017-5638,而且继Equifax首次声明之后,Apache基金会也对此做了确认。该漏洞位于Jakarta Multipart解析器中,对于Apache Struts 2的2.3版本,在2.3.32之前的版本中存在;对于Struts 2的2.5版本,在2.5.10.1之前的版本中存在。这一漏洞已于今年三月被Apache Struts团队打补丁,并关闭了该问题。但是Equifax在五月中旬出现了泄漏,直到七月底才被发现。在此期间,攻击者已经访问了不少客户的个人数据,其中包括社会保障码、出生日期和住址等。有20.9万名客户的信用卡号被访问,未知数量的英国和加拿大居民的个人数据也被泄露了。

Struts几乎曾是Java Web应用开发的普遍选择,其应用遍布业界并依然被大量使用,尤其是在企业的一些历史遗留应用范围内。Apache软件基金会的项目管理委员会(Project Management Committee)在媒体上对Equifax的声明做出了回应,其中提出了多点意见。首先,依然不能确定泄漏的源头的确是由于Struts的漏洞所导致。其次,如果的确是源于Struts的漏洞,那么“或是Equifax服务器未打补丁,使得一些更早期公布的漏洞被攻击者利用,或者是攻击者利用了一个到目前为止尚未被发现的漏洞”。根据推测,该声明提出黑客所使用的软件漏洞可能就是CVE-2017-9805漏洞,该漏洞是在九月四日公布的,这是在Equifax发现出现泄漏后的一个月。声明中还继续列出了一些软件工程上的原则。如果这些原则得到了所有使用开源或不公开软件库的开发人员的遵守,将“有助于防止Equifax所经历的不幸泄露事件重现”。

Equifax的股价在华尔街下跌了近14%,据BBC报道,两个美国国会委员会将对此次数据泄漏事件举行听证会。此外,纽约、伊利诺伊州、马赛诸塞州、康涅提格洲和宾夕法尼亚州的州检察长将在本州内对此次事件开展调查。

查看英文原文: Struts Flaw Behind Equifax Breach Disclosed and Patched in March

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/struts?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Java EE Security API(JSR-375)获得通过

Java EE Security API,即JSR 375,在八月份得到了通过。JCP执行委员会的所有成员都投了“赞成”票,没有成员投“反对”票。Intel Corp.没有针对该JSR投票。

这个JSR围绕用户管理、密码混淆、角色映射、认证和授权提供了很多的功能增强。这些增强在设计上的初衷是让Java EE安全性在云环境中更易于实现。(关于JSR 375的细节,InfoQ在2014年十一月曾经介绍过。)

该项目的站点已经迁移到了https://github.com/javaee/security-spec上。(JSR上列出的项目站点依然是错误的http://java.net/projects/javaee-security-spec。)该仓库包含了规范和20个open状态的issue,这些缺陷很可能是Glassfish在创建参考引用时发现的。

Java EE 8之路并不轻松,但是最近的JSR通过让我们看到了这个漫长道路上的曙光。Oracle也在考虑将Java EE转移给开源基金会(Oracle已经决定将Java EE移交给Eclipse基金会——译者注)。他们最近与社区的交流是提升平台透明性的一个积极举措。更多的细节会在Oracle年度的JavaOne大会上分享,该会议将会在十月初举办。到时候请关注我们的站点,因为InfoQ将会提供广泛的报道。

查看英文原文Java EE Security API (JSR-375) Approved

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/jsr-375-approved?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Java社区对Java发布周期声明的反应

InfoQ最近报道了Oracle关于Java发布模型和时间表的声明。该声明受到Java生态系统大多数参与者的广泛欢迎,但是Java标准化过程以及Java标准制定组织(JCP)在未来版本中的作用仍然存在疑问。

除了Java 9的发布之外,Oracle尚没有明确新的发布节奏如何与JCP一起合作。通常JCP的运作时间要长于Oracle新提议的6个月发布周期。这就会引发一个问题,是否每个功能版本都会有Java规范提案(JSR)。

如果这样的话,那么Oracle需要解释短时间的版本发布如何与JCP流程集成。到目前为止,很少有JSR可以在这么短的时间里进行处理,而且没有一个是平台级的JSR(定义了Java SE或Java EE的新版本)。

Oracle发言人说:

Oracle一直在与JCP合作以满足快速增长的发布节奏。在未来几周内,可能会制定出全面支持该计划的细节。

JCP执行委员会成员Simon Ritter评论说:

的确,在过去JSR的处理时间要比6个月长,主要是因为平台的开发速度比较慢,因此没有必要以如此快的速度发展。

理论上说,尽管JCP流程的推进可能会有一些变化,但是在这个时间范围内完成Java SE JSR没有任何问题。

Simon Ritter还评论了Oracle的声明“在与其他编程平台的竞争中更快的发布周期是必要的”:

一直以来,平台发展面临的问题是如何满足两个正交的用户群体。Java支持许多企业以及一些关键任务的系统;稳定性和兼容性是部署和维护这些系统最重要的因素。

然而,现在开发一个新的应用程序越来越快,开发人员希望以更快的速度使用新的语言和API特性。

Oracle决定采用6个月的版本发布周期,并提供三年的长期支持,这似乎是两方需求中最好的解决方案。

最近的JCP EC会议报告中,Oracle计划尽快提交Java SE 10 JSR(现在可能称为Java 18.3),理想情况下会在9月份发布并在12月份冻结发布日期。这表明现在Oracle愿意参与JCP流程。

然而,在JCP流程与SE版本协同的过程中存在一些已知的问题。特别是,当前的流程与第三方beta版本的构建存在问题,主要由于这些第三方要以尚未发布的或正在开发版本的Java规范为目标。

Oracle已经确认,这些挑战也将是和JCP讨论的一部分内容,并且提到了JCP OpenJDK工作组和相关各方的参与者

伦敦Java社区(LJC)领导人同时也是LJC在JCP EC会议上的发言人Martijn Verburg,发表了这样的评论:

JCP执行委员会、Oracle和OpenJDK管理机构正在努力精简标准化流程,以促进更快的发布。

Eclipse基金会执行董事兼JCP EC成员Mike Milinkovich,在他的一篇博文中写到:

最终,Java将不再使用自其发明以来一直困扰它的显式和隐式的使用限制。开发人员可以在任何设备上免费使用Java,而不需要任何额外的许可或其他权限。

距离已经延迟多次的Java 9发布只有一周多时间了,整个行业都非常关注,看看新提议的发布周期在完全实施后是否能够达到预期。

查看原文: Java Community Process Reacts to Release Cycle Announcement


感谢张卫滨对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/JCPReacts6Month?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Spring Boot 2.0将会增强Actuator端点的特性

即将发布的Spring Boot 2.0.0 M4将会增强actuator端点基础设施的特性。最重要的变更包括:

  • 支持Jersey RESTful Web服务
  • 支持基于反应式理念的WebFlux Web App
  • 新的端点映射
  • 简化用户自定义端点的创建
  • 增强端点的安全性

Spring Boot的actuator端点允许监控Web应用,并且可以与Web应用进行交互。在此之前,这些端点只支持Spring MVC,如果创建自定义端点的话,需要大量额外的编码和配置。

端点映射

内置的端点,比如/beans/health等等,现在都映射到了/application根上下文下。比如,之前Spring Boot版本中的/beans现在需要通过/application/beans进行访问。

创建用户自定义的端点

新的@Enpoint注解简化了创建用户自定义端点的过程。如下的样例创建了名为person的端点。(完整的示例应用可以在GitHub上查看。)

@Endpoint(id = "person")
@Component
public class PersonEndpoint {

    private final Map<String, Person> people = new HashMap<>();

    PersonEndpoint() {
        this.people.put("mike", new Person("Michael Redlich"));
        this.people.put("rowena", new Person("Rowena Redlich"));
        this.people.put("barry", new Person("Barry Burd"));
    }

    @ReadOperation
    public List<Person> getAll() {
        return new ArrayList<>(this.people.values());
    }

    @ReadOperation
    public Person getPerson(@Selector String person) {
        return this.people.get(person);
    }

    @WriteOperation
    public void updatePerson(@Selector String name, String person) {
        this.people.put(name, new Person(person));
    }

    public static class Person {
        private String name;

        Person(String name) {
            this.name = name;
        }

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

这个端点借助@ReadOperation@WriteOperation注解暴露了三个方法。这个端点的定义不再需要额外的代码,它可以通过/application/person/application/person/{name}进行访问。另外,这个端点同时还会自动部署为JMXMBean,可以通过像JConsole这样的JMX客户端来访问。

增强端点的安全性

Spring Boot 2.0采用一种稍微不同的方式来确保Web端点默认的安全性。Web端点默认是禁用的,management.security.enabled属性已经被移除掉了。单个端点可以通过application.properties文件中的配置来启用。比如:

endpoints.info.enabled=true
endpoints.beans.enabled=true

但是,我们还可以把endpoints.default.web.enabled属性设置为true,从而将actuator和用户自定义的所有端点暴露出去。

Stéphane Nicoll是Pivotal的首席软件工程师,关于actuator的端点事宜,InfoQ与他进行了交流。

InfoQ:升级actuator端点来支持Jersey和WebFlux的过程中,您能描述一下您的体验吗?

Stéphane Nicoll:同时支持基于servlet的传统环境以及基于reactive理念的Web App是一个很大的挑战,尤其是在处理可扩展性特性方面更是如此。

InfoQ:Spring因为其紧凑且定义良好的API而闻名。这次重构又是怎样处理的呢?

Nicoll:在框架团队中,“spring-webmvc”和“spring-webflux”共享了很多来自“spring-web”的特性,其中我们可以看到很多创造性的设计。构建抽象是非常困难的,我非常开心我们在另外一个层级上完成了相同的事情。

InfoQ:驱动架构变化的原则是什么呢?

Nicoll: Spring Boot 2.0主要关注于搭建坚实的基础和良好的共识:我们相信这个新的端点基础设施方向是正确的,它所针对的是生产环境的特性,我们期待来自社区的反馈。

InfoQ:Spring Boot 2.0 GA版本预期会在何时发布?

Nicoll:事情尚不确定(双关语,这里原文使用的是flux,可能同时指不确定性和对WebFlux的支持),但是我们目前的计划是在年底释放Spring Boot 2.0 GA。

参考资料

查看英文原文Spring Boot 2.0 Will Feature Improved Actuator Endpoints

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/spring-boot-2-actuator-endpoints?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Ceylon语言加入Eclipse基金会

8月21号,由Red Hat创建的Java和JavaScript虚拟机语言Ceylon正式加入Eclipse基金,成为Eclipse Ceylon。如官方所述,此举是为了让Ceylon与Red Hat这个品牌撇清关系,将Ceylon打造成与厂商无关的语言,从而吸引更多的协作者。这种情况在业界也并非头一举,之前的Eclipse MicroProfile就经历了相似的过程。

InfoQ采访了Ceylon项目负责人Gavin King,了解幕后更多的细节。尽管官方已正式发表了声明,但是整个代码库的移交过程还在进行当中。King说,“Ceylon拥有庞大的代码库,包含了多个相互依赖的项目,所以需要做大量的工作”。而这次代码移交也带来了一些新契机:Eclipse基金在包命名方面有些规则会影响到Ceylon的运行时,进而导致新版的二进制包与旧版不兼容。King计划借此机会对Ceylon做一些有意义的变更。

下一个Ceylon版本应该是1.4,但目前它看起来更像是2.0。Ceylon在计入Eclipse后的第一个版本包含了一些巨大的变更,令人激动不已。

每当一个公司开发出一门新语言,围绕这门语言建立起来的开发社区总是会担心语言的长期发展是否会与该公司的商业策略紧紧地绑定在一起。纵观Java生态系统,有很多这样的例子:JetBrains曾公开承认,他们开发Kotlin的目的之一就是希望能够借此推动IntelliJ IDEA在企业领域的销售。King认为,如果Ceylon为某个厂商所独有,就会影响到它的采用率,所以要让Ceylon远离Red Hat品牌的庇护。不过,虽说Red Hat把Ceylon移交给了Eclipse基金会,但这并不代表他们就不再参与其中。实际上,Gavin King和Stéphane Épardaud(也是来自Red Hat公司)将继续领导该项目,他们也希望有其他贡献者加入,替代他们的角色。

Ceylon已经在很多国际性会议上和行业报告中露过脸,比如由Rebel Labs呈现的“JVM语言开发者指南”。但从TIOBE的排名来看,Ceylon的采用率并不高,所以就让时间来验证Ceylon加入Eclipse基金会是否能够改变这一状况吧。

查看英文原文:The Ceylon Language Is Now Eclipse Ceylon

该文章由WP-AutoPost插件自动采集发布

原文地址:http://www.infoq.com/cn/news/2017/09/ceylon-joins-eclipse-foundation?utm_source=news_about_java&utm_medium=link&utm_campaign=java