Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1567|回复: 0
打印 上一主题 下一主题

JDK先生最近有点烦

[复制链接]

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
跳转到指定楼层
楼主
发表于 2017-6-27 19:30:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
https://mp.weixin.qq.com/s?__biz ... 2KjUZa3PMRTEnJ2v#rd
1 JDK 先生有点烦
JDK先生有点烦, 因为最近几个刺儿头程序经常找茬儿, 抱怨的还是classpath, jar 文件, package这几个JDK赖以生存、 引以为傲的基础设施。

想当年java诞生的时候, package 帮助程序员把java 类更好地组织起来, jar 文件把class文件打成压缩包,而classpath 这么多年一直兢兢业业地查找类文件,从来没出过差错。 为啥要抱怨他们呢?

前天用户系统跑过来说,他有两个package ,com.foo.db.api.和 com.foo.db.impl,  他期望大家只使用api包的UserDao, 可是总有一些不着调的程序员还去直接使用impl包,  屡禁不止啊。

用户系统带着怨气地问道:   你就没有办法让impl包也变成对外私有的?  你要是再不支持,我们都要转到OGSi 去了啊,到时候你后悔都来不及!

还有,昨天订票系统跑来说,他有两个模块,模块A 依赖json_1.1.jar,模块B依赖 json_2.0.jar , 可是这两个jar 互不兼容, 怎么把它们放到classpath上?  

JDK 觉得订票系统很变态,怎么会出现这样的代码,这不是自己折磨自己吗? 但转念一想,主要的问题还是自己的classpath, 这个所谓的classpath 是个平铺的线性结构, 而jar 之间的依赖关系应该是个有向图啊!

今天还有个家伙说他要开发物联网应用, 内存受限, 他发现JDK和JRE太大了,动辄上百M, 更要命的是其中有不少东西他们并不用, 例如界面相关的jar , 但是又没法从JDK中去除。  能不能按照需要裁剪一下JDK呢?  

如果说前面两个要求还算合理, 这个老兄的要求简直就是一场革命, JDK自己革自己的命。

2 模块化
虽然JDK已经非常成熟,但是用户的需求不能置之不理。

JDK闭关思考了半月, 终于憋出来一个大招:做粗粒度的模块化!

他把各位刺儿头招来商议。

“模块化? 还粗粒度? ” 一听到这个消息, 订单系统就跳了起来,生怕把自己给改乱了。

“是啊,模块一般指的是一个独立的单元, 它精确地声明了对外的接口和依赖。 你们想想,人类在开发中基本上都是把jar文件作为一个个的‘模块’, 每个jar文件中包含了一些package ,   但是 jar 文件本质上还是一堆.class文件的压缩而已。”

“那该怎么办?” 用户系统好奇心被激发了,它特别想做package的权限控制。

“最简单的办法,可以在jar包中添加一个声明性的文件, 这个文件定义模块名,它对外提供的接口,和依赖, 像这样:”


用户系统很激动, 这简直就是为了他量身定做的: “嗯,这很容易理解, 这个jar 的模块名叫做com.foo.db,  依赖另外一个模块 java.sql ,   这个export 就是说别人只能访问com.foo.db.api这个package下面的类, 像com.foo.db.impl 就不能访问了,对吧?”


com.foo.db.jar 文件的内容如下:
module-def.xml
com.foo.db.api.XXXX.class
com.foo.db.api.XXXX.class
......
com.foo.db.impl.XXXX.class
com.foo.db.impl.XXXX.class
......

JDK 赞许地说: “没错,  这就是所谓粗粒度的模块, 原来的java class 也可以称为一个模块,但是粒度太细了, 现在我们把一组类封装到一个jar 文件中,再加一个声明文件, 就变成了一个粗粒度模块。当然你肯定能想到,我自己也得做增强喽, 必须得能识别模块定义,并且正确的设置访问权限。”

用户系统说: “哎呀, 我其实最讨厌又臭又长的xml 了, 能不能用java 描述呢,就叫做module-info.java吧”


