Um problema comum que os novos desenvolvedores Java experimentam é que seus programas não funcionam com a mensagem de erro: Não poderiam encontrar ou carregar a classe principal ...
O que significa isto, o que o causa e como o deve corrigir?
java <class-name>
Primeiro de tudo, você precisa entender a maneira correta de lançar um programa utilizando o comando java
(ou javaw
).
A sintaxe normal1 é isto:
java [ <option> ... ] <class-name> [<argument> ...]
onde <option>
é uma opção de linha de comando (começando com um "-" caracter), <class-name>
é um nome de classe Java totalmente qualificado, e <argument>
é um argumento de linha de comando arbitrário que é passado para a sua aplicação.
1 - Há uma segunda sintaxe para "executável" arquivos JAR que descreverei em baixo.
O nome totalmente qualificado (FQN) para a classe é convencionalmente escrito como você faria em código fonte Java; por exemplo
packagename.packagename2.packagename3.ClassName
No entanto, algumas versões do comando `java' permitem a utilização de barras em vez de pontos; por exemplo
packagename/packagename2/packagename3/ClassName
que (confusamente) parece um nome de ficheiro, mas é't um. Note que o termo nome qualificado é a terminologia padrão do Java ... não é algo que eu apenas inventei para confundi-lo :-)
Aqui está um exemplo de como um comando java
deve ser:
java -Xmx100m com.acme.example.ListUsers fred joe bert
O acima vai fazer com que o comando 'java' faça o seguinte:
main
com signature, return type e modifiers dados por public static void main(String[])
. (Nota, o argumento do método's name is **NOT*** part of the signature).String[]
.
Razões pelas quais Java não consegue encontrar a classejava
não foi capaz de encontrar a classe. E de fato, o "..." na mensagem estará o nome da classe qualificada que a java
está procurando.
Então, por que não foi capaz de encontrar a classe?A primeira causa provável é que você pode ter fornecido o nome de classe errado. (Ou ... o nome de classe certo, mas na forma errada.) Considerando o exemplo acima, aqui estão uma variedade de ** maneiras erradas*** para especificar o nome da classe:
Exemplo #1 - um simples nome de classe:
java ListUser
Quando a classe é declarada em um pacote como com.acme.example', então você deve utilizar o nome completo da classe *incluindo* o nome do pacote no comando
java'; por exemplo.
java com.acme.example.ListUser
Exemplo #2 - um nome de arquivo ou pathname em vez de um nome de classe: java ListUser.class java com/acme/example/ListUser.class
Exemplo #3 - um nome de classe com o invólucro incorreto: java com.acme.example.listuser
Exemplo #4 - uma gralha java com.acme.example.mistuser
Exemplo #5 - um nome de arquivo de origem java ListUser.java
A segunda causa provável é que o nome da classe está correto, mas que o comando `java' não consegue encontrar a classe. Para entender isso, você precisa entender o conceito do "classpath". Isto é explicado bem pela documentação do Oracle:
O Tutorial Java - PATH e CLASSPATH. Então ... se você especificou o nome da classe corretamente, a próxima coisa a verificar é que você especificou corretamente o nome da classe:
java
.;
no Windows e :
nos outros. Se você utilizar o separador errado para sua plataforma, você ganhará't receberá uma mensagem de erro explícita. Ao invés disso, você receberá um arquivo ou diretório inexistente no caminho que será silenciosamente ignorado).
Motivo #2a - o diretório errado está no classpathQuando você coloca um diretório no classpath, ele nocionalmente corresponde à raiz do espaço do nome qualificado. As classes estão localizadas na estrutura do diretório abaixo dessa raiz, mapeando o nome totalmente qualificado para um nome de caminho. Então, por exemplo, se "/usr/local/acme/classes" está no caminho da classe, então quando a JVM procura por uma classe chamada `com.acme.example.Foon', ela irá procurar por um ".class" arquivo com este caminho:
/usr/local/acme/classes/com/acme/example/Foon.class
Se suas classes FQN é `com.acme.example.Foon', então a JVM vai procurar por "Foon.class" no diretório "com/acme/example":
/usr/local/acme/classes/com/acme/example/
,
então:# wrong, FQN is needed
java Foon
# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon
# wrong, similar to above
java -classpath . com.acme.example.Foon
# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
Notas:
A opção -classpath' pode ser abreviada para
-cp' na maioria dos lançamentos Java. Verifique as respectivas entradas manuais para java
, javac
e assim por diante.
O classpath precisa de incluir todas as outras classes (não-sistema) das quais a sua aplicação depende. (As classes do sistema são localizadas automaticamente, e raramente você precisa se preocupar com isso). Para que a classe principal seja carregada corretamente, a JVM precisa encontrar:
a própria turma.
todas as classes e interfaces na hierarquia de superclasses (por exemplo, ver https://stackoverflow.com/questions/42880748)
package'. Se você fizer isso em um IDE, o compilador do IDE's irá informá-lo sobre isso imediatamente. Da mesma forma, se você utilizar uma ferramenta de compilação Java decente, a ferramenta executará o
javac` de uma forma que detectará o problema. Entretanto, se você construir seu código Java manualmente, você pode fazê-lo de tal forma que o compilador't note o problema, e o ".class" resultante; file não está no lugar que você espera que ele esteja.
Ainda não consegue't encontrar o problema?-Xdiag' à linha de comando
java' (como a primeira coisa depois de `java'). Ele irá gerar várias coisas sobre o carregamento de classes, e isso pode oferecer pistas sobre qual é o verdadeiro problema.
Além disso, considere possíveis problemas causados pela cópia e colagem de caracteres invisíveis ou não-ASCII de sites, documentos e assim por diante. E considere "homoglyphs", eram duas letras ou símbolos parecidos ... mas são't.java -jar <jar file>
A sintaxe alternativa utilizada para " executável" arquivos JAR é a seguinte:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
por exemplo
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
java
.
No entanto, ainda é possível que essa exceção ocorra, se você fizer coisas por trás das costas da IDE. Por exemplo, se você tiver previamente configurado um Application Launcher para sua aplicação Java no Eclipse, e você então moveu o arquivo JAR contendo o "main" class para um lugar diferente no sistema de arquivos sem dizer ao Eclipse, o Eclipse lançaria inconscientemente a JVM com um classpath incorreto.
Em resumo, se você tiver esse problema em uma IDE, verifique coisas como estado da IDE, referências de projeto quebradas ou configurações de lançador quebradas.
Também é possível que uma IDE simplesmente fique confusa. IDE's são peças de software extremamente complicadas, compreendendo muitas partes que interagem entre si. Muitas destas partes adotam várias estratégias de cache para tornar a IDE como um todo responsiva. Estas podem às vezes dar errado, e um possível sintoma são os problemas ao lançar aplicações. Se você suspeita que isso pode estar acontecendo, vale a pena tentar as coisas de mentir reiniciando seu IDE e reconstruindo o projeto.Às vezes o que pode estar causando o problema não tem nada a ver com a classe principal, e eu tinha que descobrir isso da maneira mais difícil. Foi uma biblioteca referenciada que eu mudei, e ela me deu o:
Não foi possível encontrar ou carregar a classe principal xxx Linux
Acabei de apagar essa referência, adicionei-a novamente, e funcionou bem novamente.
Primeiro defina o caminho usando este comando;
set path="paste the set path address"
Então você precisa de carregar o programa. Digite "cd (nome da pasta)" na unidade armazenada e compile-o. Por exemplo, se meu programa estiver armazenado na unidade D, digite "D:" pressione enter e digite " cd (nome da pasta)".