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

查看:117
本文介绍了Java,Classpath,Classloading =>同一个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

类加载器是否足够智能以某种方式分离它们?很可能不是吗?如果Class在所有三个jar中都相同,Classloader如何处理这个问题。哪一个加载,为什么?

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?

Classloader是否只拾取一个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?

你如何处理这个问题?

是否有某种技巧以某种方式将罐子合并到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,Classpath,Classloading =>同一个jar /项目的多个版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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