我知道对于经验丰富的程序员来说这可能是一个愚蠢的问题。但我有一个库(一个 http 客户端),我的项目中使用的一些其他框架/jar 需要它。但它们都需要不同的主要版本,例如:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
类加载器是否足够智能以某种方式将它们分开?很可能不是?如果所有三个 jar 中的类都相同,类加载器如何处理这个问题。加载哪一个以及为什么?
类加载器是否只拾取一个 jar,还是任意混合类?因此,例如,如果从 Version-1.jar 加载一个类,那么从同一个类加载器加载的所有其他类都会进入同一个 jar 吗?
你如何处理这个问题?
是否有一些技巧可以以某种方式将罐子“合并”到“required.jar”中,以便被视为“一个单元/包”Classloader
,或以某种方式联系在一起?
与类加载器相关的问题是一个相当复杂的问题。
无论如何,您应该记住一些事实:
应用程序中的类加载器通常不止一个。引导类加载器委托给适当的。当您实例化一个新类时,会调用更具体的类加载器。如果它找不到对您尝试加载的类的引用,它将委托给其父级,依此类推,直到您到达引导类加载器。如果它们都找不到对您尝试加载的类的引用,您将收到 ClassNotFoundException。
如果您有两个具有相同二进制名称的类,可由同一个类加载器搜索,并且您想知道正在加载其中哪一个,则只能检查特定类加载器尝试解析类名的方式。
根据java语言规范,类二进制名称没有唯一性约束,但据我所知,它对于每个类加载器应该是唯一的。
我可以找到一种方法来加载具有相同二进制名称的两个类,并且涉及到通过两个不同的类加载器覆盖默认行为来加载它们(及其所有依赖项)。
一个粗略的例子:
ClassLoader loaderA = new MyClassLoader(libPathOne);
ClassLoader loaderB = new MyClassLoader(libPathTwo);
Object1 obj1 = loaderA.loadClass("first.class.binary.name", true)
Object2 obj2 = loaderB.loadClass("second.class.binary.name", true);
我总是发现类加载器定制是一项棘手的任务。我宁愿建议避免多次
如果可能的话,不兼容的依赖关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)