浅析MySQL JDBC连接配置上的两个误区

相信使用MySQL的同学都配置过它的JDBC驱动,多数人会直接从哪里贴一段URL过来,然后稍作修改就上去了,对应的连接池配置也是一样的,很少有人会去细想这每一个参数都是什么含义。今天我们就来聊两个比较常见的配置——是否要开启autoReconnect和是否缓存PreparedStatement

一、autoReconnect=true真的好用么?

笔者看到过很多MySQL的URL里都是这样写的,复制过来改改IP、端口和库名就能用了:

jdbc:mysql://xxx.xxx.xxx.xxx:3306/xxx?autoReconnect=true&...

从字面上看挺好的,在连接断开后还会自动重连,加之MySQL有8小时自动断开连接的特性,在断开后连接会重连,多好的功能呀。但是如果你去阅读一下MySQL Connect/J开发手册的相关章节,就会看到官方是这么说明的:

The use of this feature is not recommended, because it has side effects related to session state and data consistency when applications don’t handle SQLExceptions properly, and is only designed to be used when you are unable to configure your application to handle SQLExceptions resulting from dead and stale connections properly.

简单来说,不推荐开启这个特性,因为有副作用,在没有正确处理SQLException时容易造成会话状态和数据一致性的问题。

一般的应用都会使用数据库连接池,那我们的连接池是否正确地处理了抛出的SQLException呢?抱着这个疑问,我们来看看阿里的Druid连接池是怎么处理的。

首先,通过设置合理的健康检查及连接存活时间能解决大部分问题;其次,它有针对特定异常的处理逻辑,在MySqlExceptionSorter中会对特定返回码、异常类(比如com.mysql.jdbc.CommunicationsExceptioncom.mysql.jdbc.exceptions.jdbc4.CommunicationsException)以及错误消息进行处理,如果是致命错误就把连接抛弃。也就是说,如果用了Druid,不管是否设置了autoReconnect,都能保证后续请求的正确处理。JBoss的连接池实现也有类似的特性。

二、MySQL是否真的不用打开PSCache?

一般在设置连接池时,都会有类似下面的设置:

<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />

很多文章上都说PSCache对使用游标的数据库有巨大的性能提升,但MySQL不建议开启,因为它不支持游标。所以很多人在用MySQL时,都会将poolPreparedStatements设置为false,就连Druid的文档上也是这么写的。

但事实真的是这样么,MySQL使用PSCache真的对性能没有提升么?

先来看看关于游标的问题,其实大部分文章的表述不太准确,现在的MySQL在存储过程里是支持游标的,但其他地方的确不支持,具体详见官方手册(MySQL supports cursors inside stored programs.)。但这并不是我们要讨论的关键。

3.1.0版本后的JDBC驱动里有一个参数是useServerPrepStmts,如果服务器支持的话,会开启服务端PreparedStatement,默认是false官方手册中有如下说明:

Server-side Prepared Statements – Connector/J 3.1 will automatically detect and use server-side prepared statements when they are available (MySQL server version 4.1.0 and newer).

也就是说在MySQL 4.1.0版本后,3.1.0以上的驱动会检测到支持服务端PreparedStatement,并且启用该特性。根据MySQLTUTORIAL上的说明,整个过程分为PREPAREEXECUTEDEALLOCATE PREPARE三步。MySQL JDBC驱动的Contributor Jess BalintStackOverflow上做了一个详细的说明,《High-Performance Java Persistence》的作者也专门撰写文章分析了两者的区别。

ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()

上述代码在使用客户端PreparedStatement时,MySQL日志里看到的是:

255 Query  select 42
255 Query  select 43

如果用的是服务端PreparedStatement,看到的则是(实际每次执行只会传占位符的值,语句是不传的):

254 Prepare    select ?
254 Execute    select 42
254 Execute    select 43

在整个使用过程中,Prepare只会做一次,在这时服务端会对语句进行解析,后续收到具体值时会优化执行计划。如果同一条语句每次都新建PreparedStatement,那么每次都会多一回网络交互和语句解析,这显然是可以优化的。

综上所述,现在在使用MySQL时(如果版本比较新的话),出于性能考虑,应该在数据库连接池上开启针对PreparedStatement的缓存。如果没有使用连接池,或者所用的连接池不支持PSCache,也可以在JDBC连接上设置cachePrepStmts=true

事实上,MySQL的JDBC驱动还有不少针对性能的优化,比如设置useConfigs=maxPerformance(请酌情使用),相当于同时做了如下设置:

cachePrepStmts=true
cacheCallableStmts=true
cacheServerConfiguration=true
useLocalSessionState=true
elideSetAutoCommits=true
alwaysSendSetIsolation=false
enableQueryTimeouts=false

各位同学,是时候检视一下自己的系统是如何连接MySQL的了,时代在发展,有些以前适用的配置也许就不再合适了。

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

原文地址:http://www.infoq.com/cn/news/2017/03/Analysis-errors-MySQL-JDBC?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Devoxx 2017美国大会首日重要演讲一览

Devoxx美国大会今天开幕。

Devoxx是北美版的欧洲软件大会(European Software Conference)。广受追捧的欧洲软件大会由Stephan Janssen在2001年创立,组织方是比利时Java用户组(BeJUG,Belgian Java User Group)。今年的Devoxx在圣何塞会展中心(San Jose Convention Center)举办,第一天的特邀演讲嘉宾包括Venkat SubramaniamArun GuptaStuart MarksJosh Long

大会的第一个主题演讲是由Chet Haase所做的报告“科技企业中的技术工作(The Business of Technology Business Technology)”。Haase的演讲十分风趣,使得大会在一个轻松的主题演讲中开幕。在Haase演讲之后,是New Irond的CTO及Open Mastery的创始人Janelle Klein上台演讲,她的报告题目是“什么是身份?(What is Identity?)”。

Klein的报告内容非常紧凑,探讨了以下主题:

  • 想法是如何进入我们的大脑的
  • 将我们的大脑看作是一个感知生成器
  • 将意图看作是在设计上的约束
  • 我们认识自己身份的方式

Klein使用了软件领域的词汇解释(并讨论)了大脑的工作机制。例如,Klein提出将人类大脑看作是一种感知生成器,指出我们是通过识别模式去理解环境中的事物。

她借用了开发人员所熟知的语言,以“继承”(inheritance)作为一种描述,隐喻事物间是否存在着从属关系。我们所熟悉的事物是“从自我(或者属于自己的事物)扩展而来”,而我们不熟悉事物的是“从对象(Object)扩展而来”。报告提出的理念是,有一些事物我们认为具有从属关系,也有一些事物我们并不认为具有从属关系。

