我知道对于有经验的程序员来说,这可能是一个愚蠢的问题。但是我有一个库( http客户端),这是我的项目中使用的一些其他框架/jars所需要的。但它们都需要不同的主要版本,例如:
httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar
类加载器是否足够智能,能够以某种方式将它们分开?很可能不是吗?如果一个类在所有三个jars中都是相同的,Classloader如何处理这个问题。哪一个是加载的?为什么?
Classloader是只拾取一个jar,还是随意混合类?例如,如果一个类是从Version-1.jar加载的,那么从相同的类加载器加载的所有其他类都将进入同一个jar?
你如何处理这个问题?
是否有什么技巧可以将jars“合并”到"required.jar“中,以便Classloader
将它们视为”一个单元/包“,或者以某种方式链接起来?
发布于 2011-05-24 16:15:17
每个类加载只挑选一个类。通常是第一个找到的。
OSGi旨在解决同一jar的多个版本的问题。Equinox和Apache Felix是OSGi的常见开源实现。
发布于 2011-05-24 10:42:14
Classloader将首先从恰好位于类路径中的jar装入类。通常,不兼容的库版本在包中会有所不同,但在不太可能的情况下,它们真的不兼容,不能用一次性的jarjar替换。
发布于 2011-05-24 11:13:44
类加载器按需加载类。这意味着您的应用程序和相关库首先需要的类将在其他类之前加载;加载依赖类的请求通常在依赖类的加载和链接过程中发出。
您可能会遇到LinkageError
,说明遇到了重复的类定义,因为类加载器通常不会尝试确定应该首先加载哪个类(如果加载器的类路径中存在两个或更多同名的类)。有时,类加载器会加载类路径中出现的第一个类,并忽略重复的类,但这取决于加载器的实现。
解决此类错误的推荐做法是为具有冲突依赖关系的每组库使用单独的类加载器。这样,如果类加载器试图从库中加载类,依赖类将由同一类加载器加载,而该类加载器无法访问其他库和依赖项。
https://stackoverflow.com/questions/6105124
复制相似问题