Java 9 перекрывает неэкспортируемые пакеты

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

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

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

ИЗМЕНИТЬ
Это проблема JMPS, как указал Станислав Лукьянов


person Bax    schedule 15.11.2016    source источник


Ответы (2)


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

Когда вы загружаете два модуля 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, вероятно, сделает это за вас).

person Stanislav Lukyanov    schedule 16.11.2016

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

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

person Rafael Winterhalter    schedule 16.11.2016
comment
Я бы сказал, что два загрузчика классов не должны быть в дочерне-родительских отношениях, потому что для меня это означает, что ребенок сначала спросит у родителя класс/пакет и только затем попытается загрузить его самостоятельно (или наоборот) - person Bax; 16.11.2016
comment
Чтобы этого избежать, в Java 9 метод getPackage объявлен устаревшим в пользу метода getDefinedPackage. Одно и то же имя пакета для двух разных загрузчиков классов не считается равным даже сегодня; если вы, например, подкласс A из B, B не может переопределить частные методы пакета A, если он был загружен в другом загрузчике классов. Если родитель не определяет тот же класс (!), нет проблем, если они используют один и тот же пакет, поскольку он не равен. Эта проблема возникает только в том случае, если пакеты определены двумя модулями в одном и том же загрузчике классов. - person Rafael Winterhalter; 18.11.2016
comment
каждый модуль по умолчанию загружается другим загрузчиком классов? - person Bax; 07.02.2018
comment
Нет. По умолчанию все пользовательские классы и все системные классы загружаются двумя одними и теми же загрузчиками классов. - person Rafael Winterhalter; 07.02.2018
comment
Это означает, что проблема возникает по умолчанию, а не только если - person Bax; 07.02.2018