dot2谜团png

面对一个好老问题

我在应用程序服务器上遇到一些类加载问题。 这些库被定义为Maven依赖项,因此被打包到WAR和EAR文件中。 不幸的是,其中一些还安装在应用程序服务器中,但版本不同。 启动应用程序时,我们遇到了与这些类型的问题相关的各种异常。 如果您想深入了解,那么有一篇不错的IBM文章介绍了这些异常。

即使我们知道该错误是由类路径上的某些双重定义的库引起的,但仍花了两个多小时来调查我们真正需要的版本以及要删除的JAR。

同一周在水罐上偶然发生相同的话题

几天后,我们参加了“您真的得到了Classloaders吗? 苏黎世Java用户协会会议。 Simon Maple对类加载器进行了非常出色的介绍,并从一开始就介绍了非常深入的细节。 对于许多人来说,这是一次令人大开眼界的会议。 我还必须注意,Simon工作零周转,他为JRebel进行宣传。 在这种情况下,辅导课程通常偏向于实际产品,即辅导员的面包。 在这种情况下,我认为西蒙绝对是绅士和道德主义者,保持适当的平衡。

创建一个工具,解决神秘问题

只是为了创造另一个

一周后,我花了一些时间来学习程序,而现在我已经有几个星期没有时间了,所以我决定创建一个小工具,列出所有在类路径上的类和JAR文件,以便可以更轻松地进行调查。重复。 我试图依靠这样的事实,即类加载器通常是URLClassLoader实例,因此可以调用getURLs()方法来获取所有目录名称和JAR文件。

在这种情况下,单元测试可能非常棘手,因为该功能与类加载器的行为密切相关。 务实的是,我决定只做一些从JUnit开始的手动测试,只要代码是实验性的即可。 首先,我想看看这个概念是否值得进一步发展。 我打算执行测试,并查看报告没有重复类的日志语句,然后执行相同的运行,但是第二次向类路径添加一些冗余依赖项。 我使用的是JUnit 4.10,在这种情况下,该版本很重要。

我从命令行执行了单元测试,发现没有重复的类,我感到很高兴。 之后,我从Eclipse执行了相同的测试,并且感到惊讶:我冗余定义了21个类!

12:41:51.670 DEBUG c.j.c.ClassCollector - There are 21 redundantly defined classes.
12:41:51.670 DEBUG c.j.c.ClassCollector - Class org/hamcrest/internal/SelfDescribingValue.class is defined 2 times:
12:41:51.671 DEBUG c.j.c.ClassCollector -   sun.misc.Launcher$AppClassLoader@7ea987ac:file:/Users/verhasp/.m2/repository/junit/junit/4.10/junit-4.10.jar
12:41:51.671 DEBUG c.j.c.ClassCollector -   sun.misc.Launcher$AppClassLoader@7ea987ac:file:/Users/verhasp/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar
...

仔细研究一下,我可以很容易地发现JUnit 4.10具有额外的依赖关系,如maven所示

$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building clalotils 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ clalotils ---
[INFO] com.verhas:clalotils:jar:1.0.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.10:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.1:test
[INFO] +- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] \- ch.qos.logback:logback-classic:jar:1.1.2:compile
[INFO]    \- ch.qos.logback:logback-core:jar:1.1.2:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.642s
[INFO] Finished at: Wed Sep 03 12:44:18 CEST 2014
[INFO] Final Memory: 13M/220M
[INFO] ------------------------------------------------------------------------

这实际上在4.11中已修复,因此如果我将依赖关系更改为JUnit 4.11,则不会遇到此问题。 好。 一半的谜团解决了。 但是,为什么maven命令行执行未报告双重定义的类?

扩展日志记录,越来越多的日志记录我可以发现一条线:

12:46:19.433 DEBUG c.j.c.ClassCollector - Loading from the jar file /Users/verhasp/github/clalotils/target/surefire/surefirebooter235846110768631567.jar

这个文件里有什么? 让我们解压缩它:

