我知道这对于有经验的程序员来说可能是个愚蠢的问题。但是我有一个库(一个 http 客户端),我的项目中使用的其他一些框架/jar 需要它。但是它们都需要不同的主要版本,例如:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
类加载器是否足够智能以某种方式将它们分开?很可能不是?类加载器如何处理这个,以防所有三个罐子中的类相同。加载了哪一个,为什么?
Classloader 只拾取一个 jar 还是任意混合类?因此,例如,如果一个类是从 Version-1.jar 加载的,那么从同一个类加载器加载的所有其他类都将全部放入同一个 jar 中吗?
你如何处理这个问题?
是否有一些技巧以某种方式将罐子“合并”到“required.jar”中,以便它们被 Classloader
视为“一个单元/包”,或以某种方式链接?
原文由 jens 发布,翻译遵循 CC BY-SA 4.0 许可协议
与类加载器相关的问题是一个相当复杂的问题。在任何情况下,您都应该记住一些事实:
应用程序中的类加载器通常不止一个。引导类加载器委托给适当的。当您实例化一个新类时,将调用更具体的类加载器。如果它没有找到对您尝试加载的类的引用,它将委托给它的父类,依此类推,直到您到达引导类加载器。如果它们都找不到对您尝试加载的类的引用,您将得到一个 ClassNotFoundException。
如果你有两个具有相同二进制名称的类,可由同一个类加载器搜索,并且你想知道你正在加载其中的哪一个,你只能检查特定类加载器尝试解析类名的方式。
根据 java 语言规范,类二进制名称没有唯一性约束,但据我所知,它对于每个类加载器都应该是唯一的。
我可以想出一种方法来加载两个具有相同二进制名称的类,它涉及通过两个不同的类加载器加载它们(以及它们的所有依赖项)来覆盖默认行为。一个粗略的例子:
我总是发现类加载器定制是一项棘手的任务。我宁愿建议尽可能避免多个不兼容的依赖项。