“我们编写单元测试”和“我们做结对编程”这类陈述建模了内团体(In-Group),在我们看来是“从自我扩展而来”。对于这样的事物,我们很容易理解并产生共情(译者注:共情“empathy”是一个心理学名词)。而不好的一面在于,我们易于对外团体(Out-Group)客体化(Objective)。因此,我们会认为“经理”或“测试者”是“从对象扩展而来”,这意味着我们下意识地将“测试者”看成是一个可供使用的工具,而非“和我们一样的”员工。她认为该模型所描述的是一种我们易于频繁采用的分类方法,不能对“与我们一样的”或者并非“从自我扩展而来”的事物产生共情。

Klein指出,如果我们能认识到这种人类大脑使用的分类方法,就很容易对大脑重新接线以改进共情。她给出了一个对简单的潜入大脑(Brain Hack)的建模方法,这是一个两步的过程,用于改进彼此之间及环境中事物的共情(类似于在我们的思维中设置一个断点)。

这看上就类似于:

  1. 停下来,考虑当前事物是一个人,还是一个对象。
  2. 选择人。

就是这么简单!

Devoxx 2017美国大会首日重要演讲一览

Klein继续就如何认识我们自身、我们所秉持的信念等问题进行了探索,并对开发人员的思维给出了独到的见解。她还提出了其它一些潜入大脑的方法,可以实现用新方式考虑我们的环境信号,并提出了如何中断这些环境信号。

Klein在演讲的最后,给出了认识我们自身以及他人的切实可行的方法,该方法将对过去自我的汇总用“身份1.0”表示,而使用“身份2.0”表示“此刻选择非我莫属”。

大会首日的其它报告还关注于Java、Andriod和现代Web等话题,其中包括:

  • Hanneli Tavante讨论了Java开发人员如何做Rust开发。该演讲中所探索的主题包括:什么是Rust、为什么应考虑使用Rust,以及从Java开发人员的角度看Rust提供了哪些特性。她在演讲中给出了一个简单的例子,就是用Rust实现FizzBuzz问题,依此探讨了Rust的不变性、生存期(lifetime)、trait等问题,甚至还介绍了Rust的一些不足之处,例如学习曲线陡峭。
  • Marcus Bertrand来自于Atlassian,他的演讲探讨了代码审查与Pull Request的对比。Bertrand在演讲中介绍了一些广为使用的代码审查方法,并给出了在自己的团队中实现各个方法的建议。
  • Ty Smith来自于Uber,他的演讲介绍了深度安卓集成(Deep Android Integrations),并给出了他在Evernote、Twitter和Uber工作期间积累的一些最佳实践。
  • Venkat Subramaniam是Agile Developer Inc.的创始人,当日他做了两个演讲,第一个是关于Java的响应式编程,第二个是关于函数式编程。

大会首日共有10个并行进行的会议,约有43位演讲者做了报告,从“使用TypeScript 2.0尽早排除故障”到“编写伟大测试用例的十条基本规则”。据Janssen介绍,会议为期三天,首日预计有大约750名开发人员参加。

明天是大会的第二日,主题演讲者将是Rama Akkiraju,演讲题目是“从科学幻想到科学事实:人工智能是如何改变我们构建应用和使用数据的方法的”。

查看英文原文: Devoxx US 2017: Day 1 Recap


感谢冬雨对本文的审校。

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

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

原文地址:http://www.infoq.com/cn/news/2017/03/devoxx-day-1?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Lightbend就收购OpsClarity一事与InfoQ的对话

收购了咨询公司BoldRadius九个月后,Lightbend宣布了其收购OpsClarity的消息。OpsClarity是一家专业做交互式应用监控的公司。

Lightbend成立于2011年,刚成立时叫TypeSafe,直到去年才改名为Lightbend。收购了BoldRadius和OpsClarity之后,Lightbend如今的员工人数已超过了130人,这个数字是2015年12月时候的两倍。当问到公司的成长时,Mark Brewer,Lightbend的董事长兼CEO,告诉InfoQ:

Mark Brewer:这是好事,同时也很有趣。我很开心公司能以这种方式成长,我们得到了一个专业的团队,他们知道他们在做什么,也清楚地知道自己的角色,脚踏实地好好做事。我们很快就有了新的产品。不只是那个团队,而是我们有了一个产品可以投入市场。已经有很多客户在频繁地使用它,并且用得很开心。

Alan Ngai,现任Lightbend云服务的VP,在2012年底与人合伙创立了OpsClarity。他们在监控交互式应用方面的专业性为Lightbend及其客户带来价值,同时也对DevOps在四个方面提出了挑战:

  • 容器
  • 微服务和交互式框架
  • 持续集成
  • SMACK stack中的技术

InfoQ采访了Mark Brewer和Alan Ngai以对他们新的合作关系做更多了解。

InfoQ:你当前在Lightbend的主要职责是什么?你的日常工作都有哪些?

Alan Ngal:收购是最近才发生的,因此我近期主要专注于让OpsClarity更好的集成进Lightbend,并在OpsClarity的路线规划里提供更多关于Lightbend技术的见识,也就是说,找到更好的方式来集成Lightbend提供的产品。至于每天的日常工作,我更专注于为Lightbend提供云服务。


Mark Brewer: Alan的角色,当然是要继续管理OpsClarity团队。他和他的团队给我们带来了Lightbend之前不具备的经验。我们之前毫无关于云服务运维的经验。当然,我们的客户经常在云上构建应用。所以对于在云上构建应用,我们是知道如何去做的。我们只是还没有运营过云服务,或者说,在OpsCalrity成为我们公司的一部分之前我们没有做过。所以我们为此感到非常兴奋,我们会有更多这方面的经验。你在这个公司将会看到更多的云服务。

而我作为公司CEO的任务是运营这个公司。我来这里已经五年了,这个公司也将成立满六年。它创建于2011年2月,正好是六年前。我在公司成立一年后加入,并成为职业CEO,来运营公司并搞清楚要将什么投入市场。我之前已经做过几次类似的事情。我在加入之前就已经知道这个公司了,那个时候公司名字还叫TypeSafe,我还在VMware和SpringSource的时候,我们的一些客户使用了以Scala和Akka见长的TypeSafe服务。

InfoQ:你有参与Spring并入Pivotal的事件吗?

Brewer:我那个时候还在SpringSource,这个公司在2009年被卖给VMware。 Pivotal于2013年被分拆出VMware。我参与了拆分出Pivotal的计划。

InfoQ:能介绍下OpsCalrity的历史和时间线吗?

