JAVA_HOME deve apontar para um JDK, não um JRE
1. Introdução
Neste tutorial, vamos falar sobre uma exceção que o Maven lança quando configurado incorretamente:JAVA_HOME should point to a JDK, not a JRE.
Maven é uma ferramenta poderosa para construir código. Procuraremos entender por que esse erro ocorre e veremos como resolvê-lo.
2. O problema deJAVA_HOME
Depois de instalar o Maven,we have to set the JAVA_HOME environment variable, so the tool knows where to find the JDK commands para executar. Os objetivos do Maven executam os comandos Java apropriados no código-fonte do projeto.
Por exemplo, o cenário mais comum é compilar o código executando o comandojavac.
SeJAVA_HOME is not pointing to a valid JDK installation, o Maven lançará um erro a cada execução:
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 ou JRE
Como o Maven verifica o caminhoJAVA_HOME?
Antes de executar qualquer objetivo,Maven checks for the existence of the java command no caminho especificado porJAVA_HOME ou solicitando ao sistema operacional uma instalação JDK padrão. If the executable is not found, Maven terminates with the error.
Aqui está a verificação executávelmvn para 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
Esta verificação pode parecer razoável à primeira vista, mas temos que considerar queboth JDK and JRE have a bin folder and both contain an executable java file.
Portanto, épossible to configure JAVA_HOME to point to a JRE installation, hiding this particular error and causing problems at a later stage.. Enquanto o objetivo principal do JRE é executar o código Java,the JDK can also compile and debug among other important differences.
Por esse motivo, um comandomvn compile falharia - como veremos na próxima subseção.
3.1. Falha de compilação devido ao JRE em vez de JDK
Como de costume com as configurações padrão, eles são muito úteis se tivermos uma configuração "padrão".
Por exemplo, se instalarmos o Java 11 em um sistema Ubuntu 18.04 e não definirmos a variável de ambienteJAVA_HOME, o Maven ainda encontrará nosso JDK e o usará para os diferentes objetivos, incluindo a compilação.
Mas se conseguimos definir uma configuração fora do padrão (quanto mais bagunçar) em nosso sistema, a disponibilidade de Maven não é mais suficiente. Pode até ser enganador.
Vamos supor que temos a seguinte configuração no Ubuntu 18.04:
-
JDK 11
-
JRE 8
-
JAVA_HOME definido para o caminho da instalação do JRE 8
Se fizermos nossa verificação básica:
mvn --version
Obteremos uma saída significativa como esta:
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"
Vamos ver o que acontece se tentarmos compilar um projeto:
mvn clean compile
Agora, recebemos um erro:
[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. Corrigindo o erro de compilação no nível do projeto
Como em muitos outros casos com Maven, é recomendado definir configurações significativas em todo o sistema - neste caso, vamos alterar o valor da variávelJAVA_HOME conforme descrito na seção 5 para apontar para o JDK em vez do JRE.
No entanto, se não podemos definir padrões por qualquer motivo,we can still override the settings on the project level. Vamos ver como fazer isso.
Primeiro, vamos abrir opom.xml do nosso projeto, ir para a seçãobuild / pluginManagement / pluginse dar uma olhada na entrada para omaven-compiler-plugin:
maven-compiler-plugin
3.7.0
Em seguida, adicionaremos uma configuração a ele para que use um executável personalizado e pule a pesquisa porjavac no diretórioJAVA_HOME/bin:
maven-compiler-plugin
3.7.0
true
/usr/lib/jvm/java-11-openjdk-amd64/bin/javac
Nos sistemas Unix, esse executável deve ser um script com permissão adequada. Em sistemas Windows, deve ser um arquivo.exe.
A seguir, tentaremos compilar o projeto novamente:
mvn clean compile
Agora, a construção - incluindo a fase de compilação commaven-compiler-plugin - foi bem-sucedida.
4. Verificando a configuração deJAVA_HOME
É muito simplescheck if JAVA_HOME points to an actual JDK. Podemos imprimir seu conteúdo em um terminal ou podemos executar um dos seguintes comandos de shell:
4.1. VerificandoJAVA_HOME no Linux
Basta abrir um terminal e digite:
> $JAVA_HOME/bin/javac -version
SeJAVA_HOME aponta para um JDK, a saída deve ser semelhante a:
> javac 1.X.0_XX
SeJAVA_HOME não apontar para um JDK, o sistema operacional gerará uma mensagem de erro:
> bash: /bin/javac: No such file or directory
4.2. VerificandoJAVA_HOME no Windows
Abra um prompt de comando e digite:
%JAVA_HOME%\bin\javac -version
SeJAVA_HOME aponta para um JDK, a saída deve ser semelhante a:
> javac 1.X.0_XX
SeJAVA_HOME não apontar para um JDK, o sistema operacional gerará uma mensagem de erro:
> The system cannot find the path specified.
5. Como resolver o problema
Primeiro de tudo, precisamos saber onde encontrar nosso JDK:
-
Se instalamos nossa distribuição JDK usando um instalador de pacotes, poderemos encontrar o caminho usando o utilitário de pesquisa do SO
-
Se a distribuição era portátil, vamos verificar a pasta onde extraímos
Once we know the path to the JDK, we can set our JAVA_HOME environment variable, usandothe appropriate results for our particular OS.
6. Conclusão
Neste breve tutorial, discutimos o “erroJAVA_HOME should point to a JDK not a JRE” Maven e examinamos sua causa raiz.
Finalmente, discutimos como verificar sua variável de ambienteJAVA_HOME e como ter certeza de que aponta para um JDK.