$ ls -l /Users/verhasp/github/clalotils/target/surefire/surefirebooter235846110768631567.jar
ls: /Users/verhasp/github/clalotils/target/surefire/surefirebooter235846110768631567.jar: No such file or directory

该文件不会退出! 看来maven创建了这个JAR文件,然后在测试执行完成后将其删除。 再次谷歌搜索,我找到了解决方案。

Java从类路径加载类。 可以在命令行上定义类路径,但是应用程序类加载器还有其他来源可以从中获取文件。 一个这样的源是JAR的清单文件。 JAR文件的清单文件可以定义执行JAR文件中的类所需的其他JAR文件。 Maven创建一个JAR文件,除了清单文件定义清单中列出了JAR和列出类路径的目录外,该文件不包含其他内容。 这些JAR和目录不是由getURLs()方法返回的,因此我的小工具(第一个版本)没有找到重复的对象。

出于演示目的,我足够快地在运行mvn test命令时制作了该文件的副本,并获得以下输出:

$ unzip /Users/verhasp/github/clalotils/target/surefire/surefirebooter5550254534465369201\ copy.jar
Archive:  /Users/verhasp/github/clalotils/target/surefire/surefirebooter5550254534465369201 copy.jarinflating: META-INF/MANIFEST.MF
$ cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
Class-Path: file:/Users/verhasp/.m2/repository/org/apache/maven/surefire/surefire-booter/2.8/surefire-booter-2.8.jar file:/Users/verhasp/.m2/repository/org/apache/maven/surefire/surefire-api/2.8/surefire-api-2.8.jar file:/Users/verhasp/github/clalotils/target/test-classes/ file:/Users/verhasp/github/clalotils/target/classes/ file:/Users/verhasp/.m2/repository/junit/junit/4.10/junit-4.10.jar file:/Users/verhasp/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar file:/Users/verhasp/.m2/repository/org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar file:/Users/verhasp/.m2/repository/ch/qos/logback/logback-classic/1.1.2/logback-classic-1.1.2.jar file:/Users/verhasp/.m2/repository/ch/qos/logback/logback-core/1.1.2/logback-core-1.1.2.jar
Main-Class: org.apache.maven.surefire.booter.ForkedBooter$

实际上,除了定义类路径的清单文件外,别无其他。 但是为什么Maven会这样做呢? 索纳型人,我个人也认识一些聪明的人。 他们不会白白做任何事情。 创建临时JAR文件以启动测试的原因是, 在某些类路径长度可能超过的操作系统上 ,命令行的长度受到限制 。 即使Java(自Java 6起)本身可以解析类路径中的通配符 ,也不是maven的选择。 JAR文件位于Maven存储库中的不同目录中,每个目录都有长名称。 通配符解析不是递归的,这有充分的理由,即使是通配符解析,您也不希望将所有本地存储都放在类路径中。

结论

  • 不要使用JUnit 4.10! 使用旧的或较新的东西,或为意外做好准备。
  • 了解什么是类加载器以及它如何工作,做什么。
  • 使用对命令行长度的最大大小有极大限制的操作系统。
    或只是忍受限制。

还有吗 你的想法?

翻译自: https://www.javacodegeeks.com/2014/09/a-classloading-mystery-solved.html

dot2谜团png