Ngai:我和我的合伙人在2012年末创建了这家公司,那个时候,我们在努力探索在这个领域我们能做什么来增加价值。我曾经在eBay和Yahoo的搜索和云团队工作过。我的合伙创始人,一个曾在Google和Yahoo工作,另一个曾在Cisco从事数据运营业务。因此,我们对于这个领域是什么样的有很好的理解。当时我们就看到了开源和云的趋势。我们认为,我们能提供的是我们在数据体系里的专业性和经验——采集大量的数据,从数据里分析出有价值的信息,让信息易读、易用。在2013到2014年,我们主要致力于打造一个平台。我们有一些测试客户,但是因为我们做的是数据密集型的应用,我们用了很长的时间去做调整和收集足够的数据以验证我们的平台是可以工作的。我们有相当一段时间处于测试周期,大概有六个月,或者是将近一年的时间,然后在2016年我们去了GA。那个时候,我们对数据应用的专注更加专业,因为我们跟Lightbend一样,看到了未来的趋势——越来越多的人在使用Kafka和Spark来构建以数据为中心的应用。实际上,那时我们才刚刚第一次见面,那是在一个Kafka会议上,我们讨论了在这个领域如何做监控。Lightbend的Brad Murdoch也在关注同样的领域,所以来找我们讨论。也正是在那个时候,我们开始相互认可,并逐渐意识到我们对未来看到了同样的愿景。

InfoQ:关于OpsClarity加入Ligntbend,你有什么想说的或者更多信息可以分享的吗?

Brewer:在Lightbend我们看好的市场机会是把新类型的应用和对老应用的现代化结合起来。在这个新的世界里,要么是用微服务架构来对这些新系统进行设计和编程,要么就是把一个庞大臃肿的老应用拆分得更容易理解、更加可扩展、更易管理;这就是所谓的微服务。这个市场里我们看到的另一个有趣的趋势是,一些公司因为需要流式的应用来找我们。这些应用本身是跟动态数据打交道的,而不是静态数据。而这两个市场趋势,微服务和数据流,正好成为了当下最热门的事情之一。说实话,它使得大部分的人来到我们平台。这些趋势被包装成Reactive Manifesto,它描述了当代应用需要满足当今现实需求的特点。

而对OpsClarity的收购其实有两个原因:其一,他们跟我们紧密合作,用户得以看到使用Lightbend技术创建的应用的内部信息,看到Akka的内部信息,看到Akka信箱或者Akka服务集群之间的通信消息;其二,对流式技术做监控,比如对Kafka做监控。我们正在建立合作关系,把他们的产品和我们的平台结合起来,然后就有了我们收购这家公司的机会。二者的结合非常有意义,现在我们的客户一次性能得到两个产品:我们的产品和OpsClarity的产品。

InfoQ:这个其实回答了我们的一个问题。我们本就准备问OpsClarity会带来什么以及在加入Lightbend之前他们的客户是如何使用OpsClarity的。看来OpsClarity加入Lightbend是天作之合。

Brewer:确实是天作之合。还有一点我可以告诉你的是,OpsClarity是使用Lightbend技术设计和构建他们的系统的。所以大量使用了Scala和Akka。这个使得集成变得非常容易,当然这也使得做出收购的决定变得更容易。


Ngai:我只有一点要补充的,就是我们看到的愿景和Lightbend非常相似,就是越来越多的公司在使用开源技术采取分布式的方式构建他们的软件栈。我们从运维的角度看到的是,对于DevOps和开发工程师来说,让人们理解环境里发生了什么越来越难,更别说监控了。与此同时,Lightbend在帮助客户构建这样的分布式系统,而OpsClarity是用来帮助人们监控这样的系统,所以说确实是天作之合。

InfoQ:对于我们的读者来说,他们可能并不熟悉OpsClarity,也不知道如何监控交互式应用。您能针对如何做监控和使用什么技术做个概括性介绍吗,如果不涉及专有性的话?

Ngai: 我认为最关键的因素是,人们越来越多地使用各种各样的开源技术来构建他们的应用,甚至Lightbend本身,你也可以看到Play、Akka、Lagom、Scala等技术。而目前大多数的应用还需要其他技术,比如需要Kafka来做消息队列,或者某种NoSQL数据库,或者像Spark、Flink之类的数据处理技术。我们就是针对这样的环境做的设计,因为我们认识到,对于任何工程师或者DevOps来说,在所有这些领域都成为专家是不可能的,更不用说去做监控或者去搞明白要监控什么了。OpsClarity提供的平台的关键点在于,关于这些系统的信息是内建在产品中的。你并不需要在你的团队中有一个Kafka专家、一个Cassandra专家、一个Spark专家以及一个Akka专家,我们已经包含了很多这些方面的知识,告诉你如何去监控这些系统,错误范例是什么,关键指标是什么,以及如何结合产品去做监控。这就是OpsClarity能为我们的客户在分布式领域提供的最有价值的东西。


Brewer:有一件事我相信OpsClarity也看到了 ,就是在这个新的时代,你的容器和微服务可能只存活非常短的一段时间,而不像在应用总是很庞大的服务器时代,使用WebSphere和WebLogic,服务器永远处于运行状态。其实有的服务是长期使用,有的只是临时使用。在这个新的分布式和积木式的微服务世界,你可以在Docker容器中运行或者单独运行只存在几秒钟的服务。去做监控,或者说具备监控的能力,第一很困难,第二,使用老的监控方案是行不通的。或者说在新的世界是行不通的。

InfoQ:微服务在过去几年一直是一个很有趣的话题。基于企业开发者趋势2016年度报告,各种组织在以下几种情况的分布很平均:(a)在生产环境使用微服务,(b)正在考虑使用微服务,(c)在沙箱环境试验微服务,(d)对微服务完全没有兴趣。还有不少针对使用微服务的开发者的警告标语,包括“微服务的七宗罪”。这传达出的信息似乎是“小心使用微服务”。针对这些顾虑,Lightbend有没有什么能做的呢?

Brewer:我们正在尝试。首先,是教育,教会人们如何以正确的方式架构、构建和设计这些系统。我们出版了一些这方面的书。他们大体上都以简短、好读的方式介绍微服务,以及以什么样的方式去思考你的系统和如何用微服务的方式做架构。其次,为开发者提供合适的工具。给他们提供能在构建这些系统时提供帮助的工具。我们在去年二月的时候发布了一个项目,叫做Lagom,这是我们的微服务框架。这个名字是个瑞典词,它的意思是“刚刚好”、“大小合适”。这就是我们想要传达的。微服务并不一定要非常小,它的关键并不在于大小,而是如何做事。它可以把一件事做的很好,并以隔离的方式做,这个意味着它方便扩展,并且当一些错误发生时,只在隔离空间里抛错而并不会导致整个系统罢工。Lagom框架的设计是为了帮助人们以正确的方式构建系统或微服务。当然,还有很多别的事我们可以做,这只是个好的开始。


