Java 类加载器和依赖解析

发布于 2024-10-07 20:00:40 字数 244 浏览 0 评论 0原文

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

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

尽可能详细,我们将不胜感激:)

Can someone clarify that the role of a ClassLoader is not only to load an individual class, but also its dependencies? And if so, what exactly does the entire process entail? I'm looking for implementation detail if at all possible.

For example, at some point, bytes are going to have to be read in from somewhere (a network or filesystem location), and file system locations are going to have to be calculated on the basis of a classes canonical name and a foreknowledge of class paths available to the JVM- how does an individual ClassLoader try to locate a file over potentially multiple class-paths? Where does it get this information from? Also, at what point are a class files bytes verified and its dependencies examined for availability?

As much detail as possible would be appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我不在是我 2024-10-14 20:00:40

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

在类加载器(例如 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 类加载器,我推荐它。它是 O'Reilly Media 的 Java Security。在处理类加载器及其工作原理时,它将回答您不想知道但仍然需要知道的每一个问题。

ClassLoading is a very complex subject. The ClassLoader and Java security model are inextricably tied together. Essentially the JVM loads classes on demand. When there is a hierarchy of classloaders, the JVM attempts to resolve the class as far down the chain as possible. In short, if the class is defined in the "boot" classloader and in an application defined class loader, it will always use the version in the boot classloader.

Within a classloader, such as the URLClassLoader, the search order is the order in which you've told it to look. Essentially the array of URLs you told it had classes will be searched from the first entry to the last.

When the class that you defined references another class, that class is also resolved using the same algorithm. But here's the catch: it only resolves it relative to where it was found. Let's take the scenario where the class SomeCoolThing is in the boot classloader, but depends on SomeLameThing, which is in an application defined classloader. The process would look like this:

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

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

Even though SomeLameThing is in the classloader where you requested SomeCoolThing, SomeCoolThing was resolved in a different classloader. That other classloader has no knowledge of the child classloader, and tries to resolve it itself and fails.

I had a book a long time ago that covered the Java ClassLoaders in really good depth, and I recommend it. It's Java Security by O'Reilly Media. It will answer every question you never wanted to know, but still need to, when dealing with ClassLoaders and how they work.

晚雾 2024-10-14 20:00:40

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

单个类加载器如何尝试
潜在地定位文件
多个类路径?

如果您的意思是不同的类加载器有不同的类路径,那么每个类加载器都会采用父类加载器的属性(即类路径)。所有事情都相同,每个类加载器都具有与其他任何类加载器相同的类路径(我相信;不确定 JVM 内部是否做了任何奇怪的事情)。所以 MyClass.class 对于类加载器和所有子类加载器来说是相同的。如果在同一个类路径上定义了多个 MyClass.class,那么 JVM 将选择第一个。过去,我创建了自己的类加载器,并将自定义类路径添加到现有类路径上,以在运行时加载启动时不在类路径上的类。

深入了解它的具体细节,我确信有一个规范对此进行了描述,或者您可以下载 JVM 代码(汇编/C/C++ 代码)并进行操作,但我必须这样做和“这不漂亮”。

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

希望能有所帮助...

I can answer some of your questions:

how does an individual ClassLoader try
to locate a file over potentially
multiple class-paths?

If you mean different class loaders have different classpaths then each class loader takes the properties (i.e. classpath) of the parent class loader. All things equal each class loader has the same classpath as any other (I believe; not sure if the JVM does anything weird internally). So MyClass.class is the same for a class loader and all child class loaders. If you have multiple MyClass.class defined on the same class path then the JVM picks up the first one. In the past I've created my own class loader and prepended a custom classpath onto the existing classpath to load classes at runtime that were not on the classpath when launched.

The get to the nuts and bolts of it I'm sure there is a spec out there that describes this or you could download the JVM code (the assembly/C/C++ code) and go though that but I've had to do that and "it ain't pretty".

Of course "they" are changing the classpath stuff in 1.7 so I'm not sure how that is going to work...

Hope that helps a bit...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文