Java,类路径,类加载 =>同一个 jar/项目的多个版本 [英] Java, Classpath, Classloading => Multiple Versions of the same jar/project

查看:35
本文介绍了Java,类路径,类加载 =>同一个 jar/项目的多个版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这对于有经验的程序员来说可能是一个愚蠢的问题.但是我有一个库(一个 http 客户端),我的项目中使用的一些其他框架/jar 需要它.但它们都需要不同的主要版本,例如:

I know this may be a silly question for experienced coders. But I have a library (an http client) that some of the other frameworks/jars used in my project require. But all of them require different major versions like:

httpclient-v1.jar => Required by cralwer.jar
httpclient-v2.jar => Required by restapi.jar
httpclient-v3.jar => required by foobar.jar

类加载器是否足够智能以某种方式将它们分开?很可能不是?类加载器如何处理这个问题,以防所有三个 jar 中的类都相同.加载了哪一个,为什么?

Is the classloader intelligent enough to seperate them somehow? Most likely not? How does the Classloader handle this, in case a Class is the same in all three jars. Which one is loaded and why?

类加载器是只提取一个 jar 还是任意混合类?例如,如果一个类是从 Version-1.jar 加载的,那么从同一个类加载器加载的所有其他类都会进入同一个 jar 吗?

Does the Classloader only pickup exactly one jar or does it mix classes arbitrarily? So for example if a class is loaded from Version-1.jar, all other classes loaded from the same classloader will all go into the same jar?

你是如何处理这个问题的?

How do you handle this problem?

有什么技巧可以以某种方式将罐子合并"到required.jar"中,以便 Classloader 将它们视为一个单元/包",或者以某种方式链接?

Is there some trick to somehow "incorporate" the jars into the "required.jar" so that the are seen as "one unit/package" by the Classloader, or somehow linked?

推荐答案

与类加载器相关的问题是一个相当复杂的问题.在任何情况下,您都应该记住一些事实:

Classloader related problems are a quite complex matter. You should in any case keep in mind some facts:

  • 应用程序中的类加载器通常不止一个.引导类加载器委托给适当的.当您实例化一个新类时,会调用更具体的类加载器.如果它没有找到对您尝试加载的类的引用,它会委托给它的父类,依此类推,直到您到达引导类加载器.如果他们都没有找到对您尝试加载的类的引用,您将收到 ClassNotFoundException.

  • Classloaders in an application are usually more than a single one. The bootstrap class loader delegates to the appropriate. When you instantiate a new class the more specific classloader is invoked. If it does not find a reference to the class you are trying to load, it delegates to its parent, and so on, until you get to the bootstrap class loader. If none of them find a reference to the class you are trying to load you get a ClassNotFoundException.

如果您有两个具有相同二进制名称的类,可以由同一个类加载器搜索,并且您想知道正在加载其中的一个,则只能检查特定类加载器尝试解析类的方式名称.

If you have two classes with the same binary name, searchable by the same classloader, and you want to know which one of them you are loading, you can only inspect the way that specific classloader tries to resolve a class name.

根据java语言规范,类二进制名称没有唯一性约束,但据我所知,每个类加载器都应该是唯一的.

According to the java language specification, there is not a uniqueness constraint for a class binary name, but as far as I can see, it should be unique for each classloader.

我可以找到一种方法来加载两个具有相同二进制名称的类,这涉及到通过覆盖默认行为的两个不同的类加载器加载它们(以及它们的所有依赖项).一个粗略的例子:

I can figure out a way to load two classes with the same binary name, and it involves to have them loaded (and all their dependencies) by two different classloaders overriding default behaviour. A rough example:

    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);

我总是发现类加载器自定义是一项棘手的任务.我宁愿建议避免多个如果可能,不兼容的依赖项.

I always found classloader customization a tricky task. I'd rather suggest to avoid multiple incompatible dependencies if possible.

这篇关于Java,类路径,类加载 =>同一个 jar/项目的多个版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