Ngai:关于监控系统这点,Lagom和Lightbend技术致力于帮助行业构建这样的架构:流式的、异步的、消息驱动的等。除了帮助开发者自动构建和监控这些系统,让市场知道这些新型的分布式系统的关键运维难点是很有必要的。比如,你可以回想一下过去对于Web服务器人们最关心的东西——请求延迟和请求吞吐量,在一个异步的消息驱动的世界监控这些将会很困难。再比如,在Lagom,背压是运维会实际关心的大事。那么针对监控和这类指标我们如何提供服务呢?

InfoQ:Alan在新闻稿里声明过,“加入Lightbend,我们能够为交互式平台提供更先进的监控能力,实时收集和分析各项指标,在分布式系统自动发现动态组件,以及针对某些特定的开源框架的内建功能。”您能为我们的读者针对这个做一些详细叙述吗?

Ngai:监控不仅仅是收集指标数据。它不只是跟某个API或者某个JMX终端通信然后收集数据并在仪表盘画图。大部分的监控工具都可能做到这些。我们想要给开发者和运维工程师提供的实际上是洞察力。对于一个服务,他们实际上关心的是什么?现在,每一个服务都会暴露成百上千的数据指标,有各种各样的维度,比如主题名称、分区名称或者其他类似的数据。但是哪些数据,以及这些系统什么方面的性能特征是真正重要的呢?DevOps和工程师需要保持关注的是什么呢?他们最需要关心的四个或五个指标是什么呢?其中的每一种指标,他们又代表了什么特性?它是群组指标,还是延时指标,抑或是背压指标还是其他别的呢?对于不同类型的指标,你需要用不同的方式做监控。OpsClarity提供的智能化,就是理解这些指标是什么,如何做监控,然后以合理的方式提供出来。接下来我们要更加专注于Lightbend组件并充分理解,除了客户如何使用Lagom、Play、Akka等来构建架构,什么是人们需要关注的重要的性能和运维特性。

InfoQ:企业开发趋势2016年度报告还说了,“如果你仍然以12~18月为周期发布软件,你可能也会回到瀑布模型。”在新闻稿里,四个常见用例之一说到,“那些用持续集成来运行动态环境的,意味着新的代码会频繁发布,经常是每周好几次。”你觉得对于软件更新来说,多长时间是最优的更新周期?

Brewer:很明显,这个要分情况,它取决于组织在敏捷开发方面的专业性和经验,以及他们构建的是什么样的项目。有一些项目需要非常频繁的更新或者发布。有些公司会持续的发布更新,比如LinkedIn,至少每小时会发布一次,有时候甚至一小时会发布好几次。这是他们的实战经验,他们已经这么做好多年了,他们一直如此运营。所有团队都知道他们会每个小时发布新代码。但这并不意味着每个人在每个小时都会更新代码。如果他们想在某个发布周期更新代码,他们只需要在那个时间点之前提交代码。还有一些公司,有一些是我们的客户,是每个月发布一次。他们也能习惯于每18~24个月经历一个版本。我不知道是不是有理想情况,但目前为止我没有找到统一的答案,能针对某人提交代码的频率说“这是完美的敏捷开发实战”。


Ngai:多长时间为发布周期的都有。我想它取决于这个团队选了什么样的技术栈。如果你用了更多老的技术,比如上一代的技术,那么开发周期可能会长一些。如果你开始用Docker和Mesos,以及这一类的其它技术,几乎可以肯定,开发周期一定会短许多,因为在这种环境下,你只需要一条命令就可以启动整个环境。

InfoQ:每小时一次,这个很频繁呀。LinkedIn发布的都是什么样的代码?大部分都是改bug吗?

Brewer:是功能代码,也可能是bug修复。Twitter也类似。有很多这样的Web网站,这是他们的实战经验。一天一次对他们来说太慢了。很多都是一天升级好几次。

InfoQ:这实在很让人振奋。大部分人都知道吗?

Brewer:有一些关于这个的信息,但是你还是会对某些团队感到惊讶的。他们习惯了以这种持续发布的方式运营。即使是在Lightbend,某些团队也是发布频繁,他们的敏捷开发工作显得其他团队比较慢。

InfoQ:我们可能会认为瀑布式开发已经是过去时了。

Brewer:这方面仍有争论,如果你在构建一个庞大的应用,一个老式的庞大应用,使用的是过去的技术,那么就没有理由去切换或者强迫自己去做敏捷,还是使用瀑布式就好。我并不倡议这个,但是你是可以这么做的。

InfoQ:切换到敏捷是一个很大的改变。好像有很多反对力量,就像15年前结对编程和极限编程的出现的时候那样。我们希望,今天,大部分的公司能切换到敏捷,尤其是现有的J2EE应用,而Oracle似乎对J2EE 8缺少支持。我们对于现今还有多少组织仍然在使用J2EE很感兴趣。

Brewer:比你想象的要多的多。很多仍然在使用J2EE的公司也同时在探索新技术。他们有在新项目中使用Lightbend技术以及其他技术,但是他们还有很多线上应用。有很多都是用老的方式写的,在老的应用服务器、WebSphere或者WebLogic上运行,这些仍然需要维护。


Ngai:还有一种对持续部署和持续集成发展的理解。大多数我交谈过、接触过的工程师,他们即使在实际中并不会每天发布、每小时发布或者每周发布,他们也知道这个概念。有一种说法是,这是所有人的方向,不管你现在使用的是什么,你将来会需要这么做。所以说,是有这个趋势的。

InfoQ:SMACK-Spark,Mesos,Akka,Cassandra,Kafka。有趣的是,除了Akka,这些都是Apache的项目。你们网站上有描述,Lightbend支持所有这些Apache产品。

Brewer: Akka不是Apache的项目。我们使用了Apache开源协议,但是它属于Lightbend,所以它不是一个Apache项目。但是你说的对,其他的那些都是Apache项目。这些项目的共性并不只是他们都是Apache项目,而是这些都在新的基于流的应用中经常被一起使用。我可以说,OpsClarity拥有的产品,也就是现在Lightbend拥有的产品,很大一部分都是基于SMACK技术栈构建的。他们使用了这些技术来创建所谓的下一代监控平台。在我们的客户那里我们看到了类似的事情,尤其是当他们在处理大量的、流动的数据的时候。他们希望能够在应用中实时处理这些数据,而不是等数据写回硬盘再读取。他们的另一个不太明显的共性是,他们大部分都是用Scala写的。你也知道我们是一家主要用Scala的公司。

InfoQ:有了BoldRadius和OpsClarity加入Lightbend,Lightbend的下一步会是什么?

