侬娜·杰尔_杰尔·地狱
侬娜·杰尔
什么是JAR地狱? (或者是classpath地狱?还是依赖地狱?)在考虑使用Maven或OSGi等现代开发工具时,哪些方面仍然有意义?
有趣的是,似乎没有对这些问题的结构化答案(即,即使第二页也没有希望的头条新闻)。 该职位应填补这一空白。
总览
我们将从构成JAR地狱的一系列问题开始,暂时忽略构建工具和组件系统。 当我们评估当前的状况时,我们将回到第二部分。
杰尔·地狱
JAR Hell是一个可爱的术语,指的是Java的类加载机制的特性所引起的问题。 其中一些相互依存。 其他人是独立的。
未表达的依赖性
JAR无法以JVM可以理解的方式来表示它依赖的其他JAR。 需要一个外部实体来识别和实现依赖关系。 开发人员必须通过阅读文档,找到正确的项目,下载JAR并将其添加到项目中来手动执行此操作。 可选的依赖项(如果开发人员要使用某些功能,则JAR可能仅需要另一个JAR)会使该过程更加复杂。
运行时直到需要访问它们之前,它都不会检测到它们。 这将导致NoClassDefFoundError崩溃正在运行的应用程序。
传递依存关系
为了使应用程序正常工作,可能只需要少数几个库。 每个反过来可能需要少量其他库,依此类推。 由于未表达的依赖关系的问题变得更加复杂,因此它变得更加费力且容易出错。
遮蔽
有时,类路径上的不同JAR包含具有相同完全限定名称的类。 可能由于不同的原因而发生这种情况,例如,当同一库有两个不同版本时,当胖JAR包含的依赖项也作为独立JAR引入时,或者当一个库被重命名并在不知不觉中两次添加到类路径中时。
由于将从类路径上的第一个JAR加载类以包含它们,因此该变体将“阴影化”所有其他类并使它们不可用。
如果变体在语义上有所不同,则可能导致从微妙到通知错误的行为到破坏破坏性错误的一切。 更糟糕的是,此问题本身表现出来的形式似乎不确定。 这取决于搜索JAR的顺序。 这在不同的环境中可能会有所不同,例如在开发人员的IDE和最终将运行代码的生产机之间。
版本冲突
当两个所需的库依赖于第三个库的不同的,不兼容的版本时,就会出现此问题。
如果两个版本都存在于类路径中,则该行为将不可预测。 首先,由于存在阴影,两个版本中都存在的类将仅从其中一个加载。 更糟糕的是,如果访问一个中存在但另一个不存在的类,则该类也将被加载。 因此,调用库的代码可能会同时找到这两个版本。
由于需要不兼容的版本,如果缺少其中一个版本,则该程序很可能无法正确运行。 同样,这可以表现为意外行为或NoClassDefFoundErrors。
复杂类加载
默认情况下,所有应用程序类均由同一类加载器加载,但开发人员可以自由添加其他类加载器。
这通常是通过组件系统和Web服务器之类的容器完成的。 理想情况下,这种隐式使用对应用程序开发人员是完全隐藏的,但是,众所周知, 所有抽象都是泄漏的 。 在某些情况下,开发人员可能会明确添加类加载器以实现功能,例如,允许其用户通过加载新类来扩展应用程序,或者能够使用具有相同依赖关系的冲突版本。
不管多个类加载器如何进入画面,它们都可以Swift导致显示出意料之外且难以理解的行为的复杂机制。
类路径地狱和依赖地狱
Classpath地狱和JAR地狱本质上是同一件事,尽管后者似乎更加关注由复杂的类加载器层次结构引起的问题。 这两个术语都特定于Java和JVM。
另一方面, 依赖地狱是一个使用更广泛的术语。 它描述了软件包及其依赖项的一般问题,适用于操作系统以及各个开发生态系统。 考虑到它的通用性,它并不涵盖特定于单个系统的问题。
从上面的列表中,它包括可传递的和可能未表达的依赖关系以及版本冲突。 类的加载和屏蔽是Java特定的机制,依赖地狱将不会涵盖这些机制。
发布时间由惠康图书馆在CC-BY 4.0
事态
制作工具
在问题列表中,我们看到了构建工具如何帮助解决其中的一些问题。 它们擅长使依赖关系显式化,以便可以沿着传递依赖关系树的众多边缘查找每个所需的JAR。 这在很大程度上解决了未表达和传递依赖的问题。
但是Maven等。 对阴影不做任何事情。 虽然它们通常会努力减少重复的类, 但不能阻止它们 。 除了指出版本冲突之外,构建工具也无济于事。 而且由于类加载是运行时构造,因此它们也不会涉及。
组件系统
我从未使用过OSGi或Wildfly之类的组件系统,因此无法证明它们的工作情况。 根据他们的说法,他们似乎能够解决大多数JAR地狱问题。
但是,这带来了额外的复杂性,并且经常要求开发人员更深入地研究类加载器机制。 具有讽刺意味的是,上面的列表中也有一点。
但是,无论组件系统是否确实在很大程度上缓解了JAR地狱的痛苦,我的印象是,绝大多数项目都没有使用它们。 在这种假设下,绝大多数人仍然遭受与类路径有关的问题。
这在哪里离开我们?
由于它们未被广泛使用,因此组件系统不会影响大局。 但是,构建工具的普遍存在极大地改变了JAR地狱不同圈子的严重性。
我参与或听说过的任何构建工具都不支持的项目都花了相当长的时间来处理来自未表达或可传递依赖的问题。 阴影有时会抬起丑陋的头,需要花费不同的时间来解决-但最终总是如此。
版本冲突是JAR地狱中最棘手的问题。
但是每个项目迟早都要依靠相互冲突的版本进行战斗,并且必须做出一些艰难的决定才能解决这些问题。 通常,必须推迟某些所需的更新,因为这将强制执行当前无法执行的其他更新。
我敢说,对于大多数大小合适的应用程序,服务和库,版本冲突是何时以及如何更新依赖项的主要决定因素之一。 我觉得这是无法忍受的。
对于非平凡的类加载器层次结构,我经验不足,无法评估它们是多少个重复出现的问题。 但是考虑到我到目前为止从事的所有项目都不要求它们,所以我敢说它们并不常见。 在网络上搜索使用它们的原因通常会发现我们已经讨论的内容:依赖关系导致版本冲突。
因此,根据我的经验,我会说版本冲突是JAR地狱中最棘手的问题。
反射
我们已经讨论了JAR地狱的构成要素:
- 未表达的依赖性
- 传递依赖
- 遮蔽
- 版本冲突
- 复杂类加载
根据为游戏带来的构建工具和组件系统以及它们的使用范围,我们得出结论,很大程度上解决了未表达的和可传递的依赖关系,这至少掩盖了减轻的负担和不常见的复杂类加载。
这使版本冲突成为JAR地狱中最有问题的方面,影响了大多数项目中的日常更新决策。
翻译自: https://www.javacodegeeks.com/2015/10/jar-hell.html
侬娜·杰尔
侬娜·杰尔_杰尔·地狱相关推荐
- aws 首尔_首尔自行车:我如何重新设计首尔市的公共自行车系统
aws 首尔 by Martin Totev 马丁·托特夫(Martin Totev) 首尔自行车:我如何重新设计首尔市的公共自行车系统 (Seoul Bike: How I redesigned S ...
- 服务器e5系列和e5v4系列,至强E5 v4服务器介绍:戴尔、杰和
至强E5 v4服务器介绍:戴尔.杰和 至强E5 v4服务器介绍:戴尔.杰和 R730是戴尔2U旗舰机型,采用Intel(R)C612芯片组,能够支持Intel最新发布的Xeon E5-2600 v4处 ...
- 2.4G无线麦克风领夹麦一拖二_全双工_杰理JL6976M单芯片方案
目录 一.简介 二.详细说明 2.1 目前杰理的无线麦方案 2.2 主控芯片脚位图 2.3 系统框架图 2.4 方案参数低延时无线麦功能支持以下三种组合配置:(1)一发一收a) 无线麦(单收发) ...
- 转贴:关于克尔凯郭尔
关于克尔凯郭尔 2005-9-3 23:34:00 关于克尔凯郭尔 克尔凯郭尔,丹麦人.与安徒生同时代.这是在我身边极少能够看到的一种人,但却令我感到亲切,或许因为在他身上看到了自己心目中斑斓的影子. ...
- 黑苹果11.0big sur驱动因特尔英特尔intel82599万兆网卡教程
黑苹果11.0big sur驱动因特尔英特尔intel82599万兆网卡教程 第一步 下载得到这些东西(github上全都有) 第二步 复制文件到kext文件夹 我的是这个 第三步 修改config. ...
- 柏拉图,克尔凯郭尔,席勒,诗歌美学
在<理想国>中,柏拉图记叙了苏格拉底对于诗的看法.我们可以看出,苏格拉底对于把诗歌摆放在了一个较低的地位上,尤其是在和哲学进行比较时.在<理想国>的第三卷中,苏格拉底指责诗歌中 ...
- 戴尔外星人戴尔外星人Alienware m15R7原厂预装win11中文家庭版系统带F12 Support Assist OS Recovery一键还原恢复功能
戴尔外星人戴尔外星人Alienware m15R7原厂预装win11中文家庭版系统带F12 Support Assist OS Recovery一键还原恢复功能 恢复各机型预装系统,带所有dell主题 ...
- NBA名人堂之-萨姆·琼斯|皮特·马拉维奇|埃尔·门罗|比尔·沙尔曼|杰里·韦斯特
萨姆·琼斯 英文名:Sam Jones 出生:1933年6月24日 身高:1.93米 NBA生涯:1957-1969年 司职:后卫 主要荣誉: ① 10次夺得NBA总冠军: ② 5次入选NBA全明星阵 ...
- 皮尔松相关分析_皮尔西斯符号学与生物学认知
皮尔松相关分析 There is a natural evolution from the ideas that deep learning has empirical revealed to a t ...
最新文章
- 【技术贴】虚拟机 VMware win7 win8网卡驱动下载 解决虚拟机不识别网卡没有本地连接...
- linux c 多态原理,看了所谓的面向对象中靠继承多态实现的所谓重用 哥笑了
- windows2016服务器优化,Windows Server 2012 服务器优化图文方法
- Venn网络展示富集分析结果
- ceisum 加载geojson,webgl 加载geojson数据没有贴地
- 任正非:鸿蒙最快1年可媲美iOS;首例Apple Card用户遭盗刷;Firefox 69.0.3 发布 | 极客头条...
- db2函数写法简单说明
- Configuration Opennebula3.8 4.x Virtual Machines Contextualizing
- EPS学习笔记2----------常用地物绘制基础
- Hyper-V虚拟机和虚拟化服务器区别
- 新媒体时代,内容为王已经走偏
- OOAD 3 迭代、进化和敏捷(Iterative,Evolutionary,and Agile)
- 照片变漫画的方法有哪些?推荐两个方法给你
- 【图形学】【笔记】凹多边形
- 使用HTML5和CSS制作抖音首页
- More Effective C++ 阅读笔记 解释清晰
- 克鲁斯卡尔算法(Kruskal)求最小生成树(MST)过程详解
- 小飞升值记——(15)
- VESTA的扩胞功能——超晶胞的建立
- 大学物理 复习指导、公式推导精简过程、结论归纳 第八章 热力学基础
热门文章
- 二分算法:平均值(洛谷 UVA1451)
- P7405-[JOI 2021 Final]雪玉【二分】
- U94222-循环往复【tarjan,DAGdp】
- 欢乐纪中某B组赛【2019.1.29】
- 洛谷UVA1328,POJ1961-Period【KMP,字符串】
- [集训队作业2018] 万圣节的积木(李超线段树)
- codeforces 884E Binary Matrix 并查集,滚动数组
- Sentinel(二十六)之Sentinel Dashboard中修改规则同步到Nacos
- 面试了 N 个候选人后,我总结出这份 Java 面试准备技巧
- Maven的pom.xml文件详解------Environment Settings