JDK笑了: “看来你小子想得挺深的。 我也喜欢这样清爽的表达, 只不过得把java 语法也增强了。增加像module , requries, exports这样的关键字才行。”

现在: com.foo.db.jar 文件的内容如下:
module-info.class
com.foo.db.api.XXXX
com.foo.db.api.XXXX
......
com.foo.db.impl.XXXX
com.foo.db.impl.XXXX
......

3 JDK自身的革命
开发物联网的小伙子问道: “JDK先生, 你自己是不是也要搞成模块化啊 , 这样我就可以裁剪出我使用的模块了。”

“是啊, 你们上层要是模块化了, 我肯定也得这么搞,并且我还得先搞出来, 这样你们好使用啊。这对我来说,是一场巨大的革命啊, 我得把我成千上万的类给捋一捋,形成层次分明,隔离良好的模块, 我现在才总结了一部分: java.desktop , java.xml, java.sql , java.naming, java.logging, java.scripting......”

订单系统打断说: "慢着, 难道让我在每个模块中都导入所有的JDK的基本模块吗? 这不把人给累死?"


JDK 说: “不不, 这个问题我也考虑过了,其实可以引入一个隐式的依赖嘛, 我把JDK中最重要的核心模块组织起来,形成一个java.base 模块,其他模块都隐式的依赖它就行了,  就像你的java类不用extend Object 一样, JDK会自动给你加上。”


4 迁移
用户系统说: “ 模块化的想法很不错, 解决了我的问题。 可是现有的大部分程序和jar包都没有实现模块化, 单单自己实现模块化有什么用, 你去require 谁? 你export出去的接口被谁用? ”

大家都向用户系统投来了佩服的目光, 这是个非常现实的问题。

模块化仅仅有JDK的改变还不够, 除非大家都用起来,要不然还是无法实施。

log4j 跳出说: “是啊是啊, 你们都迁移成模块了, 我一直没改,该怎么办?”

JDK说: “ log4j 你不用担心,  肯定得有一种让大家慢慢迁移到‘模块’的路径才行, 就说你吧, 还没有模块化,但是用户系统想拥抱模块化, 他要require你,该怎么办?”

“也许我可以临时的给他们起个名字,例如log4j-module , 可是我的模块怎么才能知道这个'临时模块'的存在呢?” 用户系统说

“想想classpath , 我们可以搞个modulepath, 只要加入到这个modulepath的jar文件,例如log4j.jar ,   就自动认为这是一个module (虽然他没有module-info.java声明) , 这样你就可以requrie log4j  来使用它了。”


"妙啊,这可以让大家慢慢的迁移, 我可以先把我的应用转化为模块 , 如果哪个类库还没拥抱模块化, 我就把它放到modulepath中,让它自动成为一个模块, 这样我就可以require了!"

用户系统对JDK的方法非常佩服。

“别高兴的太早”  JDK说, “一个类库一旦成为自动的模快, 那它就能访问所有的模块,因为我们不知道它到底依赖谁, 为了能让大家迁移到模块化,这也算是一个代价吧。 ”

“对了,要是只有JDK实现了模块化, 但是我们上层的应用还没有开始迁移, 能在新的JDK上运行吗? ”   订单系统担忧的问道。

“那必须得运行,不是自夸,我比较牛的一点就是向后兼容性, 早期的代码甚至不用修改就可以在最新的JRE上运行,  新的特性可不能破坏这种兼容性!”

“那该怎么搞? ”

“很简单, 我会把所有这些没有迁移的类库都放置到一个叫做unnamed模块当中, 这样概念上就统一了。 ”

“不错不错, 听起来可行” 大家纷纷表示赞成 “要不试一试?”

“心急吃不了热豆腐, 我今天召集大家来也是把主要的想法给大家分享下, 说起来简单, 里边有很多细节我得好好想想才行, 大家耐心地等待下一个版本的发行吧!”

后记: 本文介绍的就是Java9的新特性: 模块化的一些概念, 还有很多其他的细节,感兴趣的同学可以点击阅读原文去openjdk 的网站上去看看 。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-4-28 05:13 , Processed in 0.057627 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表