Brewer:我们会让这两家公司帮助我们履行承诺。首先,作为服务团队,帮助客户接受培训,然后实现和利用这些技术。但是,我们不是一家为人们做开发工作的咨询公司。现在我们有了专家来做知识分享,提供最佳实战培训。其次,有了OpsClarity,我们就可以提供商业产品,帮助人们能够更好的了解应用的表现如何,以及提供计划如何让应用做的更好。那么,下一步是什么呢?并没有什么我们现下积极追求的东西。但是你会看到,像我刚才提到的那样,Lightbend会提供更多的基于云的服务。监控是第一个,但是你也会看到更多的Lightbend提供的高价值的服务,让公司利用技术构建应用。我们的工作就是让他们成功,并且确保他们在构建这些应用的时候,从中得到最大的好处。

查看英文原文:Lightbend Speaks to InfoQ on Their Acquisition of OpsClarity


感谢刘志勇对本文的审校。

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

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

原文地址:http://www.infoq.com/cn/news/2017/03/lightbend-acquires-opsclarity?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Kotlin 1.1新增协程、类型别名特性,提升了对JavaScript的支持

Kotlin的市场主管Roman Belov撰文写到,Kotlin的新版本引入了多项新的语言特性(其中最值得注意的就是协程),同时还提升了对其JavaScript目标环境的支持。

尽管依然被认为处于试验性阶段,但是Kotlin 1.1最关键的新特性之一就是协程(coroutine),这个特性可以通过使用三个高层级的构造(construct)来实现:asyncawaityield。举例来说:我们可以采用asyncawait来处理异步操作:

// 在后台线程池中运行代码
fun asyncOverlay() = async(CommonPool) {
    // 开启两个异步操作
    val original = asyncLoadImage("original")
    val overlay = asyncLoadImage("overlay")
    // 然后,将overlay应用到这两个结果上
    applyOverlay(original.await(), overlay.await())
}
// 在UI上下文中启动新的协程
launch(UI) {
    // 等待异步overlay完成
    val image = asyncOverlay().await()
    // 然后在UI上显示
    showImage(image)
}

注意,这里使用了launch,它会启动一个协程。实际上,await只能在一个协程中使用或者在使用关键字suspend声明的函数中使用,这样的话,能够让编译器生成相应的代码,从而在协程中运行函数:

suspend fun workload(n: Int): Int {
    delay(1000)
    return n
}

在上例中,delay推迟了协程,并不会阻塞它关联的线程。

协程还能以懒加载的方式借助yield生成序列:

// 推断出的类型为Sequence
val fibonacci = buildSequence {
    yield(1) // 第一个Fibonacci数字
    var cur = 1
    var next = 1
    while (true) {
        yield(next) // 下一个Fibonacci数字
        val tmp = cur + next
        cur = next
        next = tmp
    }
}
println(fibonacci.take(10).joinToString())

因为还是试验性的,协程目前只是选择性使用状态(opt-in),它们的API在未来的释放版本中可能会有所变更。

Kotlin 1.1添加的其他重要的新特性包括:

  • 类型别名,允许用户为某种类型定义其他的名称。
  • ::操作符能够获取特定对象某个方法的成员引用。
  • 数据类可以进行扩展。
  • 在lambdas中支持Destructuring。

在对JavaScript的支持方面,1.1版本的主要目标是让对JavaScript的支持能够达到与JVM对等的程度。这意味着,所有的语言特性都可以在这两个目标平台中使用,不过反射除外,目前JavaScript还没有这样的特性。尤其是:

  • Kotlin标准库中很大一部分都可以用在JavaScript上。
  • 生成的代码对JavaScript工具更加友好,比如压缩器(minifier),优化器(optimizer)等等。
  • 用于Kotlin类声明的external修饰符目前在JavaScript中已经实现了。

我们可以使用在线的REPL来尝试Kotlin,也可以按照多种不同的方式来进行安装。

查看英文原文Kotlin 1.1 Adds Coroutines, Type Aliases, Improved JavaScript Support

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

原文地址:http://www.infoq.com/cn/news/2017/03/kotlin-11-released?utm_source=news_about_java&utm_medium=link&utm_campaign=java

JSON-P 1.1现已发布公开预览版

JSR 374(JSON-P 1.1版本)的公开预览版现在已经开放,JSON-P是一个针对处理JSON的Java API。这个版本有望和JSON绑定库(JSON-B)的Java API一同被添加到Java EE 8的发布版本中,并且它还保持了JSON-P当前所支持的JSON IETF标准。它提供了如下支持:

在2013年,JSON-P作为GsonJackson的替代方案,被引入到J2EE 7的发布版本中。它被设计用于解析、生成和查询标准的JSON文档。

JSR-367是JSON绑定库的Java API,它也被纳入了Java EE 8的发布版本中。JSON-B被设计用来将JSON与Java中的对象绑定起来。InfoQ对之前JSON-B公开预览版的发布也有过报道

入门指南

我们先从JSON-P的解析器(Parser)和指针(Pointer)的一个例子开始入门,考虑如下的JSON文档:

[
    {
    "publication":"New Vaadin Spring Release Introduces Enhanced View Management",
    "publicationDate":"2016-12-30 00:00:00",
    "author":"Michael Redlich",
    "publicationType":"Article",
    "publisher":"C4Media"
    },
    {
    "publication":"Pivotal Releases First Milestone of Next-Generation Spring Data Featuring Reactive Database Access",
    "publicationDate":"2017-01-19 00:00:00",
    "author":"Michael Redlich",
    "publicationType":"Article",
    "publisher":"C4Media"
    },
    {
    "publication":"Netflix Introduces Hollow, a Java Library for Processing In-Memory Datasets",
    "publicationDate":"2017-01-31 00:00:00",
    "author":"Michael Redlich",
    "publicationType":"Article",
    "publisher":"C4Media"
    }
]

这个JSON文档可以使用JsonParser进行解析:

InputStream fis = new FileInputStream(JSON_FILE);
JsonParser parser = Json.createParser(fis);
while(parser.hasNext()) {
    JsonParser.Event event = parser.next();
    switch(event) {
        case START_ARRAY:
        case END_ARRAY:
        case START_OBJECT:
        case END_OBJECT:
        case VALUE_FALSE:
        case VALUE_NULL:
        case VALUE_TRUE:
            System.out.println(event.toString());
            break;
        case KEY_NAME:
            System.out.print(event.toString() + " " + parser.getString() + " - ");
            break;
        case VALUE_STRING:
        case VALUE_NUMBER:
        System.out.println(event.toString() + " " + parser.getString());
            break;
        }
    }
fis.close();

通过使用JsonPointer,我们能够找到JSON文档中的特定元素:

InputStream fis = new FileInputStream(JSON_FILE);
JsonReader jsonReader = Json.createReader(fis);
JsonArray jsonArray = jsonReader.readArray();
JsonPointer pointer = Json.createPointer("/1/publication");
JsonValue publication = pointer.getValue(jsonArray);
System.out.println(i + ": " + publication);
fis.close();

