O que significa "não foi possível encontrar ou carregar a classe principal"?

um problema comum que os novos programadores Java experimentam é que os seus programas não conseguem executar com a mensagem de erro: Could not find or load main class ...

O que significa isto, o que o causa e como o deve corrigir?

Author: Stephen C, 2013-08-07

30 answers

A sintaxe de comando java <class-name>

Em primeiro lugar, você precisa entender a maneira correta de lançar um programa usando o comando java (ou javaw).

A sintaxe normal1 é isto:

java [ <option> ... ] <class-name> [ <argument> ... ]

Onde <option> é uma opção de linha de comandos (começando com um carácter" -"), <class-name> é um nome de classe Java totalmente qualificado, e <argument> é um argumento de linha de comandos arbitrário que é passado para a sua aplicação.
1 - Existe uma segunda sintaxe para "executável" Arquivos JAR que vou descrever no fundo.

O nome totalmente qualificado (FQN) para a classe é convencionalmente escrito como você faria no código fonte Java; por exemplo

packagename.packagename2.packagename3.ClassName

Note que o termo nome completamente qualificado é terminologia Java padrão ... não foi algo que inventei para te confundir.

Aqui está um exemplo do que um comando java deve parecer:

java -Xmx100m com.acme.example.ListUsers fred joe bert

