写点什么

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:122656
用户头像

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

关注

评论

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

Termius for Mac(SSH客户端)

Mac相关知识分享

java小知识-纳秒

京东科技开发者

如何打包CST仿真结果

思茂信息

cst cst使用教程 cst操作 cst电磁仿真 CST软件

2024年最全1000道Java中高级面试题附答案详解,最全面详细,看完稳了

架构师之道

程序员 java面试

OmniPlan Pro 4 for Mac(项目流程管理工具)

Mac相关知识分享

一分钟带你了解LED全彩显示屏

Dylan

科技 LED显示屏 全彩LED显示屏 户外LED显示屏 led显示屏厂家

浙江企业采购堡垒机品牌就选行云!

行云管家

堡垒机 等保测评 浙江

文件同步工具 Beyond Compare永久密钥分享-mac/win

Rose

InDesign for Mac(id 2022中文版)

Mac相关知识分享

TouchDesigner Pro 099 for Mac可视化原型设计的 3D 渲染工具

Mac相关知识分享

Premiere Pro 2021 for Mac(PR 2021中文版)

Mac相关知识分享

DevOps帮助数字化转型的5种方式

禅道项目管理

项目管理 程序员 DevOps 数字化转型 项目管理软件

Steinberg Cubase Pro 12 for mac(音乐创作软件)

Mac相关知识分享

Navicat Premium 16 for Mac(数据库管理软件)

Mac相关知识分享

测试右移之——监控告警中心优化与建设策略

京东科技开发者

超详细!!传统NLP算法结合大模型私有化部署简易知识问答体系工程实践

京东科技开发者

流式细胞分析 FlowJo 10 for Mac 破解安装教程

Rose

山西运城等保测评机构地址在哪里?电话多少?

行云管家

网络安全 等保 堡垒机 等保测评 运城

Minitab Express 助力,让数据统计变得轻而易举

Rose

最好用的mac效率工具 Alfred 4 for mac汉化版安装包

Rose

Xcode:mac开发工具下载

Rose

易点天下与火山引擎ByteHouse共建高性能数仓,助力智能营销效率跃升

字节跳动数据平台

Java分析工具 JProfiler mac破解版+安装教程

Rose

强大的跨平台的SSH、Telnet和SFTP客户端 Termius for mac直装激活版

Rose

macOS剪切板管理工具 Paste for Mac 中文免激活版

Rose

专访丨大模型存储新王牌,焱融科技如何引爆AI竞争力

焱融科技

人工智能 文件存储 大模型 全闪存储

教你一招,轻松玩转HyperWorks网格变形

智造软件

仿真 CAE软件 Hypermesh

GreptimeDB v0.10 重磅上线:日志场景增强、功能性能双重升级

Greptime 格睿科技

数据库 日志 版本

DICT项目支撑的破局之道,提升之路

鲸品堂

提效降本 企业号 2024年11月PK榜

人工智能的应用现状

天津汇柏科技有限公司

AI 人工智能

体操冠军吴柳芳做性感跳舞主播引热议,论退役运动员和大龄程序员的出路在哪里?

陆通

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