这个例子中找到并且显示出了上述JSON文档中的第二个publication。我们在GitHub上准备了一个完备的实例程序,其中包括JSON-P、Gson以及Jackson。

最新的JSON-P 1.1规格书能够在JSR-374网站下载到。

大名鼎鼎的Java EE传播者Reza Rahman最近发布了一篇博客,他在其中阐述了JSON在Java EE 8中起到的作用:

这两个API对于加强JSON在Java中的地位至关重要,就像JAXP(处理XML的Java API)和JAXB(XML绑定库的Java API)在许多年前所起的作用一样。通过这两个API,Java开发者可以简单地将JSON视为另一种Java序列化格式。不需要过多的第三方库和配置了:JSON处理变得极其简单。在我看来,这些API非常关键,它们应该被纳入一个模块化的Java SE版本中,就像是JAXB和JAXP已经成为了Java SE中的一部分一样。

JSON-P和JSON-B的最终版本有望在2017年4月发布。

其它资源

关于JSON-P的其它更多信息请访问如下资源:

查看英文原文:Public Review of JSON-P Specification 1.1 is Now Open


感谢薛命灯对本文的审校。

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

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

原文地址:http://www.infoq.com/cn/news/2017/03/json-processing-public-review?utm_source=news_about_java&utm_medium=link&utm_campaign=java

JVM很重吗?

一种语言是轻是重,可能会影响到使用者的选型;同时,语言的轻和重有很多度量的维度。本文通过几个方面对比,看看JVM是否有想象中的那么重。

如何来度量?

  • 下载包的大小?
  • 运行时占用的资源?
  • 库文件占用硬盘大小?
  • 部署成本?
  • 开发成本?

这些问题可以让我们抛开一些偏见,从多个方面来度量JVM。

安装成本高嘛?

认为JVM重的第一个原因是前期安装成本比较高。相比于下载大小只有大约15MB左右的Node和Ruby安装包,JDK下载大小大约为200MB。但是,这仅仅是表面上的,对于Node和Ruby,系统上还必须安装C编译器,这就得再加上几百兆空间。甚至在生产环境也需要一个编译器!

Node和Ruby实际需要的总大小被依赖的每个小部分分解了,如果将这些部分都统计起来,还不如单独下载200MB的包比较高效,更别说在依赖上花费的时间了。

JVM运行时重吗?

JVM运行速度很快,甚至可以说是最快的运行时框架之一。随着时间的推移,JVM运行的速度更快,更轻便。上千个工程师致力于优化JVM,甚至有人已经为其贡献了21年的代码。

JVM支持原生线程、多个内核,并且能够通过各种配置修改JVM行为,或者只使用默认配置。其中可能必须要了解的配置是如何设置JVM的内存,以控制JVM在限定环境下发挥它的作用。

通常情况下,部署一个Java应用程序只需执行java -server -Xmx512m app.jar。如果这还不够,可以参考使用其他参数。

磁盘使用量重吗?

对于Java应用程序,如果使用Maven作为其依赖管理程序,所有依赖都会下载到~/.m2目录。以下这个示例,是结果经过了9个月的Clojure开发,仅仅积累了1010MB依赖,甚至都不到1G空间。

$ du -sh /usr/local/opt/rbenv/versions/2.3.3 ~/.nvm/versions/node/v6.9.1 ~/.m2
690M    /usr/local/opt/rbenv/versions/2.3.3
232M    /Users/kenneth/.nvm/versions/node/v6.9.1
1010M   /Users/kenneth/.m2

上述示例中,Ruby目录为全新安装,其中内容只有一个博客和一个简单工程。这些依赖占用了近700MB依赖存储。

Node相关目录只安装了ember、docpad和bower,总大小超过200MB。

部署过程重嘛?

通常情况下Java应用构建结果为Jar或者War包。其中Jar包包含了应用程序运行所需要的所有文件,而War包一般需要一个应用服务器(如Tomcat、Jetty等)。

对于Jar文件,我们只需要简单的将JAR文件放置到需要部署的机器上,让JVM执行它即可。而War包,也只需要放置到应用服务器对应目录中。当前,也可以简单的将HTTP服务端代码整合到Jar包中,类似于目前流行的微服务应用(如Springboot)。而且,至少Java应用不需要在生产环境机器上运行apt-get install build-essentials

JVM日常使用

归功于Java生态的发展,开发基于Java的应用有一系列工具。例如通过Maven,我们可以方便的管理Java应用的依赖,并通过其插件,得到最终构建出来的Jar包或者War包,甚至直接运行。通过IDE,可以方便的进行代码补全、应用启停、断点调试等操作。

另外,JVM可以很方便的通过启动参数配置内存使用,在开发机器上和实际生产机器上使用不同的参数,降低本地调试成本。同时,Java还定义了JDWP(Java Debug Wire Protocol),支持运行时替换代码,而无需每次修改都重新编译,重新启动。

总结

判断JVM是否重需要非常小心。作为一种语言,判断Java语言优劣需要各方面评判,但是JVM可以单独剥离出来讨论。

很多人都认为JVM是个巨大的怪兽。不过归功于诸多大神的支持,使得我抛弃了之前的观点。

不过,本文没有“Node语言终结”或者“Ruby语言终结”的意思,仅仅是通过一些角度给出一些观点,读者可以借此考虑消除自己常用语言的膨胀。

查看英文原文:https://www.opensourcery.co.za/2017/01/05/the-jvm-is-not-that-heavy/(译文有删减)


感谢郭蕾对本文的审校。

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

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

原文地址:http://www.infoq.com/cn/news/2017/03/JVM-how-weigh?utm_source=news_about_java&utm_medium=link&utm_campaign=java

Struts2再爆高危漏洞,解决方案一览

本文为绿盟科技马宇静投稿。

Apache Struts2作为世界上最流行的Java Web服务器框架之一,3月7日带来了本年度第一个高危漏洞——CVE编号CVE-2017-5638。其原因是由于Apache Struts2的Jakarta Multipart parser插件存在远程代码执行漏洞,攻击者可以在使用该插件上传文件时,修改HTTP请求头中的Content-Type值来触发该漏洞,导致远程执行代码。

Struts作为一个“世界级”开源架构,它的一个高危漏洞危害有多大,下面两张图可以让大家对这个漏洞的影响范围有一个直观认识。

Struts2再爆高危漏洞,解决方案一览

全球互联网上开放的Apache Struts分布

Struts2再爆高危漏洞,解决方案一览

中国互联网上开放的Apache Struts分布

数据来源:绿盟科技威胁情报中心NTI

检测与修复方案

如果您的设备已经检测出存在Struts2漏洞,根据您的具体情况有以下三种解决方式:

1.官方解决方案