O acima vai fazer com que o comando java faça o seguinte:

  1. procura a versão compilada da classe com.acme.example.ListUsers.
  2. Carreguem a classe.
  3. verifique se a classe tem um método main com a assinatura , return type and modificadores dados por public static void main(String[]). (Note, the method argument's name is NOT part of the signature.)
  4. chama a esse método passar os argumentos da linha de comando ("fred", "joe", "bert") como um String[].

Razões pelas quais Java não consegue encontrar o classe

Quando você recebe a mensagem "não conseguiu encontrar ou carregar a classe principal ...", isso significa que o primeiro passo falhou. O comando java não foi capaz de encontrar a classe. E, na verdade, o"..."na mensagem estará o nome de classe totalmente qualificado que java está procurando.

Então porque não pode encontrar a turma?

Razão # 1-cometeste um erro com o argumento do nome da classe

A primeira causa provável é que possa ter fornecido o nome errado da turma. (Ou ... o nome certo da classe, mas na forma errada.) Considerando o exemplo acima, aqui uma variedade de maneiras erradas para especificar o nome da classe:

  • Exemplo #1-um nome de classe simples:

    java ListUser
    

    Quando a classe é declarada num pacote como com.acme.example, então deve usar 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 ficheiro ou pathname nome da classe:

    java ListUser.class
    java com/acme/example/ListUser.class
    
  • Exemplo # 3 - um nome da classe com o invólucro incorrecto:

    java com.acme.example.listuser
    
  • Exemplo # 4-a typo

    java com.acme.example.mistuser
    
  • Exemplo #5 - um nome de ficheiro de código

    java ListUser.java
    
  • Exemplo nº6: Esqueceste-te completamente do nome da classe.
    java lots of arguments
    

Razão # 2 - O fecho da aplicação está incorrectamente especificado

A segunda causa provável é que o nome da classe esteja correcto, mas que o java o comando não consegue encontrar a classe. Para entender isso, você precisa entender o conceito de "classpath". Isto é explicado bem pela documentação do Oráculo:

Então ..... se você especificou o nome da classe corretamente, a próxima coisa a verificar é que você especificou o claspath correctamente:
    Leia os três documentos acima. (Sim ... Lê-os. É importante que um programador Java compreenda pelo menos o básico de como os mecanismos de classpath Java funcionam.)
  1. veja a linha de comandos e / ou a variável de ambiente CLASPATH que está em vigor quando executar o comando java. Verifique se os nomes das pastas e os nomes dos ficheiros JAR estão correctos.
  2. se há relativos nomes de caminho no classpath, verifique se resolvem correctamente ... a partir da pasta actual que está em vigor quando executar o comando java.
  3. verifique se a classe (mencionada na mensagem de erro) pode ser localizada no eficaz claspath.
  4. Note que a sintaxe do claspath é diferente Para Windows versus Linux e Mac OS. (O separador de classpath é ; nas janelas e : nas outras.)

Razão # 2a-o directório errado está no claspath

Quando coloque uma pasta no classpath, que corresponde nocionalmente à raiz do espaço de nomes qualificado. As Classes estão localizadas na estrutura de pastas por baixo dessa raiz, mapeando o nome completamente qualificado para um nome de localização . Então, por exemplo, se "/ usr / local / acme / classes "está no caminho da classe, então quando o JVM procura por uma classe chamada com.acme.example.Foon, Ele vai procurar por um".ficheiro de classe" com este nome de localização:

/usr/local/acme/classes/com/acme/example/Foon.class

Se tivesse colocado "/ usr / local / acme / classes / com / acme / exemplo" no classpath, então o JVM não seria capaz de encontrar a classe.

Razão #2b-o caminho subdirectório não corresponde ao FQN

Se as tuas aulas FQN são com.acme.example.Foon, Então o JVM vai procurar "Foon".classe "no directório" com / acme / exemplo":

  • Se a sua estrutura de diretório não corresponder ao nome do pacote de acordo com o padrão acima, o JVM não vai encontrar a sua classe.

  • Se você tentar mudar o nome de uma classe ao movê - la, isso vai falhar. Também... mas a excepção stacktrace será diferente.

Para dar um exemplo concreto, supondo que:
  • queres correr com.acme.example.Foon classe,
  • a localização completa do ficheiro é /usr/local/acme/classes/com/acme/example/Foon.class,
  • a sua pasta de trabalho actual é /usr/local/acme/classes/com/acme/example/,

Depois:

# 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 encurtada para -cp na maioria das versões Java. Verificar as entradas manuais respectivas para java, javac e assim no.
  • pense cuidadosamente ao escolher entre nomes de caminho absolutos e relativos em classpaths. Lembre-se que um nome de localização relativo pode "quebrar" se a pasta actual mudar.

Razão # 2c-dependências em falta no claspath

O claspath precisa de incluir todas as classes de outras (Não-sistema) das quais a sua aplicação depende. (As classes do sistema são localizadas automaticamente, e você raramente precisa se preocupar com isso.) Para a principal classe para carregar correctamente, o JVM precisa de encontrar:

    A própria classe.
  • todas as classes e interfaces na hierarquia da superclasse (por exemplo, ver esta questão)
  • todas as classes e interfaces referidas por meio de declarações variáveis ou variáveis, ou expressões de chamada de método ou de acesso ao campo.

(Nota: as especificações JLS E JVM permitem alguma margem para uma JVM carregar as classes "preguiçosamente", o que pode afectar quando um carregador de classes a excepção é lançada.)

Razão #3-a classe foi declarada na embalagem errada Às vezes acontece que alguém coloca um ficheiro de código-fonte no ... a pasta errada na sua árvore de código fonte, ou deixam de fora a declaração package. Se você fizer isso em uma IDE, o compilador da IDE vai lhe falar sobre isso imediatamente. Da mesma forma, se você usar uma ferramenta de compilação Java decente, a ferramenta irá executar javac de uma forma que irá detectar o problema. No entanto, se você construir o seu código Java à mão, você pode fazê-lo de tal forma que o compilador não percebe o problema, e o resultado ".o arquivo class " não está no lugar que você espera que esteja. Ainda não encontraste o problema? Há muitas coisas para verificar, e é fácil perder alguma coisa. Tente adicionar a opção -Xdiag à linha de comandos java (como a primeira coisa a seguir a java). Ele irá produzir várias coisas sobre o carregamento de classes, e isso pode lhe oferecer pistas sobre o que o problema real e. 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 "homoglifos", eram duas letras ou símbolos iguais ... mas não são.

A sintaxe java -jar <jar file>

A sintaxe alternativa usada para ficheiros JAR "executáveis" é a seguinte:

java [ <option> ... ] -jar <jar-file-name> [<argument> ...]

Por exemplo

java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred

Neste caso, são especificados o nome da classe do ponto de entrada (isto é, com.acme.example.ListUser) e o claspath. no manifesto do ficheiro JAR.


IDEs

Um IDE Java típico tem suporte para executar aplicações Java no IDE JVM em si ou em um JVM infantil. Estes são geralmente imunes a esta excepção em particular, porque o IDE usa os seus próprios mecanismos para construir o classpath do tempo de execução, identificar a classe principal e criar a linha de comandos java.

No entanto, ainda é possível que esta exceção ocorra, se você fizer coisas nas costas da IDE. Por exemplo, se tiver configurado previamente um lançador de aplicações para a sua aplicação Java no Eclipse, e tiver então movido o ficheiro JAR que contém a classe "principal" para um local diferente no sistema de ficheiros sem dizer ao Eclipse, O Eclipse iria lançar involuntariamente o JVM com um classspath incorrecto. Em resumo, se você tiver este problema em um IDE, verifique para coisas como estado de IDE obsoleto, referências de projeto quebradas ou configurações de lançadores quebrados.

Também é possível uma IDE para ficar confusa. As IDE são peças de software extremamente complicadas que compreendem muitas partes interagindo. Muitas destas partes adotam várias estratégias de caching, a fim de tornar a IDE como um todo responsivo. Estes podem às vezes dar errado, e um possível sintoma é problemas ao lançar aplicações. Se suspeita que isto possa estar a acontecer, vale a pena reiniciar a sua IDE.


Outras Referências

 922
Author: Stephen C, 2018-10-13 16:53:51

Se o seu nome de código é HelloWorld.java, o seu código compilado será HelloWorld.class.

Você vai ter esse erro se você chamá-lo usando:

java HelloWorld.class

Em vez disso, use isto:

java HelloWorld
 190
Author: panoet, 2017-09-04 14:06:24

Se as suas classes estão em pacotes, então você tem que cd para a pasta principal e executar usando o nome completo da classe (packageName.MainClassName).

Exemplo:

As minhas aulas estão aqui.
D:\project\com\cse\

O nome completo da minha turma principal é:

com.cse.Main

De volta ao directório principal:

D:\project

Então emite o comando java:

java com.cse.Main
 101
Author: tharinduwijewardane, 2017-01-14 16:54:38

Se o seu método principal estiver na classe sob um pacote, deve passá-lo pela pasta hierárquica.

Assume que existe um ficheiro de código-fonte (Main.java):

package com.test;

public class Main {

    public static void main(String[] args) {
        System.out.println("salam 2nya\n");
    }
}

Para executar este código, deverá colocar Main.Class no pacote como directory ./com/test/Main.Java. E na pasta de base use java com.test.Main.

 44
Author: M-Razavi, 2017-05-23 17:32:03

Quando o mesmo código funciona num PC, mas mostra o erro noutro, a melhor solução que já encontrei é compilar como o seguinte:

javac HelloWorld.java
java -cp . HelloWorld
 36
Author: Enamul Hassan, 2017-01-14 16:56:52

O que me ajudou foi especificar o fecho na linha de comando, por exemplo:

  1. Criar uma nova pasta, C:\temp

  2. Criar a temperatura do ficheiro.java in C:\temp, com a seguinte classe:

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
    
  3. Abra uma linha de comandos na pasta C:\temp, e escreva o seguinte comando para compilar a classe Temp:

    javac Temp.java
    
  4. Execute a classe Java compilada, adicionando a opção -classpath para que o JRE saiba onde encontrar a classe:

    java -classpath C:\temp Temp Hello!
    
 27
Author: Celebes, 2017-01-14 16:51:55

De acordo com a mensagem de erro ("não foi possível encontrar ou carregar a classe principal"), existem duas categorias de problemas:

  1. A classe principal não pôde ser encontrada
  2. A classe principal não pôde ser carregada (este caso não é completamente discutido na resposta aceite)

A classe principal não pôde ser encontrada quando existe erro de sintaxe no nome da classe completamente qualificado ou não existe no classpath indicado.

Principal a classe não poderia ser carregada Quando a classe não pode ser iniciada, normalmente a classe principal estende-se por outra classe e essa classe não existe no fecho fornecido.

Por exemplo:

public class YourMain extends org.apache.camel.spring.Main

Se a camela-primavera não estiver incluída, este erro será reportado.

 21
Author: Xiao Peng - ZenUML.com, 2017-06-05 00:38:20
Às vezes, o que pode estar a causar o problema não tem nada a ver com a turma principal, e tive de descobrir isto da maneira mais difícil. Foi uma biblioteca referenciada que eu mudei, e deu-me o:

Não foi possível encontrar ou carregar a classe principal xxx Linux

Apaguei a referência, voltei a adicioná-la e funcionou bem outra vez.
 12
Author: Eduardo Dennis, 2017-01-14 16:49:21

Tive um erro tão grande neste caso:

java -cp lib.jar com.mypackage.Main

Funciona com ; Para O Windows e : para o Unix:

java -cp lib.jar; com.mypackage.Main
 12
Author: Yamahar1sp, 2017-04-09 10:30:52

Use este comando:

java -cp . [PACKAGE.]CLASSNAME

Exemplo: se o seu nome de classe é Hello.classe criada a partir de Hello.java então use o comando abaixo:

java -cp . Hello

Se o seu ficheiro está.java está dentro do pacote com.demonstração então use o comando abaixo

java -cp . com.demo.Hello

Com o JDK 8 muitas vezes acontece que o arquivo de classe está presente na mesma pasta, mas o java comando de espera classpath e por esta razão, iremos adicionar -cp . para assumir a pasta atual como referência para classpath.

 12
Author: shaILU, 2018-02-06 23:55:46

Tenta - Xdiag .

A resposta de Steve C cobre os casos possíveis muito bem, mas às vezes para determinar se a classe não poderia ser encontrada ou carregada pode não ser assim tão fácil. Utilizar java -Xdiag (desde JDK 7). Isto imprime um stacktrace bonito que fornece uma dica para o que a mensagem Could not find or load main class significa.

Por exemplo, pode indicar-lhe outras classes utilizadas pela classe principal que não puderam ser encontradas e impediram a classe principal de ser carregado.

 10
Author: jan.supol, 2018-02-06 23:18:14

Neste caso tens:

Não foi possível encontrar ou carregar a classe principal ?claspath

É porque você está usando "- claspath", mas o traço não é o mesmo usado por {[[0]} na linha de comandos. Eu tinha este número copiando e colando de Notepad para cmd.

 8
Author: Nathan Williams, 2017-01-14 16:55:34

No meu caso, ocorreu um erro porque eu tinha fornecido o nome do ficheiro de origem em vez do nome da classe.

Temos de fornecer o nome da classe que contém o método principal ao intérprete.
 6
Author: KawaiKx, 2014-03-12 00:37:57

Isto pode ajudá-lo se o seu caso for especificamente como o meu: como principiante, também me deparei com este problema quando tentei executar um programa Java.

Eu compilei-o assim:
javac HelloWorld.java

E eu tentei correr também com a mesma extensão:

java Helloworld.java

Quando removi o .java e reescrevi o comando como java HelloWorld, o programa correu perfeitamente. :)

 6
Author: Ramesh Pareek, 2018-02-06 23:53:28

enter image description here

Localização do ficheiro da classe: C:\test\com\company

Nome Do Ficheiro: Main.classe

Nome Completo da classe: com.empresa.Principal

Comando da linha de comandos:

java  -classpath "C:\test" com.company.Main
Note aqui que a localização da classe não inclui a \com \ company
 5
Author: developer747, 2017-03-27 02:18:52

Se usar Maven para compilar o ficheiro JAR, certifique-se que indica a classe principal no pom.ficheiro xml:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>class name us.com.test.abc.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
 5
Author: Junchen Liu, 2018-02-06 23:52:16
Passei um bom tempo a tentar resolver este problema. Pensei que estava de alguma forma a ajustar o meu Fecho incorrectamente, mas o problema era que eu escrevia:
java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool  

Em vez de:

java -cp C:/java/MyClasses utilities/myapp/Cool   

Pensei que o Significado de totalmente qualificado significava incluir o nome completo do caminho em vez do nome completo do pacote.

 5
Author: mathewbruens, 2018-02-07 08:14:26

Primeiro defina a localização com este comando;

set path="paste the set path address"
Então tens de carregar o programa. Escreva "cd (nome da pasta)" na unidade armazenada e compile-a. Por exemplo, se meu programa armazenado na unidade D, digite "D:" pressione enter e digite " cd (nome da pasta)".
 4
Author: arun, 2013-12-02 14:33:34

O que resolveu o problema no meu caso foi:

Carregue com o botão direito no projecto / classe que deseja executar, depois Run As->Run Configurations. Então você deve corrigir a sua configuração existente ou adicionar nova da seguinte forma:

Abra a Página Classpath, carregue no botão Advanced... e depois adicione bin pasta do seu projecto.

 4
Author: syntagma, 2016-01-16 10:26:31
Este é um caso específico, mas como vim a esta página à procura de uma solução e não a encontrei, vou adicioná-la aqui.

O Windows (testado com 7) não aceita caracteres especiais (como á) nos nomes das classes e dos pacotes. No entanto, o Linux tem.

Descobri isto quando construí um em NetBeans e tentei executá-lo na linha de comando. Funcionava em NetBeans, mas não na linha de comando.
 3
Author: GuiRitter, 2015-12-27 00:26:16

Todas as respostas aqui são direcionadas para os usuários do Windows que parece. Para Mac, o separador de claspath é :, não ;. Como um erro configurar o classpath usando ; não é jogado, então isso pode ser difícil de descobrir se vindo do Windows para Mac.

Aqui está o comando Mac correspondente:

java -classpath ".:./lib/*" com.test.MyClass

Onde neste exemplo o pacote é com.test e uma pasta lib também deve ser incluída no claspath.

 3
Author: blue-sky, 2017-01-20 19:24:53

Ao executar a opção {[2] } com a opção -cp como anunciado no Windows PowerShell, poderá obter um erro que se pareça com:

The term `ClassName` is not recognized as the name of a cmdlet, function, script ...

Para que o PowerShell aceite o comando, os argumentos da Opção -cp devem ser contidos entre aspas como em:

java -cp 'someDependency.jar;.' ClassName

Formar o comando desta forma deverá permitir ao Java processar os argumentos do claspath correctamente.

 3
Author: Chezzwizz, 2017-05-21 08:14:38

Às vezes, em alguns compiladores online que você pode ter tentado você vai obter este erro se você não escrever {[[0]} mas apenas class [Classname].

 3
Author: lor, 2017-08-18 18:29:30
Tudo bem, muitas respostas já, mas ninguém mencionou o caso onde a permissão de arquivo pode ser o culpado. Quando o utilizador em execução não tem acesso ao ficheiro jar ou a uma das pastas da localização. Por exemplo, considere:

Jar file in /dir1/dir2/dir3/myjar.jar

User1 quem é o dono do frasco pode fazer:

# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
Mas ainda não funciona.
# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram

Isto acontece porque o utilizador em execução (User2) não tem acesso a dir1, dir2, ou javalibs ou dir3. Pode enlouquecer alguém quando User1 pode ver os arquivos, e pode acessar a eles, mas o erro ainda acontece para User2

 3
Author: biocyberman, 2018-09-26 12:33:35

No Windows coloque {[[0]} no valor de CLASPATH no início.

O . (dot) significa "procurar na pasta actual". Esta é uma solução permanente.

Também pode definir "uma vez" com set CLASSPATH=%CLASSPATH%;.. Isto durará enquanto a janela do cmd estiver aberta.

 2
Author: Nenad Bulatovic, 2017-01-20 19:12:33

Você realmente precisa fazer isso a partir da pasta src. Aí você escreve a seguinte linha de comando:

[name of the package].[Class Name] [arguments]
Digamos que a tua turma se chama CommandLine.class, e o código é assim:
package com.tutorialspoint.java;

    /**
     * Created by mda21185 on 15-6-2016.
     */

    public class CommandLine {
        public static void main(String args[]){
            for(int i=0; i<args.length; i++){
                System.out.println("args[" + i + "]: " + args[i]);
            }
        }
    }

Então você deve cd para a pasta src e o comando que você precisa executar ficaria assim:

java com.tutorialspoint.java.CommandLine this is a command line 200 -100

E o resultado na linha de comando seria:

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
 2
Author: mdarmanin, 2017-01-20 19:17:26

No meu caso, eu tenho o erro porque eu tinha misturado nomes de pacotes em maiúsculas e minúsculas em um sistema Windows 7. Mudar os nomes dos pacotes para todos os casos menores resolveu o problema. Note também que neste cenário, eu não tenho nenhum erro compilando o .java file into A.ficheiro de classe; não iria correr da mesma pasta (sub-sub-sub -).

 2
Author: Howard007, 2017-12-26 19:55:15

Também enfrentei erros semelhantes ao testar uma ligação Java MongoDB JDBC. Eu acho que é bom resumir minha solução final em resumo para que no futuro qualquer um pode olhar diretamente para os dois comandos e são bons para prosseguir mais.

Assuma que está na pasta onde o seu ficheiro Java e dependências externas (ficheiros JAR) existem.

Compilar:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • - cp - argumento de claspath; passar todos os ficheiros jar dependentes um por um
  • *.java-Este é o arquivo de classe Java que tem o método principal. sdsd

Executar:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • por favor, observe o colon (Unix) / vírgula (Windows) depois de todos os ficheiros do JAR de dependência terminarem
  • no final, observe o nome da classe principal sem qualquer extensão (no .sala de aula .java)
 2
Author: khichar.anil, 2018-02-06 23:21:13
Tive uma estranha.

Erro: não foi possível encontrar ou carregar o 'mypackage' da classe principal.App

Descobri que tinha um pom (pai) configurado no pom do meu projecto.xml (pom do meu projecto.o xml apontava para um pom pai.xml) e o relativePath estava desligado / errado. Abaixo está uma parte do pom do meu projecto.xml
<parent>
    <groupId>myGroupId</groupId>
    <artifactId>pom-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../badPathHere/pom.xml</relativePath>
</parent> 
Uma vez resolvido o pom relativePath, o erro desapareceu. Vá-se lá saber.
 2
Author: granadaCoder, 2018-09-21 20:34:55

Em Java, quando você corre, às vezes, a JVM da linha de comando usando o executável java e está a tentar iniciar um programa a partir de um arquivo de classe com public static void main (PSVM), você pode executar o abaixo erro, mesmo que o classpath parâmetro para a JVM é preciso e o arquivo de classe está presente no classpath:

Error: main class not found or loaded

Isto acontece se o ficheiro da classe com o PSVM não puder ser carregado. Uma possível razão para isso é que a classe pode estar implementando uma interface ou estender outra classe que não está no classpath. Normalmente se uma classe não está no claspath, o erro jogado indica como tal. Mas, se a classe em uso é estendida ou implementada, java é incapaz de carregar a classe em si.

Referência: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/

 1
Author: Anandaraja Ravi, 2015-09-18 03:01:01