2016-11-15 3 views
6

различные ресурсы (infoq, jigsaw-dev, osdir) показывают, что наличие того же пакета в различных модулях ява приведет к LayerInstantiationException, даже когда пакеты находятся внутри модуля (неэкспортированной).
Это, кажется, точная противоположность того, что requirements говорят:Java 9 перекрывающихся неэкспортируемые пакеты

Java-компилятор, виртуальная машина, и времени выполнения системы необходимо убедиться, что модули, которые содержат пакеты одного и того же имени не мешают друг другу , Если два разных модуля содержат пакеты с одинаковым именем, то с точки зрения каждого модуля все типы и члены этого пакета определяются только этим модулем.

Таким образом, два модуля, используемые приложением, могут содержать частные пакеты с тем же именем?

EDIT
Это issue из спецификациям пестицидов как указывает Станислав Лукьянов

ответ

1

Это определение открыто для интерпретации. Он остается верным, поскольку Jigsaw гарантирует, что два модуля никогда не будут определять общие пакеты, разбив загрузку класса в случае такого конфликта.

Если вы посмотрите на реализацию загрузчика классов Java 9, вы увидите, что имя пакета отображается одним модулем. Поэтому невозможно, чтобы два имели два модуля для объявления права собственности. Тем не менее, возможно, что два класса загрузчика в дочерних и родительских отношениях определяют один и тот же пакет.

+0

Я бы сказал, что два загрузчика классов не должны находиться в отношениях между родителями и родителями, потому что для меня это означает, что ребенок сначала попросит родителя для класса/пакета и только затем попытается загрузить его самостоятельно (или наоборот) – Bax

+1

Чтобы избежать этого, Java 9 отказался от метода 'getPackage' в пользу метода' getDefinedPackage'.Такое же имя пакета двумя разными загрузчиками классов не считается равным даже сегодня; если вы, например, подкласс A из B, B не можете переопределить частные методы пакета A, если он был загружен в другой загрузчик классов. Если родитель не определяет один и тот же класс (!), Нет проблем, если они используют тот же пакет, что и его не равный. Эта проблема возникает только в том случае, если пакеты определены двумя модулями внутри одного загрузчика классов. –

+0

- это каждый модуль, загруженный другим загрузчиком классов по умолчанию? – Bax

5

Как сказано в обсуждаемых вами обсуждениях, проблема заключается в сопоставлении между загрузчиками классов и модулями.

Когда вы загружаете два модуля M1 и M2 как содержащие неэкспортированный (он же скрытый) пакет P через загрузчик классов CL JPMS должен отвергнуть такую ​​конфигурацию, так как в противном случае оба ключевых принципов JPMS - сильная капсула и надежной конфигурация - может быть сломан. Выбрасывая исключение, JPMS фактически реализует указанное вами требование и гарантирует, что никакие конфликты не могут сломать что-либо позже во время выполнения.

С другой стороны, когда вы загружаете M1 и M2 через два погрузчиков CL1 и CL2 вы на самом деле создаете два время выполнения пакетов {CL1, P} и {CL2, P}, так что нет никакого столкновения и Layer может быть реализован.

Проблема юзабилити заключается в том, что java использует один загрузчик для всех модулей прикладного уровня («начальный», созданный из аргументов командной строки), что приводит к LayerInstantiationException. В настоящее время это открытая проблема в списке JPMS, см. [Здесь] (http://openjdk.java.net/projects/jigsaw/spec/issues/#AvoidConcealedPackageConflicts). Но независимо от разрешения проблемы, если необходимо, вы должны иметь возможность иметь дело с разделенными пакетами, написав крошечный основной класс, который создаст нужный вам Configuration (Кстати, контейнер приложений, поддерживающий JPMS, вероятно, сделает это за вас).

Смежные вопросы