官方已经发布版本更新,尽快升级到不受影响的版本(Struts 2.3.32或Struts 2.5.10.1),建议在升级前做好数据备份。

Struts 2.3.32 下载地址:https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.3.32

Struts 2.5.10.1下载地址: https://cwiki.apache.org/confluence/display/WW/Version+Notes+2.5.10.1

2. 临时修复方案

在用户不便进行升级的情况下,作为临时的解决方案,用户可以进行以下操作来规避风险:

在WEB-INF/classes目录下的struts.xml 中的struts 标签下添加

<constant name="struts.custom.i18n.resources" value="global" />

在WEB-INF/classes/ 目录下添加 global.properties,文件内容如下:

struts.messages.upload.error.InvalidContentTypeException=1

Struts2再爆高危漏洞,解决方案一览

配置过滤器过滤Content-Type的内容,在web应用的web.xml中配置过滤器,在过滤器中对Content-Type内容的合法性进行检测:

Struts2再爆高危漏洞,解决方案一览

3.技术解决方案

对于没有网络防护设备的企业,可以使用专业厂商的防护设备进行防护;或者使用专业安全厂商的针对性安全服务对已有业务进行漏洞排查和修复。正在使用安全防护设备的企业,目前各大安全厂商都已经推出针对该漏洞的紧急升级包,请及时升级已有防护设备的防护规则和检测规则。

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

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

对话Eric Bottard:Spring Cloud Data Flow的Cloud Foundry特别版

Pivotal发布了Spring Cloud Data Flow的Cloud Foundry特别版,用于在Cloud Foundry平台上为微服务提供编排服务。

Spring Cloud Data Flow是对Spring XD进行重构的产物,而它的Cloud Foundry特别版为企业在Cloud Foundry上运行以微服务为中心的架构提供了一系列实用的模式和最佳实践,不过它并不是一个开箱即用的ETL或数据集成方案。Spring Cloud Data Flow将开发人员从分布式架构的复杂性中解脱出来,提供了一站式的系统集成方案,为项目复用奠定了坚实的基础。

InfoQ采访了在Pivotal负责该项目的高级工程师Eric Bottard

InfoQ:你能简要地介绍一下Spring Cloud Data Flow的Cloud Foundry特别版吗?它在Spring的生态系统里依赖了哪些项目?这个项目有其他短一点的名字吗?

Eric Bottard : Spring Cloud Data Flow的Cloud Foundry特别版前身是运行在Cloud Foundry上的旧版Spring Cloud Data Flow。它是整个生态系统的一部分(还有其他运行时,由“部署器”提供支持),可以被看成是Spring Boot应用之上的一个编排层。更准确地说,它支持“流”(由多个基于数据驱动的应用组成,应用间挨个发生交互,从头到尾形成一个数据流)和任务(基于固定数量数据运行的应用,且只运行一次)的协调部署和监控。

它为使用Spring Cloud Stream或Spring Cloud Task的Spring开发者提供了额外的选择。Spring Cloud Data Flow本身也是一个Spring Boot应用,并依赖了其他Spring Cloud软件包

它的名字太长了,所以我们给它取了个别称叫SCDF,Cloud Foundry版本的叫作“SCDF for CF”。

InfoQ: Spring XD对这个项目的设计是否产生了重大影响?Spring Cloud Data Flow解决了哪些在Spring XD中存在的问题?该如何看待这个项目与Apache Spark、Flink、Kafka之间的不同?

Bottard:我们最初将Spring XD设计成一个独立的分布式数据管道产品,它为应用部署提供了一个弹性的运行时,我们为此投入了一定的精力。不过市场对不间断扩展、canary部署和分布式追踪的需求更为强烈,而Cloud Foundry可以更好地处理这些问题。Spring Cloud Data Flow把焦点放在如何为用户创造价值上,并降低数据驱动应用的开发准入门槛。

至于说到如何将它与其他产品进行比较,我们可以先来看看Spring的观点:当一部分技术占领了相同的市场份额(比如Apache Flink),它们需要专有的运行时环境,这为构建以数据为中心的应用带来了不必要的负担。我们可以把一些产品作为我们的组件(Apache Kafka是一个很好的粘合剂,Spring Cloud Steam将消息中间件称为粘合剂),有时候可以考虑把它们集成起来,或者从已有的架构进行迁移,比如Apache Spark。

InfoQ:Cloud Foundry是一个微服务平台,而Spring Cloud Data Flow的Cloud Foundry特别版是为数据微服务而设计的。你能介绍一下一般性微服务和数据微服务在Spring平台上有什么区别吗?

Bottard:当说到微服务,开发人员会想到RESTful服务、简单的外部配置和动态服务发现,Spring Boot和Spring Cloud就提供了这些功能。不过企业应用要求的远不止这些,他们还要为开发消息驱动和任务驱动的应用找到一些方法,避免与那些古板老旧的集成产品打交道。这也就是Spring Cloud Stream和Spring Cloud Task项目存在的意义。Spring Cloud Data Flow用于编排由Spring Cloud Stream和Spring Cloud Task应用组成的数据管道。

InfoQ:Spring Cloud Data Flow的Cloud Foundry特别版可以被用于批处理应用和基于流的应用,对吗?你可以介绍一下实现和优化方面的细节吗?

Bottard:实际上是这样的,你不需要编写任何所谓的“Spring Cloud Data Flow”应用。在用它来编排Spring Cloud Steam和Spring Cloud Task应用时,你不需要编写任何代码。这是Spring Cloud Data Flow的一个主要设计原则:帮助开发人员方便地集成微服务应用,同时将应用的运行时也抽离出去。Cloud Foundry是唯一可用的运行时。

如果你需要用到流和边界内数据,那么事情就会变得很有趣。你可能需要使用面向任务的事件(比如在批处理结束后发出的通知)来驱动处理过程,Spring Cloud Data Flow为此提供了支持。

至于实现细节,基于流的应用和基于任务的应用分别与LRP和Cloud Foundry的任务概念相呼应的。LRP是长运行进程(Long Running Process)的缩写,平台负责管理这些进程,确保它们一直处于运行状态,在必要的时候需要对其进行扩展。另外需要注意的是,任务总是有开始和结束的。

InfoQ:从开发者的角度来看,Spring Cloud Data Flow可以被用于多种用途,比如DSL、仪表盘,等等。你可以对此发表你的看法吗?请告诉我们一般怎样上手?

Bottard:是的。Spring Cloud Data Flow的模型结构可以满足你的特定需求(基于流和任务),你可以决定是否需要将这些结构部署在你的运行时(比如Cloud Foundry)上,以及如何部署。这些模型结构是通过RESTful API暴露出来的,至于使用何种方式与之进行交互,比如使用仪表盘、shell或直接调用API,这个并不重要。

