Установка Oracle Java 11 и OpenJDK 11 в CentOS 8 и RHEL 8
![]()
Как очень популярный язык программирования, Java используется для разработки чего угодно, от легких мобильных приложений до настольных приложений. Java JDK (Java Development Kit) — это среда разработки программного обеспечения, используемая для разработки Java-приложений. JDK — это набор инструментов программирования, в частности JRE (Java Runtime Environment — среда выполнения Java), Java (приложение Loader for Java), Javac (компилятор), Jar (архиватор) и так далее.
Эта статья поможет вам установить Oracle Java 11 на CentOS 8 или RHEL 8.
JDK или JRE, OpenJDK или Oracle Java
Разработчики приложений, которые плохо знакомы с Java, часто путают Java Development Kit с Java Runtime Environment. JDK — это пакет инструментов для разработки приложений Java, тогда как JRE — это пакет инструментов для запуска приложений Java. JRE входит в JDK.
Есть два способа установки Java 11:
- Установка Oracle Java SE Development Kit 11 (JDK 11)
- Установка OpenJDK 11
Отличие в том Oracle Java имеет дополнительные коммерческие функций и разрешает только некоммерческое использование ПО, для личного использования. А OpenJDK, в свою очередь — это реализация платформы Java с открытым исходным кодом. Технической разницы между OpenJDK и Oracle JDK нет
Установка OpenJDK 11
Для установки нужно выполнить всего лишь одну команду:
sudo yum install java-11-openjdk-devel
Проверим что все установилось корректно при помощи следующей команды:
java -version
openjdk 11-ea 2018-09-25 OpenJDK Runtime Environment (build 11-ea+28) OpenJDK 64-Bit Server VM (build 11-ea+28, mixed mode, sharing)
Либо c помошью команды which :
which java
Мы должны увидеть такой вывод:
/usr/bin/java
Готово! Мы успешно установили Java!
Чтобы установить более старую версию LTS, OpenJDK 8, используйте следующую команду:
sudo yum install java-1.8.0-openjdk-devel
Установка OpenJRE
Если вы не разрабатываете на Java, но по-прежнему должны запускать приложения Java, вы можете пропустить установку JDK и настроить среду выполнения Java (JRE). JRE представляет собой комбинацию виртуальной машины Java (JVM) и библиотек, необходимых для выполнения кода во время выполнения. Это минимальное требование для запуска любого Java-приложения. Как и в случае с комплектом разработчика, существует две версии среды выполнения LTS — JRE 8 и JRE 11.
Примечание: помните — вам не нужно устанавливать OpenJRE, если у вас уже есть OpenJDK. Среда выполнения поставляется с Java Development Kit по умолчанию.
Чтобы установить JRE 11, запустите:
sudo yum install java-11-openjdk
Чтобы установить JRE 8, используйте команду:
sudo yum install java-1.8.0-openjdk
Установка OpenJDK Headless
Как и OpenJRE, Java Headless является частью OpenJDK и не должна устанавливаться поверх него.
Headless — это минимальная среда выполнения, без графического интерфейса, более подходящая для серверных приложений. Она использует минимальные системные ресурсы и не включает поддержку клавиатуры или мыши.
Установите OpenJDK 11 Headless, введя следующее:
sudo yum установить java-11-openjdk-headless
Для OpenJDK 8 Headless:
sudo yum установить java-1.8.0-openjdk-headless
Установка Oracle Java SE Development Kit 11 (JDK 11)
Официальный Oracle JDK недоступен для загрузки из локального репозитория. Вы должны загрузить пакет .rpm со страницы загрузок Java SE.
Java SE (Standard Edition) является стандартной версией программного обеспечения, в основном используемой для разработки портативных настольных приложений. Альтернативой Java SE является Java Enterprise Edition (Java EE), более подходящая для разработки на уровне энтерпрайза.
Прокрутите вниз, чтобы увидеть разные версии Java SE и найти ту, которая вам нужна. В этой статье мы придерживаемся релиза LTS — Java 11.
Раздел Java SE 11.0.5 (LTS) имеет кнопку загрузки для установки Oracle JDK (Java Development Kit). В отличие от предыдущих версий, в этом выпуске нет возможности загрузить Oracle JRE (Java Runtime Environment) в виде отдельного пакета.
После завершения загрузки вы можете установить пакет с помощью команды:
sudo yum install /home/user/Downloads/jdk-11.0.5-linux-x64.rpm
Замените user фактическим именем пользователя. Кроме того, если ваше имя файла отличается, используйте имя файла вашей загрузки.
Проверяем установку так же при помощи команды -version
java -version
java version "11.0.1" 2018-10-16 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
Установить версию Java по умолчанию
Используйте команду alternatives , чтобы установить версию Java по умолчанию.
alternatives --config java
Если ваша система имеет несколько версий Java, то приведенная выше команда выдаст список всех версий Java, как показано ниже.
There are 3 programs which provide 'java'. Selection Command ----------------------------------------------- 1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.212.b04-1.el8_0.x86_64/jre/bin/java) 2 java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.2.7-2.el8.x86_64/bin/java) *+ 3 /usr/java/jdk-12.0.2/bin/java Enter to keep the current selection[+], or type selection number: 2
Введите число ниже столбца выбора, чтобы установить версию Java по умолчанию. В нашем примере мы выбрали второй вариант.
Установка переменной окружения JAVA_HOME
Приложения Java часто требуют, чтобы переменные окружения JAVA были установлены в системе.
Создайте новый файл в каталоге /etc/profile.d .
vi /etc/profile.d/java.sh
Установите переменные в зависимости от местоположения и версии Java (эти данные мы ранее находили с помошью команды alternatives ):
export PATH=$PATH:/usr/lib/jvm/java-11-openjdk-11.0.2.7-2.el8.x86_64/bin/ export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.2.7-2.el8.x86_64/ export J2SDKDIR=/usr/lib/jvm/java-11-openjdk-11.0.2.7-2.el8.x86_64/
Загрузите окружения в текущий сеанс:
source /etc/profile.d/java.sh
Чтобы установить переменные среды для конкретного пользователя, поместите указанные выше переменные в файл ~/.bash_profile .
Готово. Теперь, мы знаем как установить Java на сервер.
# Установка Java Runtime Environment и Java Development Kit на Ubuntu
Java и Java Virtual Machine — необходимые инструменты для запуска множества программ (Elasticsearch, Kibana, Cassandra). В этой инструкции мы расскажем, как установить Java Runtime Environment (JRE) и Java Development Kit (JDK) на сервер под управлением Ubuntu.
Для работы нам понадобится настроенный сервер под управлением Ubuntu 20.04.
# Установка Java Runtime Environment и Java Development Kit
Мы опишем два способа установки Java, каждый из которых будет использовать команду apt , но источники устанавливаемых приложений будут разными: в первом случае это будут стандартные версии, доступные в репозиториях apt, во втором — релиз будет взят с официального сайта Oracle.
# Способ 1: установка из стандартных репозиториев Ubuntu
Перед началом установки обновим список пакетов apt:
sudo apt update sudo apt upgrade
Теперь проверим, установлен ли Java на сервере. Вводим команду:
java -version
Она должна вернуть сообщение:
java: command not found
Это означает, что Java не установлен. Установим его:
sudo apt install default-jre
Программа-установщик установит Java Runtime Environment.
sudo apt install default-jdk
Она установит доступную по умолчанию версию Java Development Kit.
Проверить версии установленных JRE и JDK можно командами:
java -version javac -version
Чтобы установить конкретные версии JRE и JDK, можно использовать команды:
sudo apt install openjdk-№-jre sudo apt install openjdk-№-jdk
Здесь вместо «№» нужно указать интересующую вас версию устанавливаемого пакета.
# Способ 2: официальный сайт Oracle
Альтерантивным вариантом установки Java является установка с официального сайта
(opens new window) выберите файл с расширением tar.giz. Это архив, из которого будет установлена интересующая нас версия Java.
Для поиска более ранних версий Java можно воспользоваться архивом доступных версий
Скачайте архив с нужной версией на локальный компьютер и поместите его на сервер. Для этого можно воспользоваться SFTP-подключением к серверу или файловым менеджером, если ваш VPS расположен на Джино.
Теперь ереместим архив в специально созданную для него папку:
sudo mkdir -p /var/cache/oracle-jdk-installer-local/ sudo cp archive_name.tar.giz /var/cache/oracle-jdk-installer-local/
Здесь в качестве имени архива указан archive_name.tar.giz — имя архива зависит от выбранной версии.
Архив готов к установке. Теперь нужно произвести дополнительную настройку apt. Установим для него дополнительный пакет, который позволит добавлять репозитории простой командой:
sudo apt install software-properties-common
Добавим ключ для подтверждения устанавливаемых приложений:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EA8CACC073C3DB2A
Также добавим репозиторий для установки Java:
sudo add-apt-repository ppa:linuxuprising/java
Теперь можно обновить список пакетов apt и переходить к установке Java:
sudo apt update sudo apt install image_name
Здесь вместо image_name нужно указать имя скрипта, запускающего установку. В зависимости от образа Java, который вы выбрали, имя может отличаться. Узнать имя скрипта можно здесь
После установки дистрибутива проверить его версию можно теми же командами:
java -version javac -version
# Управление версиями Java
На одном сервере можно устанавливать несколько версий Java и переключаться между ними для удобства управления создаваемыми проектами.
Вывести список всех доступных версий Java и выбрать нужную можно командой:
sudo update-alternatives --config java
В зависимости от количества установленных версий список команда выведет примерно такой список:
Selection Path Priority Status ------------------------------------------------------------ 0 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 auto mode 1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode * 2 /usr/lib/jvm/java-17-oracle/bin/java 1091 manual mode Press enter> to keep the current choice[*], or type selection number:
В конце списка доступных версий команда предлагает выбрать версию Java, которая будет активирована.
Java Runtime Environmetn и Java Development Kit установлены, можно переходить к установке более сложных приложений — например, установить программный стек ELK (Elasticsearch + Logstah + Kibana).
© Джино, 2003–2022. «Джино» является зарегистрированным товарным знаком.
Лицензия на телематические услуги связи №150549 от 09.03.2017.
Переход с Java 8 на Java 11
Для перехода с Java 8 на Java 11 не существует универсального решения. Переход нетривиального приложения с Java 8 на Java 11 может быть трудоемким процессом. К потенциальным проблемам относятся удаленные API, устаревшие пакеты, использование внутреннего API, изменения в загрузчиках классов, а также изменения в сборке мусора.
В целом, подходы заключаются в попытке запуска на Java 11 без перекомпиляции, или с начальной компиляцией с JDK 11. Если цель состоит в том, чтобы запустить приложение как можно быстрее, то зачастую лучшим подходом является попытка запустить приложение на Java 11. Для библиотеки целью будет публикация артефакта, который компилируется и тестируется с помощью JDK 11.
Переход на Java 11 трудозатратный. После выхода Java 8 было добавлено много новых функций и улучшений. Эти функции и усовершенствования улучшают запуск, производительность, использование памяти и обеспечивают лучшую интеграцию с контейнерами. Кроме того в API добавлены дополнения и изменения, повышающие производительность разработчиков.
Этот документ касается средств для проверки кода. Здесь также рассматриваются проблемы, с которыми вы можете столкнуться, и рекомендации по их устранению. Вам также следует принять во внимание другие руководства, такие как Oracle JDK Migration Guide (Руководство по миграции Oracle JDK). В этом руководстве не обсуждается вопрос изменения существующего кода на модулярный.
Панель элементов
В Java 11 есть два инструмента, jdeprscan и jdeps, полезные при выявлении потенциальных проблем. Эти инструменты можно запустить в существующих классах или JAR-файлах. Вы можете оценить усилия для перехода, не нуждаясь в выполнении перекомпиляции.
jdeprscan ищет варианты использования нерекомендуемого или удаленного API. Использование нерекомендуемого API не является блокирующей проблемой, однако на него следует обратить внимание. У вас есть обновленный JAR-файл? Нужно ли заносить проблему в журнал, чтобы решить проблему использования нерекомендуемого API? Использование удаленного API — это блокирующая проблема, которую необходимо решить до попытки запуска на Java 11.
jdeps, представляющий собой анализатор зависимости от класса Java. При использовании с опцией —jdk-internals , jdeps сообщает, от которого внутреннего API зависит каждый класс. Вы можете продолжать использовать внутренний API на Java 11, однако приоритетом должна стать замена потребления. На вики-странице OpenJDK Java Dependency Analysis Tool (Средство анализа зависимости от класса Java) содержатся рекомендуемые замены для некоторых широко используемых внутренних API для JDK.
Для Gradle и Maven есть подключаемые модули jdeps и jdeprscan. Мы рекомендуем добавить эти инструменты в ваши скрипты сборки.
| Инструмент | Подключаемый модуль Gradle | Подключаемый модуль Maven |
|---|---|---|
| jdeps | jdeps-gradle-plugin | Подключаемый модуль Apache Maven JDeps |
| jdeprscan | jdeprscan-gradle-plugin | Подключаемый модуль Apache Maven JDeprScan |
Сам компилятор Java, javac, является еще одним инструментом в вашем инструментарии. Предупреждения и ошибки, которые вы получите от jdeprscan и jdeps, будут выдаваться компилятором. Преимущество использования jdeprscan и jdeps заключается в том, что вы можете запускать эти инструменты поверх существующих файлов JAR и файлов классов, включая сторонние библиотеки.
Что jdeprscan и jdeps не могут сделать, так это предупредить об использовании отражения для доступа к инкапсулированному API. Доступ с помощью рефлексии проверяется во время выполнения. Безусловно, чтобы быть уверенным, код следует запустить на Java 11.
Использование jdeprscan
Самый простой способ использовать jdeprscan — предоставить ему JAR-файл из существующей сборки. Ему можно также предоставить каталог, например выходной каталог компилятора или имя отдельного класса. Используйте параметр —release 11 , чтобы получить наиболее полный список нерекомендуемых API. Если вы хотите определить, какой из нерекомендуемых API следует использовать, снова верните для параметра значение —release 8 . API, признанный нерекомендуемым на Java 8, скорее всего, будет удален раньше, чем API, признанный нерекомендуемым совсем недавно.
jdeprscan --release 11 my-application.jar
Инструмент jdeprscan генерирует сообщение об ошибке при возникновении проблем с разрешением зависимого класса. Например, error: cannot find class org/apache/logging/log4j/Logger . Рекомендуется добавлять зависимые классы в —class-path или использовать путь класса приложения, однако инструмент продолжит сканирование без него. Аргумент — —class-path. Никакие другие вариации аргумента пути класса не сработают.
jdeprscan --release 11 --class-path log4j-api-2.13.0.jar my-application.jar error: cannot find class sun/misc/BASE64Encoder class com/company/Util uses deprecated method java/lang/Double::(D)V
Этот вывод говорит о том, что класс com.company.Util вызывает нерекомендуемый конструктор класса java.lang.Double . javadoc порекомендует, какой API следует использовать вместо нерекомендуемого. Никакой объем работы не решит error: cannot find class sun/misc/BASE64Encoder , поскольку это API, который был удален. Начиная с Java 8, следует использовать java.util.Base64 .
Запустите jdeprscan —release 11 —list , чтобы получить представление о том, какие API стали нерекомендуемыми после Java 8. Чтобы получить список удаленных API, запустите jdeprscan —release 11 —list —for-removal .
Использование jdeps
Используйте jdeps, с опцией —jdk-internals , что найти зависимости от внутреннего API для JDK. Для этого примера нужен параметр командной строки —multi-release 11 , поскольку log4j-core-2.13.0.jar является JAR-файлом с несколькими выпусками. Без этой опции при нахождении JAR-файла с несколькими выпусками jdeps будет создавать предупреждение. Параметр определяет, какую версию файлов классов необходимо проверить.
jdeps --jdk-internals --multi-release 11 --class-path log4j-core-2.13.0.jar my-application.jar Util.class -> JDK removed internal API Util.class -> jdk.base Util.class -> jdk.unsupported com.company.Util -> sun.misc.BASE64Encoder JDK internal API (JDK removed internal API) com.company.Util -> sun.misc.Unsafe JDK internal API (jdk.unsupported) com.company.Util -> sun.nio.ch.Util JDK internal API (java.base) Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break your application. Please modify your code to eliminate dependence on any JDK internal APIs. For the most recent update on JDK internal API replacements, please check: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool JDK Internal API Suggested Replacement ---------------- --------------------- sun.misc.BASE64Encoder Use java.util.Base64 @since 1.8 sun.misc.Unsafe See http://openjdk.java.net/jeps/260
Выход дает несколько хороших советов по устранению использования внутреннего API JDK. Замена API предлагается на всех возможных местах. В скобках указано имя модуля, в котором инкапсулирован пакет. Имя модуля можно использовать с —add-exports или —add-opens , если необходимо явно прервать инкапсуляцию.
Использование sun.misc.BASE64Encoder или sun.misc.BASE64Decoder приведет на Java 11 к ошибке java.lang.NoClassDefFoundError. Использующий эти API код следует модифицировать для использования java.util.Base64.
Попробуйте исключить использование любых API, исходящих из модуля jdk.unsupported. API из этого модуля будет ссылаться на Предложение по усовершенствованию JDK (JEP) 260 в качестве предлагаемой замены. Если кратко, то JEP 260 говорит, что использование внутреннего API будет поддерживаться до тех пор, пока не будет доступен заменяющий API. Несмотря на то, что ваш код может использовать внутренний API для JDK, он будет продолжать работать, по крайней мере, некоторое время. Взгляните на JEP 260, так как он указывает на замену некоторых внутренних API. переменные дескрипторы можно использовать, например, вместо некоторых API sun.misc.Unsafe.
jdeps может сделать нечто большее, чем просто проверить использование внутренних компонентов JDK. Это полезный инструмент для анализа зависимостей и создания файлов сведений о модуле. Дополнительные сведения можно найти в документации.
Использование javac
Компиляция с JDK 11 потребует обновлений для сборки скриптов, инструментов, тестовых платформ и включенных библиотек. Используйте параметр -Xlint:unchecked для javac, чтобы получить подробные сведения об использовании внутреннего API JDK и других предупреждений. Также для демонстрации компилятору инкапсулированных пакетов может потребоваться использование —add-opens или —add-reads (см. JEP 261).
Библиотеки могут рассматривать упаковку как JAR-файл с несколькими выпусками. JAR-файлы с несколькими выпусками позволяют поддерживать среды выполнения как Java 8, так и Java 11 из одного и того же JAR-файла. Они действительно добавляют сложность в выполнение сборки. Сведения о сборке JAR-файлов с несколькими выпусками не входят в область, рассматриваемую эти документом.
Выполнение на Java 11
Большинство приложений должно работать на Java 11 без необходимости в изменениях. Первое, что нужно попробовать — это запустить Java 11 без перекомпиляции кода. Смысл простого запуска заключается в том, чтобы посмотреть, какие предупреждения и ошибки будут выданы во время выполнения. При таком подходе
приложение работает на Java 11 быстрее, сосредоточившись на минимуме, который необходимо сделать.
Большинство проблем, с которыми вы можете столкнуться, можно решить, не выполняя перекомпиляцию кода. Если проблему следует исправлять в коде, исправьте ее, но продолжайте компилировать с помощью JDK 8. По возможности работайте над доведением приложения до запуска с java версией 11 до компиляции с JDK 11.
Проверка параметров командной строки
Перед выполнением на Java 11 следует выполнить быструю проверку параметров командной строки. Удаленные опции приведут к выходу виртуальной машины Java. Эта проверка особенно важна, если вы используете опции ведения журнала для сборки мусора, поскольку они радикально изменились с Java 8. Инструмент JaCoLine хорошо подходит для обнаружения проблем с параметрами командной строки.
Проверка сторонних библиотек
Потенциальным источником проблем являются сторонние библиотеки, которые вы не контролируете. Вы можете заблаговременно обновлять сторонние библиотеки до более новых версий. Или посмотреть, что выходить за пределы выполнения приложения и обновить только нужные библиотеки. Проблема с обновлением всех библиотек до последней версии заключается в том, что это затрудняет поиск первопричины появления в приложении ошибки. Ошибка произошла из-за какой-то обновленной библиотеки? Или ошибка была вызвана каким-то изменением в среде выполнения? Проблема обновления связана только с тем, что для ее решения может потребоваться несколько итераций.
Рекомендуется вносить как можно меньше изменений и обновлять сторонние библиотеки в виде отдельных трудозатрат. Если вы обновляете стороннюю библиотеку, то чаще всего вам потребуется самая последняя версия, совместимая с Java 11. В зависимости от того, насколько отстает ваша текущая версия, возможно, вы захотите применить более осторожный подход и обновить ее до первой версии, совместимой с Java 9+.
Кроме просмотра заметок о выпуске, для оценки JAR-файла можно использовать jdeps и jdeprscan. Кроме того, Группа контроля качества OpenJDK поддерживает вики-страницу Quality Outreach (Популяризация качественного содержимого), на которой перечислен статус тестирования многих проектов FOSS с версиями OpenJDK.
Явно установленная сборка мусора
Сборщик мусора Parallel (Parallel GC) — это стандартный сборщик мусора в Java 8. Если приложение использует значение по умолчанию, сборку мусора следует явно задать с помощью параметра командной строки -XX:+UseParallelGC . Вместо значения по умолчанию в Java 9 используется сборщик мусора G1GC (Garbage First Garbage Collector). Чтобы справедливо сравнить приложение, работающее на Java 8, с Java 11, настройки сборки мусора должны быть одинаковыми. Экспериментирование с настройками сборки мусора следует отложить, пока приложение не будет проверено на Java 11.
Явно заданные параметры по умолчанию
При запуске на ВМ HotSpot, установка параметра командной строки -XX:+PrintCommandLineFlags будет сбрасывать значения параметров, установленных ВМ, в частности, значения по умолчанию, установленные сборкой мусора. Запускайте с этим флагом на Java 8 и используйте печатные параметры при запуске на Java 11. По большей части, значения по умолчанию для версий от 8 до 11 одинаковы. Но использование настроек из 8 обеспечивает четность.
Рекомендуется использовать параметр командной строки —illegal-access=warn . Использование рефлексии для доступа к внутреннему API для JDK в Java 11 приведет к появлению предупреждения о недопустимом доступе с помощью рефлексии. По умолчанию предупреждение выдается только при первом недопустимом доступе. Установка —illegal-access=warn приведет к вызову предупреждения при каждом недопустимом доступе с помощью рефлексии. Установив параметр на предупреждение, вы сможете найти еще больше случаев недопустимого доступа. Но вы также будете получать много лишних предупреждений.
После запуска приложения на Java 11, установите —illegal-access=deny для имитации будущего поведения во время выполнения Java. Начиная с Java 16, значением по умолчанию будет —illegal-access=deny .
Предостережения ClassLoader
В Java 8 загрузчик системного класса можно привести к URLClassLoader . Обычно это выполняется приложениями и библиотеками, которые хотят внедрить классы в путь к классу во время выполнения. В Java 11 иерархия классов загрузчиков изменилась. Загрузчик системного класса (также известный как загрузчик класса приложения) теперь является внутренним классом. Приведение к URLClassLoader вызовет ClassCastException во время выполнения. Java 11 не имеет API для динамического дополнения пути к классу во время выполнения, но это можно сделать с помощью рефлексии, с очевидными предостережениями об использовании внутреннего API.
В Java 11 загрузчик класса загрузки загружает только основные модули. При создании загрузчика классов с нулевым родительским элементом, он сможет найти не все классы платформы. В Java 11 в таких случаях в качестве загрузчика класса родительского элемента нужно передавать ClassLoader.getPlatformClassLoader() , а не null .
Изменения локальных данных
Источник локальных данных по умолчанию на Java 11 изменен с помощью JEP 252 на Единый репозиторий локальных данных консорциума Юникод. Это может повлиять на локальное форматирование. При необходимости установите системное свойство java.locale.providers=COMPAT,SPI для возврата к поведению языкового стандарта Java 8.
Возможные проблемы
Вот некоторые из общих проблем, с которыми вы можете столкнуться. Более подробные сведения по этим вопросам см. по ссылкам.
- Нераспознанный параметр ВМ
- Нераспознанный параметр
- Предупреждение ВМ: игнорирование параметра
- Предупреждение ВМ: параметр option> нерекомендуемый
- ПРЕДУПРЕЖДЕНИЕ: возникла недопустимая операция доступа с помощью рефлексии
- java.lang.reflect.InaccessibleObjectException
- java.lang.NoClassDefFoundError
- -Xbootclasspath/p больше не поддерживается
- java.lang.UnsupportedClassVersionError
Нераспознанные параметры
Если параметр командной строки удален, то приложение выведет Unrecognized option: или Unrecognized VM option , за которым последует имя конфликтующего параметра. Нераспознанный параметр приведет к выходу ВМ. Нерекомендуемые параметры, которые не были удалены, будут выдавать предупреждение ВМ.
В общем, удаленные параметры не заменяются, и единственным решением является удаление параметра из командной строки. Исключением являются опции для ведения журнала о сборе мусора. Ведение журнала о сборке мусора реализовано в Java 9 для использования унифицированной платформы ведения журналов JVM. См. «Table 2-2 Mapping Legacy Garbage Collection Logging Flags to the Xlog Configuration» (Таблица 2-2. Сопоставление флагов ведения журнала устаревших сборок мусора с конфигурацией Xlog) в разделе Enable Logging with the JVM Unified Logging Framework (Включение ведения журнала с помощью унифицированной платформы ведения журналов JVM) из Справочника по инструментам Java SE 11.
Предупреждения ВМ
Использование нерекомендуемых параметров приведет к созданию предупреждения. Параметр становится нерекомендуемым, если он заменен или больше не используется. Как и в случае с удаленными параметрами, эти параметры следует удалить из командной строки. Предупреждение VM Warning: Option was deprecated означает, что параметр все еще поддерживается, но эта поддержка может быть удалена в будущем. Параметр, который больше не поддерживается, будет выдавать предупреждение VM Warning: Ignoring option . Неподдерживаемые параметры не влияют на среду выполнения.
На веб-странице VM Options Explorer (Обозреватель параметров ВМ) представлен исчерпывающий список параметров, которые были добавлены в Java, начиная с JDK 7 или добавлены в него.
Ошибка: Не удалось создать виртуальную машину Java.
Это сообщение об ошибке выводится, когда виртуальная машина Java сталкивается с нераспознанным параметром.
ПРЕДУПРЕЖДЕНИЕ. Возникла недопустимая операция доступа с помощью рефлексии
Если Java-код использует отражение для доступа к внутреннему API JDK, во время выполнения будет выдано предупреждение о недопустимом доступе с помощью рефлексии.
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by my.sample.Main (file:/C:/sample/) to method sun.nio.ch.Util.getTemporaryDirectBuffer(int) WARNING: Please consider reporting this to the maintainers of com.company.Main WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
Это означает, что модуль не экспортировал пакет, доступ к которому осуществляется через отражение. Пакет инкапсулирован в модуль и по сути является внутренним API. Предупреждение можно проигнорировать в качестве первого шага по установке и запуску Java 11. Время выполнения Java 11 разрешает доступ с помощью рефлексии, так что старый код может продолжать работу.
Чтобы решить это предупреждение, найдите обновленный код, который не использует внутренний API. Если проблему невозможно решить с помощью обновленного кода, для открытия доступа к пакету можно использовать либо параметр —add-exports , либо параметр командной строки —add-opens . Эти параметры позволяют получить доступ к неэкспортированным типам одного модуля из другого.
Параметр —add-exports позволяет целевому модулю получить доступ к общедоступным типам именованного пакета модуля-источника. Иногда для доступа к членам и API, не являющимся открытыми, код будет использовать setAccessible(true) . Он известен, как глубокое отражение. В этом случае используйте —add-opens для предоставления вашему коду доступа к членам пакета, которые не являются открытыми. Если вы не уверены, использовать —add-exports или —add-opens, начните с —add-exports.
Параметры —add-exports или —add-opens следует рассматривать как обходной путь, а не как долгосрочное решение. Использование этих опций прерывает инкапсуляцию модульной системы, которая должна препятствовать использованию внутреннего API JDK. Если внутренний API будет удален или изменен, приложение выйдет из строя. Доступ с помощью рефлексии будет запрещен на Java 16, за исключением случаев, когда доступ будет разрешен параметрами командной строки, такими как —add-opens . Чтобы имитировать будущее поведение, установите —illegal-access=deny в командной строке.
Предупреждение в приведенном выше примере выдается потому, что пакет sun.nio.ch не экспортируется модулем java.base . Другими словами, в файле module-info.java модуля java.base нет exports sun.nio.ch; . Это можно решить с помощью —add-exports=java.base/sun.nio.ch=ALL-UNNAMED . Классы, не определенные в модуле, неявно принадлежат неименованному модулю, буквально названному ALL-UNNAMED .
java.lang.reflect.InaccessibleObjectException
Это исключение указывает на то, что вы пытаетесь вызвать setAccessible(true) в поле, или метод инкапсулированного класса. Вы также можете получить предупреждение о недопустимом доступе с помощью рефлексии. Используйте —add-opens для предоставления вашему коду доступа к членам пакета, которые не являются открытыми. Сообщение об исключении сообщит, что модуль «не открывает» пакет модулю, который пытается вызвать setAccessible. Если модуль является «неименованным», используйте UNNAMED-MODULE в качестве целевого модуля в параметре —add-opens.
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.ArrayList jdk.internal.loader.URLClassPath.loaders accessible: module java.base does not "opens jdk.internal.loader" to unnamed module @6442b0a6 $ java --add-opens=java.base/jdk.internal.loader=UNNAMED-MODULE example.Main
java.lang.NoClassDefFoundError
Ошибка NoClassDefFoundError, скорее всего, вызвана разделенным пакетом или ссылкой на удаленные модули.
Ошибка NoClassDefFoundError, вызванная разделением пакетов
Раздельный пакет —это пакет, находящийся в нескольких библиотеках. Симптомом проблемы разделения пакетов является то, что класс, который должен находится в пути класса, невозможно найти.
Эта проблема будет возникать только при использовании пути модуля. Система модулей Java оптимизирует поиск классов, ограничивая пакет одним именованным модулем. При выполнении поиска классов предпочтение отдается пути модуля, а не класса. Если пакет разделен между модулем и путем к классу, то для поиска класса используется только модуль. Это может привести к ошибкам NoClassDefFound .
Простой способ проверки разделенного пакета — подключить путь к модулю и к классу в jdeps и использовать путь к файлам класса приложения в качестве значения . Если есть разделенный пакет, jdeps выведет предупреждение: Warning: split package: .
Эту проблему можно решить, используя —patch-module =[,] для добавления разделенного пакета в именованный модуль.
Ошибка NoClassDefFoundError, вызванная использованием модулей Java EE или CORBA
Если приложение работает на Java 8, но вызывает java.lang.NoClassDefFoundError или java.lang.ClassNotFoundException , то вполне вероятно, что приложение использует пакет из модулей Java EE или CORBA. Эти модули признаны нерекомендуемыми на Java 9 и удалены на Java 11.
Чтобы решить проблему, добавьте в проект зависимость среды выполнения.
| Удаленный модуль | Затронутый пакет | Предлагаемая зависимость |
|---|---|---|
| Java API для Веб-служб XML (JAX-WS) | java.xml.ws | Среда выполнения RI для JAX WS |
| Архитектура Java для привязки XML (JAXB) | java.xml.bind | Среда выполнения JAXB |
| Платформа активации JavaBeans (JAV) | java.activation | Платформа активации JavaBeans (TM) |
| Общие заметки | java.xml.ws.annotation | API заметки Javax |
| Архитектура брокера запросов общих объектов (CORBA) | java.corba | GlassFish CORBA ORB |
| API транзакций Java (JTA) | java.transaction | API транзакций Java |
-Xbootclasspath/p больше не поддерживается
Поддержка для -Xbootclasspath/p удалена. Используйте вместо этого —patch-module . Параметр —patch-module описан в JEP 261. Ищите раздел с названием «Patching module content» (Исправление содержимого модуля). —patch-module можно использовать с javac и java для переопределения или дополнения классов в модуле.
Что делает —patch-module, так это вставляет модуль исправления в поиск класса модульной системы. Модульная система сначала захватит класс из модуля исправления. Это тот же эффект, что и в случае с bootclasspath на Java 8.
UnsupportedClassVersionError
Это исключение означает, что вы пытаетесь запустить код, который был скомпилирован с более поздней версией Java, на более ранней версии Java. Например, вы работаете на Java 11 с JAR-файлом, скомпилированным с JDK 13.
| Версия Java | Версия формата файла класса |
|---|---|
| 8 | 52 |
| 9 | 53 |
| 10 | 54 |
| 11 | 55 |
| 12 | 56 |
| 13 | 57 |
Дальнейшие действия
После того, как приложение запустится на Java 11, рассмотрите возможность переноса библиотек с пути класса на путь модуля. Выполните поиск обновленных версий библиотек, от которых зависит ваше приложение. Если возможно, выбирайте модульные библиотеки. Используйте путь модулей, даже если вы не планируете использовать модули в своем приложении. Использование пути модуля предоставляет производительность при загрузке классов, которая намного лучше производительности при использовании пути модуля.
Как установить Java на Ubuntu
Если вы хотите узнать, как установить Java в Ubuntu быстро и без трудностей — используйте нашу инструкцию. Мы поможем разобраться, какая версия Java лучше, и рассмотрим оптимальные способы установки Java в Ubuntu.
Java — это объектно-ориентированный язык веб-программирования. Он применяется при создании сайтов, десктопных программ, серверных и веб-приложений. Рассмотрим версии Java и способы их установки в Ubuntu.
Какие версии Java существуют
Когда-то Java имела всего две стабильные версии — Java 7 и Java 8. Версия Java 8 регулярно обновлялась, поэтому много лет была популярна в разработке. Например, на ней написаны приложения для Android, компьютерная игра Minecraft и социальная сеть Twitter. В настоящее время компания Oracle выпускает новые версии каждые полгода, но к ним выходит минимальное количество обновлений.
Любую версии Java можно установить в одном из форматов распространения. Основные форматы распространения дистрибутивов Java:
- Oracle Java (Oracle JDK) — бесплатный для разработки, но платный при использовании в рабочей среде. Включает дополнительные возможности и техподдержку.
- Open JDK — открытая бесплатная версия. Представлена в двух редакциях:
- JRE (Java Runtime Environment) — содержит компоненты, предназначенные только для запуска Java-программ в Linux.
- JDK (Java Development Kit) — полная версия, которая включает компоненты, предназначенные для запуска, компиляции и разработки Java-программ. JDK по умолчанию содержит в себе редакцию JRE.
Описанные форматы подойдут для любой версии семейства Linux Ubuntu и будут работать как на десктопах, так и на веб-серверах. Мы разберем оба способа установки Java и в разных вариантах редакций.
Перед установкой Java проверьте, что она ещё не установлена на вашем сервере, командой: java —version.
В примере ниже установлена версия OpenJDK 11.0.7:

Ubuntu Java install
Как установить OpenJDK
Рассмотрим, как установить самую свежую и более старые версии Java.
Чтобы автоматически установить самую свежую версию OpenJDK (она уже есть в официальном репозитории Ubuntu):
Обновите пакеты apt:
sudo apt update