ModuleLayer和ClassLoader之间是什么关系? [英] What is the relation between ModuleLayer and ClassLoader?
问题描述
让我们考虑以下情况.一共有三层.
Let's consider the following situation. There are three layers.
BootLayer (moduleA)
|
|_______Child1(moduleB)
|
|__________ Child2(moduleC)
Child1是BootLayer的子代,Child2是Child1的子代.
Child1 is the child of the BootLayer, Child2 is the child of the Child1.
Child1
和 Child2
是由相同的代码创建的:
Child1
and Child2
was created by the same code:
ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parentLayer.defineModulesWithOneLoader(cf, parentClassLoader);
如您所见,两个子层的父类加载器是SystemClassLoader.但是, moduleB
可以使用 moduleA
的类,但是 moduleC
可以使用 moduleA
和 moduleB
.
As you see the parent class loader of both child layers is SystemClassLoader. However, moduleB
can use classes of moduleA
, but moduleC
can use classes of moduleA
and moduleB
.
我是类加载的初学者,但是我已经阅读了有关 parent-first委托模型
的信息.但是,如果两个子层都使用SystemClassLoader,那么为什么他们看到其他层的类呢?有人可以解释吗?
I am a beginner at classloading, but I've read about parent-first delegation model
. However, if for both child layers SystemClassLoader is used, then why they see classes from other layers? Could anyone explain?
推荐答案
答案由Alan Bateman在jigsaw-dev邮件列表中给出,并在此处发布.
The answer was given by Alan Bateman in jigsaw-dev mailing list and is posted here.
模块层是一个高级主题.ClassLoaders也是一个高级主题.在使用模块层并使用 defineModulesWithXXX
方法创建模块层时,您通常不需要太在意类加载器.它们仍然用于加载类,但是它们大部分在后台(而不是您的脸).
Module layers are an advanced topic. ClassLoaders are also an advanced topic. When working with module layers and using the defineModulesWithXXX
methods to create the module layers, then you mostly don't need to be too concerned with class loaders. They are still used to load classes but they are mostly in the background (and not in your face).
您也不必太担心为 defineOneWithOneLoader
方法指定的父类加载器".从模块加载类时不使用它,仅当 moduleB
或 moduleC
中的代码试图加载不在模块中的类(例如> Class.forName("Foo")
,其中 Foo
在类路径上.因此,可能最好在开始时忽略父类加载器.
You also don't need to be too concerned with the "parent class loader" that you specify to the defineOneWithOneLoader
method. It's not used when loading classes from modules, it's only when for cases where the code in moduleB
or moduleC
tries to load a class that is not in a module, maybe Class.forName("Foo")
where Foo
is on the class path. So probably best to ignore the parent class loader when starting out.
The API docs explain how the delegation works with modules but maybe it's not clear enough for what is needed here. In your example, support L1
is the class loader for moduleB
in child layer 1, and L2
is the class loader for moduleC
in child layer 2. Further suppose the module declarations are:
module moduleC {
requires moduleB;
}
module moduleB {
exports b;
}
Child1 的配置非常简单:一个读取 java.base
Child2 的配置也非常简单:一个读取 moduleB
和 java.base
的 moduleC
.
The configuration for Child2
is also very simple: one moduleC
that reads moduleB
and java.base
.
创建 Child1
后,它将创建 L1
,并将 moduleB
映射到 L1
.当 moduleB
中的代码尝试解析其自身模块中对类的引用时,它将由 L1
(无委托)加载.当 moduleB
引用 java.base
中的类时, L1
将委托给 boot loader
.
When Child1
is created it will create L1
and map moduleB
to L1
. When code in moduleB
tries to resolve a reference to a class in its own module then it will be loaded by L1
(no delegation). When moduleB
references a class in java.base
then L1
will delegate to the boot loader
.
创建 Child2
后,它将创建 L2
,并将 moduleC
映射到 L2
.当 moduleC
中的代码尝试解析其自身模块中对类的引用时,它将由 L2
加载(无委托).当 moduleC
引用一个 b.*
类时,它将被委托给 L1
来解析该引用.当 moduleC
在java.base中引用一个类时, L2
将委托给引导加载程序.
When Child2
is created it will create L2
and map moduleC
to L2
. When code in moduleC
tries to resolve a reference to a class in its own module then it will be loaded by L2
(no delegation). When moduleC
references a b.*
class then it will be delegate to L1
to resolve the reference. When moduleC
references a class in java.base then L2
will delegate to the boot loader.
如果将其绘制出来,则应该看到类加载器委托是直接委托",并且完全反映了可读性图(配置对象)中的边缘.
If you draw this out then you should see that the class loader delegation is "direct delegation" and exactly mirrors the edges in the readability graph (Configuration object).
希望这足以开始您的学习.它确实需要图表来解释其中的一些细节.正如我所说,在使用模块层时,您几乎可以忽略类加载器的详细信息.
Hopefully this is enough to get your started. It really needs diagrams and graphs to explain some of these details probably. As I said, you can mostly ignore class loader details when working with module layers.
这篇关于ModuleLayer和ClassLoader之间是什么关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!