Ответ был дан Аланом Бейтманом в списке рассылки jigsaw-dev и размещен здесь.
Слои модуля - это продвинутая тема c. ClassLoaders также являются продвинутыми topi c. При работе со слоями модулей и использовании методов defineModulesWithXXX
для создания слоев модулей вам больше не нужно слишком беспокоиться о загрузчиках классов. Они по-прежнему используются для загрузки классов, но в основном они находятся в фоновом режиме (а не на вашем лице).
Вам также не нужно слишком беспокоиться о «родительском загрузчике классов», который вы указываете для defineOneWithOneLoader
метод. Он не используется при загрузке классов из модулей, это только когда для случаев, когда код в moduleB
или moduleC
пытается загрузить класс, который не находится в модуле, возможно Class.forName("Foo")
, где Foo
находится на пути к классам , Поэтому, вероятно, лучше всего игнорировать загрузчик родительского класса при запуске.
Документы API объясняют, как делегирование работает с модулями, но, возможно, не совсем понятно, для чего здесь нужно. В вашем примере поддержка L1
- это загрузчик класса для moduleB
на дочернем уровне 1, а L2
- это загрузчик класса для moduleC
на дочернем уровне 2. Далее предположим, что объявления модуля:
module moduleC {
requires moduleB;
}
module moduleB {
exports b;
}
Конфигурация для Child1
очень проста: один moduleB
, который читает java.base
Конфигурация для Child2
также очень прост: один moduleC
, который читает moduleB
и java.base
.
Когда создается Child1
, он создает L1
и отображает moduleB
в L1
. Когда код в moduleB
пытается разрешить ссылку на класс в своем собственном модуле, он будет загружен L1
(без делегирования). Когда moduleB
ссылается на класс в java.base
, L1
делегирует boot loader
.
Когда создается Child2
, он создает L2
и отображает moduleC
в L2
, Когда код в moduleC
пытается разрешить ссылку на класс в своем собственном модуле, он будет загружен L2
(без делегирования). Когда moduleC
ссылается на класс b.*
, он будет делегирован L1
для разрешения ссылки. Когда moduleC
ссылается на класс в java .base, тогда L2
делегирует загрузчику.
Если вы вытягиваете это, вы должны увидеть, что делегирование загрузчика классов является "прямым делегированием" и точно отражает края в графе читаемости (объект конфигурации).
Надеюсь, этого достаточно для начала работы. Это действительно нуждается в диаграммах и графиках, чтобы объяснить некоторые из этих деталей, вероятно. Как я уже сказал, при работе со слоями модуля вы можете в основном игнорировать детали загрузчика классов.