последовательность
В этой статье в основном изучаются некоторые меры предосторожности для миграции в Java9.
Типы миграции
1. Код не модульный, сначала мигрируйте в JDK9, чтобы использовать API JDK9.
2. Код также модульный мигрируется
Некоторые вещи должны отметить
Нечитаемые занятия
Например, Sun.security.x509 классифицируется в модуль Java.base в Java9, но модуль не экспортирует пакет.
Вы можете изменить настройки экспорта, добавив hava.base/sun.security.x509 = все наложено-add-exports.
Внутренний класс
Например, sun.misc.unsafe первоначально хотел использовать команду Oracle JDK, но поскольку эти классы слишком широко используются, Java9 сделал компромиссы, чтобы быть обратной совместимостью, но только классифицировал эти классы в модуль JDK.UnSupport, и не ограничивал их читаемость.
➜ ~ java -d jdk.unsupportedjdk.unsupported@9exports com.sun.nio.fileexports sun.miscexports sun.reflectrecefir
Удаленный класс
Java9 удалил Sun.misc.base64encoder, в этом случае вы можете использовать только другие API, такие как java.util.base64
ClassPath против модуля-пат
Java9 представил модульную систему, и ее собственный JDK также был модулизован, и модульный Path был введен для блокировки ClassPath. То есть модульный пат предпочтительнее в Java9. В конце концов, сам JDK модульный. Если само приложение не является модульным, Java9 неявно модулизован через неназванные модули и автоматические механизмы модулей. Конечно, ClassPath может продолжать использоваться на Java9, например, использование Module-Path.
Банка без модульности будет классифицирована как неназванные модули в классе; В Module-Path он будет автоматически создан в виде автоматических модулей (автоматический модуль будет заявлять, что переход зависит от всех именованных и неназванных модулей, а затем экспортировать свой собственный пакет)
Имя пакета не может отображаться в нескольких модулях (разделенные пакеты)
Поскольку экспорт может быть указан на другие модули в модулях, если несколько модулей экспортируют одно и то же имя пакета, это приведет к путанице. Особенно, если есть другие классовые библиотеки, которые требуют этих двух модулей одновременно, вы не знаете, на какой модуль следует ссылаться.
Транзитивные зависимости
Если параметры интерфейса или тип возврата модуля используют классы других модулей, рекомендуется требовать транзитивных модулей, от которых это зависит.
Будьте осторожны с круглыми зависимостями
При проектировании модулей подумайте, будут ли как можно больше круговых зависимостей. Если это так, вам нужно перепроектировать их.
Используйте услуги для реализации дополнительных зависимостей
Услуги особенно подходят для развязки зависимостей абонентов и классов реализации. Если интерфейс имеет несколько классов реализации, абоненту не нужно требовать всех классов реализации, но требует только интерфейса Asm, и используйте тип служб для загрузки экземпляров класса реализации. Развязка достигается путем динамического добавления модулей реализации в модуле.
Управление версией модуля
Module info.java не поддерживает объявление номеров версий, но при создании пакетов JAR вы можете установить их-модуль-версия. Однако, когда модульная система ищет модули, она по-прежнему использует имя модуля для поиска (если есть несколько дублирующих модулей в пакете модуля, модульная система будет знать, чтобы использовать первый найденный и автоматически игнорировать последующий модуль с тем же именем). Проблема зависимости версии не находится в рамках решения системы модульной системы и оставлена инструментами управления зависимостями, такими как Maven для управления.
Доступ к ресурсам модуля
После модуляризации файл ресурса также защищен, и модуль может получить доступ только к файлу ресурса самого модуля. Если требуется кросс-модульный доступ, необходимо также использовать модулелей, чтобы найти целевой модуль, а затем вызовать целевой модуль для загрузки файла ресурса модуля.
Использование отражения
Это включает в себя проблему глубокого размышления. Так называемое глубокое отражение-это назвать непубличный элемент класса посредством отражения. Экспорты модуля info.java заявляют, что пакет разрешает только класс, к которому пакет принадлежит напрямую, позволяет доступа к своему общественному элементу, и не позволяет отражать вызовы в непубличных элементах.
Отражение требует особых объявлений, которые должны быть разрешены в системе модулей (с использованием объявлений Opens, чтобы обеспечить глубокое отражение), что приводит к многим классовым библиотекам, которые используют отражение, такие как пружина, которые требуют, чтобы дополнительная конфигурация была перенесена на Java9. Существует два решения: одно - открыть имя пакета для модулей, которые нуждаются в отражении, таких как Spring.Beans и т. Д.; Другой должен напрямую открыть весь модуль.
По умолчанию-Allegal-Access = разрешение, и эта настройка применима только к пакетам перед Java9, которым не разрешается получить доступ к Java9, и не применимо к новым пакетам, которым не разрешается доступ в Java9. (Рекомендуется установить, чтобы отрицать при миграции в модульную систему)
Однако в модульной системе имена пакетов различны, и нет никаких отношений наследования. Например, com.service.func1 и com.service.func2 - это разные пакеты. Вы не можете просто открыть Com.service, но вы должны указать их отдельно, что приводит к большему количеству пакетов, которые требуют открытия. Следовательно, открытие всего модуля может быть проще в использовании, но это также относительно грубый подход.Приведенный выше метод состоит в том, чтобы внести изменения в оригинальный модуль info.java. Другой метод состоит в том, чтобы изменить исходную связь через указанную команду при выполнении Java или Javac. например
java ...-oadd-opens source-module/source-package = target-module
Если вам необходимо экспортировать в неназванные модули, целевой модуль вселен, не названный
Конечно, если это новая система, не рекомендуется использовать отражение. Методы и вариноцы могут быть использованы.
Часто задаваемые вопросы и меры
ClassNotFoundException/noclassDeffoundError
Например, javax.xml.bind.jaxbexception, Jaxb был классифицирован в модуль Java.xml.bind и добавляется после именования Java.
-Адд-модулы java.xml.bind
Если вы хотите сэкономить неприятности, добавьте $ java_home и всю стороннюю библиотеку в модуль-пат, а затем
-Адд-модулы
Незаконный рефлексивный доступ к XXX к методу java.lang.classloader.defineclass
Отражение причин, поскольку старая система не имеет модуля, добавляйте параметры к именованию Java и модифицируют ее.
-add-opens java.base/java.lang = all-unnamed
Определите модуль зависимости
Анализ через IDE или JDEPS
jdeps -классы классов/lib/*'-recursive -summary app.jar
JDEPS - это всего лишь статический анализ кода. Если есть класс, который использует отражение, вы не можете его проанализировать. Вам нужно вручную требовать этого. Если зависимость не является обязательной, вам может потребоваться статическое.
Проблемы читаемости для модульных модульных тестов
Если для модульного тестирования используется модуль, модулю модульного тестирования может быть предоставлен возможность читабельности и отражения целевого модуля через-ADD-Exports или-ADD-OPEN во время выполнения. Кроме того, из -за проблем с разделенными пакетами имя пакета класса модульного тестирования не может быть дублировано с помощью имени пакета целевого модуля. Оказывается, тест проекта Maven
краткое содержание
Вы можете переехать в Java9 за два шага. Во -первых, сначала вы не модуль, сначала вы работаете только на JDK9; Тогда вы модульный.