写点什么

Jigsaw 项目会解决 Java 的 JAR 地狱问题么?

  • 2015-12-31
  • 本文字数:2011 字

    阅读完需:约 7 分钟

Nicolai Parlog 是一位热情的软件工程师,数字版权与开源软件的狂热拥护者;他对 AssertJ、ControlsFX、FindBugs 及 Property Alliance 等项目都做出过重要的贡献。近日,Parlog 就 Jigsaw 项目撰写了一篇文章,谈到了 Jigsaw 项目的一些不足以及改进之处。Jigsaw 项目有着雄心勃勃的宏伟目标,其目标之一就是彻底摆脱极易出错且问题多多的类路径机制中的 JAR 地狱问题。不过,虽然该项目的其他目标会在不久的将来得以实现,但解决 JAR 地狱问题这一目标似乎并不是那么容易的。

为了更好地理解我们接下来要讨论的内容,首先来看一下 JAR 地狱问题,接下来介绍 Jigsaw 项目将会解决问题的哪些方面,以及为什么说 Jigsaw 所尝试解决的问题并不会对整个问题域产生本质的影响。最后,我们来看一下官方对于这个话题的立场,并给出如何防止出现模块地狱的提案。

JAR 地狱问题

JAR 地狱存在着如下循环问题:

  • 表述不清以及传递性依赖
  • 遮蔽
  • 版本冲突
  • 复杂的类加载

根据构建工具与组件系统(JDK 开发者称之为容器)为我们所带来的诸多功能与特性,我们可以认为表述不清以及传递性依赖问题已经在很大程度上得到了解决,遮蔽问题至少得到了缓解,而复杂的类加载也不再是老生常谈的问题了。这样,版本冲突就成为 JAR 地狱中最为严重的一个问题了,它影响到了很多很多项目每天的更新决策。

Jigsaw 将会带来哪些改变?

我之前曾就 Jigsaw 项目会为 Java 9 带来哪些新特性专门写过文章进行过介绍,不过这里将从不同的视角进行阐述。首先,它会受到当前的早期访问构建版的影响;其次,我们这里只从与 JAR/ 模块地狱相关的角度进行介绍。

Jigsaw 为 Java 带来的核心概念就是模块化。简而言之,模块就像 JAR 一样,同时带有一些附加信息与特性。这些信息包含了模块的名字以及模块所依赖的其他模块的名字。

依赖

当编译器与 JVM 在处理模块时,他们会解析这些信息。在编译或启动时,他们会通过模块路径传递性解析所有依赖。总体来说,这类似于类路径扫描,不过现在寻找的是整个模块而非单个类,对于 JVM 来说,这是在启动期而非运行期进行的。如果在模块路径上无法找到所有依赖,那么解析模块的传递性依赖就会失败。这显然可以解决表述不清,以及无休止的传递性依赖的问题。我认为这是个很棒的做法,Java 语言现在正式知道关于依赖的信息了,所有工具(编译器与 JVM 等)都能理解这一点并正常使用!不过,我认为这并不会对开发者每天的工作产生多少积极的影响,因为现在很多既有的基础设施都已经解决这个问题了,比如说构建工具等。

遮蔽

Jigsaw 消除了遮蔽的问题。模块系统可以确保每个依赖都会被另一个模块所实现,每个模块都会读取至多一个模块,定义了同名包的模块之间并不会相互干扰。更准确地说,模块系统在遇到模糊不清的情况时就会终止并报错,比如说两个模块将相同的包导出到相同模块中。

版本冲突

我们认为第三方库的版本冲突是 JAR 地狱最为难以解决的问题。最直接的解决方案就是一个模块系统能够加载同一个模块的不同版本。这需要确保这些版本之间不存在互相交互的情况。问题在于:在单个配置中,没必要支持一个模块的多个版本。实际上,当前的构建既不会创建,也无法理解模块版本信息。曾有人使用了一些变通办法。最丑陋,同时也是最可行的办法就是重命名出现冲突的构件,这样他们就不再是相同模块的两个不同版本了,而是两个完全不同的模块。不过,这种做法最后证明也是行不通的。显然,确保“定义了同名包的模块之间不会相互干扰”是在两个模块导出相同包时拒绝任何启动配置来实现的。即便没有模块读取他们亦如此!

复杂的类加载

