1. Введение
В этом руководстве мы поговорим об исключении, которое выдает Maven при неправильной настройке: JAVA_HOME должен указывать на JDK, а не на JRE.
Maven — мощный инструмент для создания кода. Мы заглянем под капот, чтобы понять, почему возникает эта ошибка, и посмотрим, как ее решить.
2. Проблема JAVA_HOME
После установки Maven мы должны установить переменную среды JAVA_HOME
, чтобы инструмент знал, где найти команды JDK для выполнения. Цели Maven запускают соответствующие команды Java для исходного кода проекта.
Например, наиболее распространенным сценарием является компиляция кода путем выполнения команды javac
.
Если JAVA_HOME
не указывает на допустимую установку JDK , Maven будет выдавать ошибку при каждом выполнении:
mvn -version
# Output...
The JAVA_HOME environment variable is not defined correctly
This environment variable is needed to run this program
NB: JAVA_HOME should point to a JDK, not a JRE
3. JDK или JRE
Как Maven проверяет путь JAVA_HOME ?
Прежде чем запускать какие-либо цели, Maven проверяет наличие команды java по
пути, указанному JAVA_HOME
, или запрашивая у ОС установку JDK по умолчанию. Если исполняемый файл не найден, Maven завершает работу с ошибкой.
Вот проверка исполняемого файла mvn
для Linux (Apache Maven v3.5.4):
if [ -z "$JAVA_HOME" ] ; then
JAVACMD=`which java`
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
echo "The JAVA_HOME environment variable is not defined correctly" >&2
echo "This environment variable is needed to run this program" >&2
echo "NB: JAVA_HOME should point to a JDK not a JRE" >&2
exit 1
fi
Эта проверка может показаться разумной на первый взгляд, но мы должны учитывать, что и JDK, и JRE имеют папку bin
и обе содержат исполняемый файл Java
.
Следовательно, можно настроить JAVA_HOME
так , чтобы он указывал на установку JRE, скрывая эту конкретную ошибку и вызывая проблемы на более позднем этапе. Хотя основной целью JRE является запуск кода Java, JDK также может выполнять компиляцию и отладку среди других важных отличий .
По этой причине команда компиляции mvn
завершится ошибкой, как мы увидим в следующем подразделе.
3.1. Ошибка компиляции из-за JRE вместо JDK
Как обычно с настройками по умолчанию, они очень полезны, если у нас «стандартная» конфигурация.
Например, если мы установим Java 11 в системе Ubuntu 18.04 и не установим переменную среды JAVA_HOME
, Maven все равно с радостью найдет наш JDK и будет использовать его для различных целей, включая компиляцию.
Но если нам удалось настроить нестандартную конфигурацию (не говоря уже о том, чтобы навести беспорядок) в нашей системе, полезности Maven уже недостаточно. Это может даже ввести в заблуждение.
Предположим, у нас есть следующая конфигурация Ubuntu 18.04:
- JDK 11
- JRE 8
JAVA_HOME указывает
путь к установке JRE 8.
Если мы выполним нашу базовую проверку:
mvn --version
Мы получим значимый вывод, подобный этому:
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T18:41:47Z)
Maven home: /opt/apache-maven-3.6.0
Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-8-openjdk-amd64/jre
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-42-generic", arch: "amd64", family: "unix"
Давайте посмотрим, что произойдет, если мы попытаемся скомпилировать проект:
mvn clean compile
Теперь получаем ошибку:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project my-app: Compilation failure
[ERROR] No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
3.2. Исправление ошибки компиляции на уровне проекта
Как и во многих других случаях с Maven, рекомендуется установить значимые общесистемные настройки — в этом случае мы изменим значение переменной JAVA_HOME
, как описано в разделе 5, чтобы она указывала на JDK, а не на JRE.
Однако, если мы не можем установить значения по умолчанию по какой-либо причине, мы все равно можем переопределить настройки на уровне проекта. Давайте посмотрим, как это сделать.
Сначала мы откроем pom.xml
нашего проекта, перейдем в раздел build/pluginManagement/plugins
и посмотрим на запись для maven-compiler-plugin
:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
Затем мы добавим к нему конфигурацию, чтобы он использовал собственный исполняемый файл и пропустил поиск javac
в каталоге JAVA_HOME/bin
:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<fork>true</fork>
<executable>/usr/lib/jvm/java-11-openjdk-amd64/bin/javac</executable>
</configuration>
</plugin>
В системах Unix этот исполняемый файл должен быть сценарием с соответствующими разрешениями. В системах Windows это должен быть файл .exe
.
Далее попробуем снова скомпилировать проект:
mvn clean compile
Теперь сборка, включая фазу компиляции с плагином maven-compiler-plugin
, прошла успешно.
4. Проверка конфигурации JAVA_HOME
Довольно просто проверить, указывает ли JAVA_HOME
на настоящий JDK. Мы можем либо распечатать его содержимое в терминале, либо запустить одну из следующих команд оболочки:
4.1. Проверка JAVA_HOME
в Linux
Просто откройте терминал и введите:
> $JAVA_HOME/bin/javac -version
Если JAVA_HOME
указывает на JDK, вывод должен выглядеть так:
> javac 1.X.0_XX
Если JAVA_HOME
не указывает на JDK, ОС выдаст сообщение об ошибке:
> bash: /bin/javac: No such file or directory
4.2. Проверка JAVA_HOME
в Windows
Откройте командную строку и введите:
%JAVA_HOME%\bin\javac -version
Если JAVA_HOME
указывает на JDK, вывод должен выглядеть так:
> javac 1.X.0_XX
Если JAVA_HOME
не указывает на JDK, ОС выдаст сообщение об ошибке:
> The system cannot find the path specified.
5. Как решить проблему
Прежде всего, нам нужно знать, где найти наш JDK:
- Если мы установили наш дистрибутив JDK с помощью установщика пакетов, мы должны найти путь с помощью утилиты поиска ОС.
- Если дистрибутив был портативным, давайте проверим папку, куда мы его распаковали.
Как только мы узнаем путь к JDK, мы можем установить нашу переменную среды JAVA_HOME
, используя соответствующие результаты для нашей конкретной ОС .
6. Заключение
В этом кратком руководстве мы обсудили ошибку Maven « JAVA_HOME должна указывать на JDK, а не на JRE»
и рассмотрели ее основную причину.
Наконец, мы обсудили, как проверить переменную среды JAVA_HOME
и как убедиться, что она указывает на JDK.