Java ClassLoader和依赖项解析

时间:2010-12-17 18:02:52

标签: java architecture classloader

有人可以澄清一下,ClassLoader的作用不仅仅是加载一个单独的类,还加载它的依赖关系?如果是这样,整个过程到底需要什么?如果可能的话,我正在寻找实施细节。

例如,在某些时候,必须从某个地方(网络或文件系统位置)读取字节,并且必须根据类规范名称和文件系统位置来计算文件系统位置。预知JVM可用的类路径 - 单个ClassLoader如何尝试在可能多个类路径上定位文件?它从哪里获取此信息?此外,在什么时候验证了类文件字节并检查其依赖性是否可用?

尽可能多的细节将被赞赏:)

2 个答案:

答案 0 :(得分:7)

ClassLoading是一个非常复杂的主题。 ClassLoader和Java安全模型密不可分。本质上,JVM按需加载类。当存在类加载器的层次结构时,JVM会尝试尽可能地解析链中的类。简而言之,如果类在“boot”类加载器和应用程序定义的类加载器中定义,它将始终使用引导类加载器中的版本。

在类加载器(例如URLClassLoader)中,搜索顺序是您告诉它的顺序。基本上,你告诉它有类的URL数组将从第一个条目到最后一个条目进行搜索。

当您定义的类引用另一个类时,该类也使用相同的算法进行解析。但这里有一个问题:它只能解决相对于它被发现的地方。让我们看一下SomeCoolThing类在引导类加载器中的情况,但依赖于SomeLameThing,它位于应用程序定义的类加载器中。这个过程看起来像这样:

App-ClassLoader: resolveClass("SomeCoolThing")
    parent->resolveClass("SomeCoolThing")

Boot-ClassLoader (the ultimate parent): resolveClass("SomeCoolThing")
    SomeCoolThing needs SomeLameThing
    resolveClass("SomeLameThing") // Can't find SomeLameThing!!!!

尽管SomeLameThing位于您请求SomeCoolThing的类加载器中,但SomeCoolThing已在另一个类加载器中解析。其他类加载器不了解子类加载器,并尝试自行解决它并失败。

很久以前我有一本书非常好地涵盖了Java ClassLoaders,我推荐它。这是Java Security by O'Reilly Media。它将回答您从未想知道的每个问题,但在处理ClassLoaders及其工作方式时仍需要这些问题。

答案 1 :(得分:0)

我可以回答你的一些问题:

  

单个ClassLoader如何尝试   找到潜在的文件   多个类路径?

如果你的意思是不同的类加载器有不同的类路径,那么每个类加载器都会获取父类加载器的属性(即类路径)。与每个类加载器相同的所有东西都具有相同的类路径(我相信;不确定JVM是否在内部做了任何奇怪的事情)。因此,对于类加载器和所有子类加载器,MyClass.class是相同的。如果在同一个类路径上定义了多个MyClass.class,那么JVM会选择第一个。在过去,我已经创建了自己的类加载器并在现有类路径上添加了一个自定义类路径,以便在运行时加载类,这些类在启动时不在类路径上。

了解它的细节我确定有一个描述这个的规格,或者你可以下载JVM代码(程序集/ C / C ++代码)然后去,但我已经有了这样做,“它不漂亮”。

当然“他们”正在改变1.7中的类路径内容,所以我不确定它是如何工作的......

希望有所帮助...