模块与类加载器之间如何交互以及如何改变类加载的复杂性是个很棘手的问题。实际上,模块系统对模块与类加载器之间的关系并没有做多少限制。类加载器可以从一个模块或是多个模块来加载类型,只要模块之间不存在相互干扰的情况,并且每个模块中的类型只由一个加载器加载即可。因此,类加载器与模块之间是一对多的关系。

模块地狱?

既然依赖与遮蔽问题已经得到了解决,并且类加载问题也得到了改进,那我为何还要讨论模块地狱呢?就是因为版本冲突么?没错!如果 Jigsaw 想要解决 JAR 地狱问题,它就需要特别注意版本冲突问题。否则,很多项目并不会出现什么起色。他们依然要面对版本冲突问题,并且会陷入到自定义类加载器的梦魇中。

提案

我的提案是让开发者与构建工具能够传递一些额外的信息,这些信息能够解决一些含糊不清的问题。传递这种信息的两种常见方式是命令行与配置文件。如果使用命令行参数,那么每次启动时都需要输入一次。根据信息的多少以及项目的规模,这种做法可能会变得非常乏味。可以通过构建工具来创建配置文件,然后再通过命令行指定配置文件。这看起来是个不错的解决方案。目前,初始模块与所有的传递性依赖都是通过单个配置来解析的,这形成了单独的一个层次。不过,我们可以在运行期将相同模块的多个版本加载到不同层次中,这正是组件系统要做的事情。总的来说,我的建议就是通过多个层次来显式指定配置。

2015-12-31 02:122643
用户头像

发布了 88 篇内容, 共 263.2 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

唯品会商品详情数据接口(VIP.item_get)丨唯品会平台API接口教程

tbapi

唯品会商品详情数据接口 唯品会 唯品会商品数据采集 唯品会API

一键聚合,视频无忧!PullTube让您的视频观看体验再升级

理理

Steinberg SpectraLayers Pro for mac(Mac音频频谱编辑器) v11.0.10

Mac相关知识分享

音频编辑器

混音师的秘密武器,Steinberg Nuendo,让每一个音符都精准到位

理理

DBeaver Ultimate Edition(数据库管理工具)

理理

搜款网商品详情数据接口(VVIC.item_get)丨搜款网平台API接口教程

tbapi

搜款网 搜款网API 搜款网商品详情数据接口 VVIC数据采集

IntelliJ IDEA 2023 for Mac(最好用的Java开发工具) v2023.3.2汉化版

Mac相关知识分享

开发工具

妙笔生花,创意无限!WonderPen妙笔引领写作新风尚

理理

SpectraLayers Pro for mac,解锁音频编辑的新潜能

理理

第19届 OpenFOAM国际研讨会顺利举行

Geek_2d6073

天猫商品详情数据接口(tmall.item_get)丨天猫平台API数据接口

tbapi

天猫商品详情接口 天猫API 天猫商品数据采集 天猫商品详情数据采集

借助办公小浣熊,完成双十一当天各品牌口红销量的数据分析

言程序

数据分析预测 智能办公 办公小浣熊 商汤科技 代码小浣熊

Termius for Mac(多协议远程管理软件) 8.4.0版

Mac相关知识分享

远程 mac软件下载

PullTube for Mac(在线视频下载器) v1.8.5.35中文版

Mac相关知识分享

开发软件

Final Cut Pro X for Mac(fcpx视频剪辑) v10.7.1简体中文版

Mac相关知识分享

视频编辑软件

最新版Ableton Live 12 Suite 中文安装包 live12永久许可证分享

理理

抖音商品详情数据接口(Dy.item_get)丨抖音平台API数据接口指南

tbapi

抖音商品详情数据接口 抖音API 抖音商品详情数据采集

软件测试学习笔记丨JUnit5动态测试的并行运行与分布式运行

测试人

软件测试

前端开发 如何高效落地 Design Token

秃头小帅oi

Downie 4 for Mac(视频下载工具)兼容14系统 v4.7.2中文版

Mac相关知识分享

微店商品详情数据接口(Micro.item_get)丨微店平台API数据接口指南

tbapi

微店商品详情数据接口 微店API接口 微店

绿意盎然,从规划开始!Garden Planner,您的私人花园设计大师

理理

小程序开发者福利分享:既能生成小程序又能生成APP

Geek_2305a8

Sketch for mac(专业矢量绘图设计软件)

Mac相关知识分享

Photoshop 2021 for mac(PS 2021) v22.5.1版

Mac相关知识分享

Jigsaw项目会解决Java的JAR地狱问题么?_Java_张龙_InfoQ精选文章