内建的shell是一个典型的开发工具,数据工程师可以配置自己的profile。它使用了一种unix风格的DSL,应用间的交互式通过管道来进行的,比如“http –server.port=1234 | hdfs”。

对于数据科学家和数据仓库工程师来说,他们更喜欢使用仪表盘,仪表盘提供了一个概览视图。当数据规模不断增长,流与流之间相互嵌套的时候,仪表盘会带来很多方便。

InfoQ:这个特别版是否只适用于Pivotal的Cloud Foundry?它可以被用于其他基于Cloud Foundry的平台吗?你能详细说一下这个项目的路线图吗?

Bottard:Spring Cloud Data Flow与Cloud Foundry之间的交互依赖一种部署器,这种部署器是为Cloud Foundry开源API而设计的,所以SCDF是完全可以与其他平台兼容的。在少数情况下,如果某些平台对一些特定的服务支持地不好(比如RabbitMQ),SCDF就会受到限制,你不得不选择其他消息中间件。

我们争取每三个月发布一个版本,发布的版本里包含了一些开箱即用的应用和一些核心的改进。例如,在v1.2里将带来已经组合好的任务、基于角色的安全机制,如果使用了Docker,还会带来更好的用户体验。

这里有快速入门的例子和文档

查看英文原文:Q&A with Eric Bottard Regarding Spring Cloud Data Flow for Cloud Foundry

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

原文地址:http://www.infoq.com/cn/news/2017/03/scdf-for-cloudfoundry?utm_source=news_about_java&utm_medium=link&utm_campaign=java

新年上班第一天,我的 IDE 挂了

新的一年又开始了

你年前的总结还记得么?你新年的计划做好了么?反正我都没做。
上班第一天大家都在晒着开工红包,看着一个比一个刷到的红包多,庆幸自己幸好没结婚;开心的聊着过年又被七大姑八大姨爷爷奶奶爸爸妈妈催婚,然后自己没有女朋友;说着同学朋友聚会大家都开着车去的,自己骑着一个自行车;他家孩子已经一岁多了,她又去了一次境外游,他买了房子并涨价四千块。而你呢,好像还是和去年没什么两样…

第一天我就开始写代码了

当和大家一起刷完领导和同事的开工红包后,我就马不停蹄的打开电脑准备写代码啦!但万万没想到,当我点开 Eclipse 的时候,她给我弹出一个对话框,我以为是要祝我新年快乐、鸡年大吉吧呢!谁知道…

eclipse_erroe.png

Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion' has value '1.7', but '1.8' is required.
明显感受到了来自 IDE 深深的新年祝福,新年第一天打开电脑第一件事就是修复 IDE,也是够了。不过,从对话框上的文字,可以得出是 JDK 版本冲突了,这时候我想起来,在过年前放假回家的前一天,我在这台电脑上又装了 Java 1.8 版本的 JDK 来调试其他的一个项目。CMD 打开命令行窗口,敲击 java -version 命令,果然还是这句话:

cmd_error.png

Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'

has value '1.7', but '1.8' is required.
Error: could not find java.dll
Error: Could not find Java SE Runtime Environment.

翻译成人话:出错啦!你告诉我 1.7 ,却给我 1.8 ,找不到!找不到!!

既然 IDE 挂了,那就不写代码了

怎么可能,今天还有一个小功能要上线呢。首先考虑是环境变量配置出问题,检查也没错,都是之前配置的 1.7 版本;接着检查注册表都没有什么异常,CurrentVersion也都是之前的 1.7 版本;我想不出来还是什么问题了,就去 Google 了一下,找到了 SO 上的一个问题:Registry key Error: Java version has value ‘1.8’, but ‘1.7’ is required 哈哈,和我一样,这就好办了。再接着了解到,虽然我们一直配置的环境变量中的Path\JAVA_HOME等这些东西,但当我们在命令行窗口执行java -version或打开 Eclipse 的时候,执行的并不是环境变量配置下bin目录的文件,而是C:\Windows\System32下的文件。

了解原因以后,那再根据提示就会发现:可能我的C:\Windows\System32下的文件是 1.8 版本的,不是 1.7 的。这是因为我先安装的 JDK 版本是 1.7 的,这时候C:\Windows\System32下的文件肯定只有 1.7 版本的,但当我又安装了 1.8 版本的 JDK 之后,系统可能把 C:\Windows\System32 下的 1.7 版本文件覆盖掉了!掉了!!掉了!!!那我就替换呗。

肯定有人会问:既然知道是多个不同 JDK 版本,卸载年前安装的 1.8 版本不就行了?那可不行,1.8 还有用呢,所以,需要保留 JDK 1.7 和 1.8 两个版本,现在要做的就是让两个版本共存且不再冲突

替换。两个不同版本 JDK 共存

Windows 下多个 JDK 版本共存首要条件是得仅有一个版本为主要的,其他不同的版本 JDK 调用只需要在 Tomcat 的bin/catalina.bat中配置JAVA_HOME即可了。选定自己需要的 JDK 版本后,就要把环境变量的JAVA_HOME、注册表等这些关于 JDK 版本的配置改为你需要的,我这里需要 1.7 版本,就拿 1.7 版本做演示。

1.安装 1.7 和 1.8 JDK,配置 1.7 环境变量(已安装,略)。
2.查看或修改注册表
找到HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft节点,查看Java Runtime EnvironmentJava Development kit中的CurrentVersion值是不是 1.7 ,不是就改为 1.7 。如图:

regedit.png

3.替换 java.exe/javaw.exe/javaws.exe
找到环境变量JAVA_HOME中配置路径下的bin目录中的 java.exe/javaw.exe/javaws.exe 这三个文件,用这三个替换C:\Windows\System32C:\Windows\SysWOW64中的文件。如图:

jdk_bin.png

当然,还有C:\ProgramData\Oracle\Java\javapath下的这三个文件快捷方式,也要替换一下。

4.完成
命令行窗口再次执行java -version,看到下面画面就是成功啦!Eclipse 也能打开了,我写完了代码。

cmd_success.png

总结一下

新年开工第一天竟然是以修 IDE 开始的,打死我也想不到,但我们作为开发者不就是整天在做修补工作么,修完这个 Bug ,还有下一个 Bug 在等着,我认为这才是这个职业的魅力所在,你永远不知道接下来等着你的是什么,在没来临的那一刻。

好了,年也过完了,新的年又开始了,你也许去年混的不怎么样,但你放心,你今年会依然混的不怎么样,哈哈,开个玩笑,不过在我有限的认知中,我认为我们所从事的这个职业是现阶段社会上的职业中幸福的了(因为我特么没干过其他职业)。当然,我知道你们又要跳槽了,祝大家找工作的找到好工作,不找工作的好好加班写代码,未来都是大家的。