¿Qué significa “No se pudo encontrar o cargar la clase principal”?

Un problema común que experimentan los nuevos desarrolladores de Java es que sus progtwigs no se ejecutan con el mensaje de error: Could not find or load main class ...

¿Qué significa esto, qué lo causa y cómo se debe solucionar?

La syntax del comando java

En primer lugar, debe comprender la forma correcta de iniciar un progtwig utilizando el comando java (o javaw ).

La syntax normal 1 es esta:

  java [  

donde es una opción de línea de comando (comenzando con un carácter “-“), es un nombre de clase Java completamente calificado, y es un argumento de línea de comando arbitrario que se pasa a su aplicación.
1 – Hay una segunda syntax para los archivos JAR “ejecutables” que describiré en la parte inferior.

El nombre completo (FQN) para la clase se escribe convencionalmente como lo haría en el código fuente de Java; p.ej

  packagename.packagename2.packagename3.ClassName 

Sin embargo, algunas versiones del comando java permiten usar barras en lugar de puntos; p.ej

  packagename/packagename2/packagename3/ClassName 

que (confusamente) se parece a un nombre de ruta de archivo, pero no es uno. Tenga en cuenta que el término nombre completo es la terminología estándar de Java … no es algo que inventé para confundirlo 🙂

Aquí hay un ejemplo de cómo debe ser un comando de java :

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

Lo anterior hará que el comando java haga lo siguiente:

  1. Busque la versión comstackda de la clase com.acme.example.ListUsers .
  2. Carga la clase.
  3. Verifique que la clase tenga un método main con firma , tipo de retorno y modificadores dados por public static void main(String[]) . (Tenga en cuenta que el nombre del argumento del método NO es parte de la firma).
  4. Llame a ese método pasándole los argumentos de la línea de comando (“fred”, “joe”, “bert”) como String[] .

Razones por las cuales Java no puede encontrar la clase

Cuando aparece el mensaje “No se pudo encontrar o cargar la clase principal …”, eso significa que el primer paso ha fallado. El comando java no pudo encontrar la clase. Y, de hecho, el “…” en el mensaje será el nombre de clase totalmente calificado que java está buscando.

Entonces, ¿por qué no podría encontrar la clase?

Razón n. ° 1: cometió un error con el argumento nombre de clase

La primera causa probable es que haya proporcionado el nombre de clase incorrecto. (O … el nombre correcto de la clase, pero en el formulario incorrecto). Considerando el ejemplo anterior, aquí hay una variedad de maneras incorrectas de especificar el nombre de la clase:

  • Ejemplo # 1 – un nombre de clase simple:

     java ListUser 

    Cuando la clase se declara en un paquete como com.acme.example , debe usar el nombre de clase completo, incluido el nombre del paquete en el comando java ; p.ej

     java com.acme.example.ListUser 
  • Ejemplo # 2 – un nombre de archivo o ruta en lugar de un nombre de clase:

     java ListUser.class java com/acme/example/ListUser.class 
  • Ejemplo # 3 – un nombre de clase con la carcasa incorrecta:

     java com.acme.example.listuser 
  • Ejemplo n. ° 4: un error tipográfico

     java com.acme.example.mistuser 
  • Ejemplo # 5 – un nombre de archivo fuente

     java ListUser.java 
  • Ejemplo n. ° 6: olvidó por completo el nombre de la clase

     java lots of arguments 

Motivo n. ° 2: el classpath de la aplicación está incorrectamente especificado

La segunda causa probable es que el nombre de la clase sea correcto, pero que el comando java no pueda encontrar la clase. Para entender esto, necesitas entender el concepto de “classpath”. Esto se explica bien por la documentación de Oracle:

  • La documentación del comando java
  • Configurando el Classpath .
  • El tutorial de Java: RUTA y CLASSPATH

Entonces … si ha especificado el nombre de la clase correctamente, lo siguiente que debe verificar es que haya especificado la ruta de clase correctamente:

  1. Lea los tres documentos vinculados anteriormente. (Sí … LÉALOS. Es importante que un progtwigdor de Java comprenda al menos los conceptos básicos de cómo funcionan los mecanismos de la ruta de clase de Java).
  2. Observe la línea de comando y / o la variable de entorno CLASSPATH que está en vigencia cuando ejecuta el comando java . Verifique que los nombres de los directorios y los archivos JAR sean correctos.
  3. Si hay rutas de acceso relativas en el classpath, verifique que se resuelvan correctamente … desde el directorio actual que está en vigencia cuando ejecuta el comando java .
  4. Verifique que la clase (mencionada en el mensaje de error) pueda ubicarse en el classpath efectivo .
  5. Tenga en cuenta que la syntax classpath es diferente para Windows en comparación con Linux y Mac OS. (El separador classpath es ; en Windows y : en los demás)

Razón # 2a – el directorio incorrecto está en el classpath

Cuando coloca un directorio en la ruta de clase, teóricamente corresponde a la raíz del espacio de nombre calificado. Las clases se ubican en la estructura del directorio debajo de esa raíz, asignando el nombre completo a un nombre de ruta . Entonces, por ejemplo, si “/ usr / local / acme / classes” está en la ruta de clase, cuando la JVM busca una clase llamada com.acme.example.Foon , buscará un archivo “.class” con este nombre de ruta:

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

Si hubiera puesto “/ usr / local / acme / classes / com / acme / example” en classpath, entonces la JVM no podría encontrar la clase.

Motivo # 2b: la ruta del subdirectorio no coincide con FQN

Si sus clases FQN es com.acme.example.Foon , entonces la JVM buscará “Foon.class” en el directorio “com / acme / example”:

  • Si la estructura de su directorio no coincide con el nombre del paquete según el patrón anterior, la JVM no encontrará su clase.

  • Si intenta cambiar el nombre de una clase moviéndola, también fallará … pero la stack de excepción será diferente.

Para dar un ejemplo concreto, supongamos que:

  • quieres ejecutar com.acme.example.Foon class,
  • la ruta completa del archivo es /usr/local/acme/classes/com/acme/example/Foon.class ,
  • su directorio de trabajo actual es /usr/local/acme/classes/com/acme/example/ ,

entonces:

 # 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:

  • La opción -classpath se puede acortar a -cp en la mayoría de las versiones de Java. Verifique las entradas manuales respectivas para java , javac , etc.
  • Piense detenidamente al elegir entre rutas de acceso absolutas y relativas en classpaths. Recuerde que una ruta de acceso relativa puede “romperse” si el directorio actual cambia.

Razón # 2c – dependencias que faltan en el classpath

El classpath necesita incluir todas las otras clases (no del sistema) de las que depende su aplicación. (Las clases del sistema se ubican automáticamente, y rara vez necesita preocuparse por esto). Para que la clase principal se cargue correctamente, la JVM necesita encontrar:

  • la clase en si.
  • todas las clases e interfaces en la jerarquía de superclase (p. ej., vea que la clase Java está presente en classpath, pero el inicio falla con Error: no se pudo encontrar o cargar la clase principal )
  • todas las clases e interfaces a las que se hace referencia mediante declaraciones de variables o variables, o expresiones de métodos o de acceso a campos.

(Nota: las especificaciones JLS y JVM permiten que una JVM cargue las clases “de forma perezosa”, y esto puede afectar cuando se lanza una excepción de cargador de clases).

Motivo n. ° 3: la clase ha sido declarada en el paquete incorrecto

Ocurre ocasionalmente que alguien coloca un archivo de código fuente en la carpeta incorrecta en su árbol de código fuente, o dejan de lado la statement del package . Si haces esto en un IDE, el comstackdor del IDE te informará sobre esto de inmediato. De manera similar, si usa una herramienta de construcción Java decente, la herramienta ejecutará javac de una manera que detectará el problema. Sin embargo, si construye su código Java a mano, puede hacerlo de tal manera que el comstackdor no advierta el problema, y ​​el archivo “.class” resultante no se encuentre en el lugar que usted espera.

Todavía no puede encontrar el problema?

Hay muchas cosas que revisar, y es fácil perderse algo. Intente agregar la opción -Xdiag a la línea de comandos de java (como lo primero después de java ). Emitirá varias cosas sobre la carga de clases, y esto puede ofrecerte pistas sobre cuál es el verdadero problema.


La java -jar

La syntax alternativa utilizada para los archivos JAR “ejecutables” es la siguiente:

  java [  

p.ej

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

En este caso, el nombre de la clase de punto de entrada (es decir, com.acme.example.ListUser ) y classpath se especifican en MANIFEST del archivo JAR.


IDEs

Un IDE típico de Java tiene soporte para ejecutar aplicaciones Java en la propia JVM IDE o en una JVM secundaria. Estos son generalmente inmunes a esta excepción en particular, porque el IDE usa sus propios mecanismos para construir el classpath en tiempo de ejecución, identifica la clase principal y crea la línea de comando java .

Sin embargo, todavía es posible que se produzca esta excepción, si hace cosas detrás de la parte posterior del IDE. Por ejemplo, si previamente ha configurado un Lanzador de aplicaciones para su aplicación Java en Eclipse, y luego movió el archivo JAR que contiene la clase “principal” a un lugar diferente en el sistema de archivos sin decirle a Eclipse , Eclipse lanzaría involuntariamente la JVM con un classpath incorrecto

En resumen, si obtiene este problema en un IDE, compruebe si hay estado IDE obsoleto, referencias de proyecto rotas o configuraciones de iniciador rotas.

También es posible que un IDE simplemente se confunda. Los IDE son piezas de software enormemente complejas que comprenden muchas partes que interactúan. Muchas de estas partes adoptan diversas estrategias de almacenamiento en caché para hacer que el IDE en su conjunto responda. En ocasiones, esto puede ir mal, y un posible síntoma son los problemas al iniciar aplicaciones. Si sospecha que esto podría estar pasando, vale la pena reiniciar su IDE.


Otras referencias

  • De los tutoriales de Oracle Java: problemas comunes (y sus soluciones)

Si el nombre de su código fuente es HelloWorld.java, su código comstackdo será HelloWorld.class .

Obtendrá ese error si lo llama usando:

 java HelloWorld.class 

En cambio, usa esto:

 java HelloWorld 

Si sus clases están en paquetes, entonces debe cd un cd al directorio principal y ejecutar usando el nombre completo de la clase (packageName.MainClassName).

Ejemplo:

Mis clases están aquí:

 D:\project\com\cse\ 

El nombre completo de mi clase principal es:

 com.cse.Main 

Así que volví al directorio principal:

 D:\project 

Luego emita el comando java :

 java com.cse.Main 

Si su método principal está en la clase en un paquete, debe ejecutarlo sobre el directorio jerárquico.

Supongamos que hay un archivo de código fuente (Main.java):

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

Para ejecutar este código, debe colocar Main.Class en el paquete como directorio ./com/test/Main.Java . Y en el directorio raíz, use java com.test.Main .

Cuando el mismo código funciona en una PC, pero muestra el error en otra, la mejor solución que he encontrado es la siguiente:

 javac HelloWorld.java java -cp . HelloWorld 

Lo que me ayudó fue especificar el classpath en la línea de comando, por ejemplo:

  1. Crea una nueva carpeta, C:\temp

  2. Crea el archivo Temp.java en C:\temp , con la siguiente clase:

     public class Temp { public static void main(String args[]) { System.out.println(args[0]); } } 
  3. Abra una línea de comando en la carpeta C:\temp y escriba el siguiente comando para comstackr la clase Temp:

     javac Temp.java 
  4. Ejecute la clase Java comstackda, agregando la opción -classpath para que JRE sepa dónde encontrar la clase:

     java -classpath C:\temp Temp Hello! 

De acuerdo con el mensaje de error (“No se pudo encontrar o cargar la clase principal”), hay dos categorías de problemas:

  1. La clase principal no pudo ser encontrada
  2. No se pudo cargar la clase principal (este caso no se discute completamente en la respuesta aceptada)

No se pudo encontrar la clase principal cuando hay un error tipográfico o una syntax incorrecta en el nombre de clase completo o no existe en el classpath proporcionado .

La clase principal no se pudo cargar cuando no se puede iniciar la clase, por lo general, la clase principal amplía otra clase y esa clase no existe en el classpath proporcionado.

Por ejemplo:

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

Si camel-spring no está incluido, este error será informado.

A veces, lo que podría estar causando el problema no tiene nada que ver con la clase principal, y tuve que descubrirlo de la manera difícil. Era una biblioteca referenciada que moví, y me dio el:

No se pudo encontrar o cargar la clase principal xxx Linux

Acabo de eliminar esa referencia, la agregué nuevamente y funcionó bien de nuevo.

Tuve un error en este caso:

 java -cp lib.jar com.mypackage.Main 

Funciona con ; para Windows y : para Unix:

 java -cp lib.jar; com.mypackage.Main 

Use este comando:

 java -cp . [PACKAGE.]CLASSNAME 

Ejemplo: si su nombre de clase es Hello.class creado a partir de Hello.java, utilice el siguiente comando:

 java -cp . Hello 

Si su archivo Hello.java está dentro del paquete com.demo, utilice el siguiente comando

 java -cp . com.demo.Hello 

Con JDK 8 muchas veces ocurre que el archivo de clase está presente en la misma carpeta, pero el comando java espera classpath y por esta razón agregamos -cp . tomar la carpeta actual como referencia para classpath.

Prueba -Xdiag .

La respuesta de Steve C cubre muy bien los casos posibles, pero a veces para determinar si la clase no pudo ser encontrada o cargada podría no ser tan fácil. Use java -Xdiag (desde JDK 7). Esto imprime una buena stacktrace que proporciona una pista de lo que significa que el mensaje Could not find or load main class mensaje de Could not find or load main class .

Por ejemplo, puede indicarle otras clases utilizadas por la clase principal que no se pudieron encontrar e impedir que se cargue la clase principal.

En este caso, tienes:

No se pudo encontrar o cargar la clase principal ? Classpath

Es porque está utilizando “classpath”, pero el tablero no es el mismo guión utilizado por java en el símbolo del sistema. Tuve este problema copiando y pegando desde el Bloc de notas a cmd.

Esto podría ayudarlo si su caso es específicamente como el mío: como principiante también encontré este problema cuando traté de ejecutar un progtwig Java.

Lo compilé así:

 javac HelloWorld.java 

Y traté de ejecutar también con la misma extensión:

 java Helloworld.java 

Cuando .java y reescribí el comando como java HelloWorld , el progtwig funcionó perfectamente. 🙂

En mi caso, apareció un error porque había proporcionado el nombre del archivo fuente en lugar del nombre de la clase.

Necesitamos proporcionar el nombre de la clase que contiene el método principal al intérprete.

Si usa Maven para comstackr el archivo JAR, asegúrese de especificar la clase principal en el archivo pom.xml:

    maven-jar-plugin    class name us.com.test.abc.MyMainClass       

enter image description here

Ubicación del archivo de clase: C: \ test \ com \ company

Nombre de archivo: Main.class

Nombre de clase totalmente calificado: com.company.Main

Comando de línea de comando:

 java -classpath "C:\test" com.company.Main 

Tenga en cuenta que la ruta de clase NO incluye \ com \ company

Pasé una buena cantidad de tiempo tratando de resolver este problema. Pensé que de alguna manera estaba configurando mi classpath incorrectamente, pero el problema fue que escribí:

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

en lugar de:

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

Pensé que el significado de totalmente calificado significaba incluir el nombre completo de la ruta en lugar del nombre completo del paquete.

Primero establece la ruta usando este comando;

 set path="paste the set path address" 

Entonces necesitas cargar el progtwig. Escriba “cd (nombre de la carpeta)” en la unidad almacenada y compílelo. Por ejemplo, si mi progtwig está almacenado en la unidad D, escriba “D:”, presione intro y escriba “cd (nombre de la carpeta)”.

Este es un caso específico, pero como llegué a esta página buscando una solución y no la encontré, la agregaré aquí.

Windows (probado con 7) no acepta caracteres especiales (como á ) en los nombres de clase y paquete. Linux lo hace, sin embargo.

Descubrí esto cuando construí un .jar en NetBeans e intenté ejecutarlo en línea de comandos. Funcionó en NetBeans pero no en la línea de comando.

Lo que solucionó el problema en mi caso fue:

Haga clic derecho en el proyecto / clase que desea ejecutar, luego Run As -> Run Configurations . Luego, debe corregir su configuración existente o agregar nueva de la siguiente manera:

abra la pestaña Classpath , haga clic en el botón Advanced... luego agregue la carpeta bin de su proyecto.

En Windows puesto .; al valor CLASSPATH al principio.

Los . (punto) significa “buscar en el directorio actual”. Esta es una solución permanente.

También puede configurarlo “una vez” con establecer CLASSPATH=%CLASSPATH%;. . Esto durará mientras tu ventana de cmd esté abierta.

Todas las respuestas aquí están dirigidas a los usuarios de Windows, parece. Para Mac, el separador classpath es : not ; . Como un error que establece el classpath usando ; no se lanza, entonces esto puede ser difícil de descubrir si viene de Windows a Mac.

Aquí está el comando Mac correspondiente:

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

En este ejemplo, el paquete es com.test y también se debe incluir una carpeta lib en classpath.

Al ejecutar java con la opción -cp tal como se anuncia en Windows PowerShell, es posible que aparezca un error parecido a este:

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

Para que PowerShell acepte el comando, los argumentos de la opción -cp deben estar entre comillas como en:

 java -cp 'someDependency.jar;.' ClassName 

Formar el comando de esta manera debería permitirle a Java procesar los argumentos de la ruta de clase correctamente.

Sometimes, in some online compilers that you might have tried you will get this error if you don’t write public class [Classname] but just class [Classname] .

In Java, when you sometimes run the JVM from the command line using the java executable and are trying to start a program from a class file with public static void main (PSVM), you might run into the below error even though the classpath parameter to the JVM is accurate and the class file is present on the classpath:

 Error: main class not found or loaded 

This happens if the class file with PSVM could not be loaded. One possible reason for that is that the class may be implementing an interface or extending another class that is not on the classpath. Normally if a class is not on the classpath, the error thrown indicates as such. But, if the class in use is extended or implemented, java is unable to load the class itself.

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

I got this error after doing mvn eclipse:eclipse This messed up my .classpath file a little bit.

Had to change the lines in .classpath from

   

a

   

You really need to do this from the src folder. There you type the following command line:

 [name of the package].[Class Name] [arguments] 

Let’s say your class is called CommandLine.class , and the code looks like this:

 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 

Then you should cd to the src folder and the command you need to run would look like this:

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

And the output on the command line would be:

 args[0]: this args[1]: is args[2]: a args[3]: command args[4]: line args[5]: 200 args[6]: -100 

In my case, I got the error because I had mixed UPPER- and lower-case package names on a Windows 7 system. Changing the package names to all lower case resolved the issue. Note also that in this scenario, I got no error compiling the .java file into a .class file; it just wouldn’t run from the same (sub-sub-sub-) directory.

I also faced similar errors while testing a Java MongoDB JDBC connection. I think it’s good to summarize my final solution in short so that in the future anybody can directly look into the two commands and are good to proceed further.

Assume you are in the directory where your Java file and external dependencies (JAR files) exist.

Compile:

 javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java 
  • -cp – classpath argument; pass all the dependent JAR files one by one
  • *.java – This is the Java class file which has main method. sdsd

Run:

 java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection 
  • Please do observe the colon (Unix) / comma (Windows) after all the dependency JAR files end
  • At the end, observe the main class name without any extension (no .class or .java)

In the context of IDE development (Eclipse, NetBeans or whatever) you have to configure your project properties to have a main class, so that your IDE knows where the main class is located to be executed when you hit “Play”.

  1. Right click your project, then Properties
  2. Go to the Run category and select your Main Class
  3. Hit the Run button.

Ingrese la descripción de la imagen aquí