dot2谜团png_一个类加载的谜团解决了相关推荐

  1. 一个类加载的谜团解决了

    面对一个好老问题 我在应用程序服务器上遇到一些类加载问题. 这些库被定义为Maven依赖项,因此被打包到WAR和EAR文件中. 不幸的是,其中一些也已安装到应用程序服务器中,但版本不同. 启动应用程序 ...

  2. 熬了一个通宵,终于解决了所有的事情,下线,睡觉

    熬了一个通宵,终于解决了所有的事情,下线,睡觉 现在时间2009年12月30日4:56:55. 完成移动邮件初步内容.打包上传,更新到SVN 完成网络工程分享网站(http://www.the520. ...

  3. 码农节快乐|一个系统,高效解决复杂事件采集-计算-实时触达

    PartI: 1024 今天是1024,一个特别的数字,比如某网站内容的解压密码通常都是1024,想求一个种子留言也是1024.1024是属于广大程序猿(又称码农)的节日,在这样一个节日里,各种&qu ...

  4. 计算机消失了一个磁盘,win7系统重装后莫名奇妙消失一个分区磁盘的解决方法...

    很多小伙伴都遇到过win7系统重装后莫名奇妙消失一个分区磁盘的困惑吧,一些朋友看过网上零散的win7系统重装后莫名奇妙消失一个分区磁盘的处理方法,并没有完完全全明白win7系统重装后莫名奇妙消失一个分 ...

  5. java+oracle数据库锁,数据库学习之Oracle数据库\记录被另一个用户锁住\解决方法...

    1.先来看看为什么会出锁住: 数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数 ...

  6. 【引用】IP地址已经分配给另一个适配器问题的解决方法

    本文引用自天若有情<IP地址已经分配给另一个适配器问题的解决方法> 局域网中有的电脑网卡有问题,拔出来后插在另外一个插槽,重新安装驱动程序,重新分配固定IP时候,提示:您为这个网络适配器输 ...

  7. 计算机上的框英文,电脑打开steam平台弹出一个英文框的解决方法

    现在玩绝地求生的人越来越多了,想要玩吃鸡游戏,首先要启动Steam平台.很多朋友下载Steam之后总提示无法在非英文文件夹运行,造成游戏无法继续运行,这要怎么解决?针对此疑问,小编来和大家说说一招解决 ...

  8. PhpMyAdmin 配置文件现在需要一个短语密码的解决方法

    PhpMyAdmin 配置文件现在需要一个短语密码的解决方法 参考文章: (1)PhpMyAdmin 配置文件现在需要一个短语密码的解决方法 (2)https://www.cnblogs.com/yd ...

  9. vue 随机显示数组的其中一个_两个显示器组建双屏其中一个屏幕出现重影解决方法...

    两个显示器组建双屏其中一个屏幕出现重影,通过测试,将两台显示器的缩放布局中的缩放比例调至一致并没有任何效果,那么还有什么原因可以导致这个问题?下面分享一下两个显示器组建双屏其中一个屏幕出现重影解决方法 ...

最新文章

  1. include/filter.inc.php,dedecms /include/filter.inc.php 变量覆盖注入漏洞及解决方案
  2. mfc中picture control的用法_可能是最被误用的 HTTP 响应头之一 Cache-Control: must-revalidate
  3. 短信网址价值不大不应被热炒
  4. Android 开机自动运行和添加删除桌面快捷方式
  5. 修改注册表给windows防火墙添加例外 ------------ 转
  6. 不积跬步无以至千里[转]
  7. python测试testsuite使用命令行参数的问题
  8. 全球44家机构,55位大佬,历时两年,打造最强NLG评测基准!
  9. 软件工程中英对照术语表
  10. lae界面开发工具入门之介绍五--秘籍篇-杂项
  11. 【 unity3d 】Transform.LookAt()方法
  12. 当幸福来敲门,不是影评
  13. 思成五笔的通俗易懂讲解
  14. Unity升级2018与Google Android64位支持
  15. 计算机文档里的圆圈,请问在WORD文档里怎样插入数字上的圆点?
  16. 高频前端面试问题及答案整理
  17. 如何使用Echarts设计专业的K线图
  18. 人机交互-1-人机交互概述
  19. freebsd jail nginx php-fpm mysql weberp安装
  20. HTML经过按钮时按钮变大,html – 调整按钮大小

热门文章

  1. jzoj3189-解密【字符串hash】
  2. P5022-旅行【基环树,dfs】
  3. 【c++算法刷题笔记】——洛谷2
  4. 纪中B组模拟赛总结(2020.2.3)
  5. CERC2017 Gambling Guide,最短路变形,期望dp
  6. hdu4609 3idiots 三角形计数 FFT
  7. 3、oracle数据库的语法基础
  8. 6、java中的排序算法
  9. JavaFX其他事件
  10. 从理论知识到落地能力,你欠缺了什么?