¿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 programas no se ejecutan con el mensaje de error: Could not find or load main class ...

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

preguntado el 07 de agosto de 13 a las 04:08

Tenga en cuenta que esta es una pregunta de "auto-respuesta" que pretende ser una pregunta y respuesta de referencia genérica para los nuevos usuarios de Java. No pude encontrar una pregunta y respuesta existente que cubra esto adecuadamente (OMI). -

para mí, sucedió en un proyecto que funcionó antes ... así que lo arreglo con "reconstruir proyecto" -

@Vladi- "También es posible que un IDE simplemente se confunda. Los IDE son piezas de software enormemente complicadas que comprenden muchas partes que interactúan. Muchas de estas partes adoptan varias estrategias de almacenamiento en caché para que el IDE responda en su conjunto. A veces, esto puede salir mal, y un posible síntoma son problemas al iniciar aplicaciones.Si sospecha que esto podría estar sucediendo, vale la pena probar otras cosas como reiniciar su IDE, reconstruir el proyecto etcétera." -

30 Respuestas

LA java <class-name> sintaxis de comandos

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

La sintaxis habitual1 es la siguiente:

    java [ <options> ] <class-name> [<arg> ...]

donde <option> es una opción de línea de comando (que comienza con un carácter "-"), <class-name> es un nombre de clase Java completamente calificado, y <arg> es un argumento de línea de comando arbitrario que se pasa a su aplicación.


1 - Hay algunas otras sintaxis que se describen cerca del final de esta respuesta.

El nombre totalmente calificado (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 java comando le permite usar barras en lugar de puntos; p.ej

    packagename/packagename2/packagename3/ClassName

que (confusamente) parece una ruta de archivo, pero no lo es. Nótese que el término nombre completo es terminología estándar de Java... no es algo que inventé para confundirte :-)

He aquí un ejemplo de lo que es un java el comando debería verse así:

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

Lo anterior va a provocar que java comando para hacer lo siguiente:

  1. Busque la versión compilada del com.acme.example.ListUsers clase.
  2. Carga la clase.
  3. Compruebe que la clase tiene un main método con firma, tipo de retorno e modificadores dada por public static void main(String[]). (Nota, el nombre del argumento del método es NO parte de la firma).
  4. Llame a ese método pasándole los argumentos de la línea de comando ("fred", "joe", "bert") como un String[].

Razones por las que Java no puede encontrar la clase

Cuando recibe el mensaje "No se pudo encontrar o cargar la clase principal...", eso significa que el primer paso ha fallado. los java El comando no pudo encontrar la clase. Y de hecho, el "..." en el mensaje será el nombre de clase completamente calificado esta java está buscando.

Entonces, ¿por qué podría ser incapaz de encontrar la clase?

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

La primera causa probable es que haya proporcionado el nombre de clase incorrecto. (O... el nombre de clase correcto, pero en la forma incorrecta). Teniendo en cuenta el ejemplo anterior, aquí hay una variedad de maneras equivocadas para 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, entonces debe usar el nombre de clase completo incluso el nombre del paquete en el java mando; p.ej

    java com.acme.example.ListUser
    
  • Ejemplo n.º 2: un nombre de archivo o ruta de acceso en lugar de un nombre de clase:

    java ListUser.class
    java com/acme/example/ListUser.class
    
  • Ejemplo #3 - un nombre de clase con mayúsculas y minúsculas incorrectas:

    java com.acme.example.listuser
    
  • Ejemplo #4 - un error tipográfico

    java com.acme.example.mistuser
    
  • Ejemplo n.º 5: un nombre de archivo de origen (excepto para Java 11 o posterior; consulte a continuación)

    java ListUser.java
    
  • Ejemplo #6: olvidaste el nombre de la clase por completo

    java lots of arguments
    

Razón n.° 2: la ruta de clase de la aplicación se especificó incorrectamente

La segunda causa probable es que el nombre de la clase sea correcto, pero que el java El comando no puede encontrar la clase. Para comprender esto, debe comprender el concepto de "ruta de clases". esto se explica bien por la documentación de Oracle:

Entonces... si ha especificado correctamente el nombre de la clase, lo siguiente que debe comprobar es que ha especificado correctamente el classpath:

  1. Lea los tres documentos vinculados anteriormente. (Sí... LÉALOS! Es importante que un programador Java entiende al menos los conceptos básicos de cómo funcionan los mecanismos de classpath de Java).
  2. Mire la línea de comando y/o la variable de entorno CLASSPATH que está en efecto cuando ejecuta el java dominio. Compruebe que los nombres de los directorios y los nombres de los archivos JAR sean correctos.
  3. Si hay relativo nombres de ruta en el classpath, verifique que se resuelvan correctamente ... desde el directorio actual que está en vigencia cuando ejecuta el java mando.
  4. Verifique que la clase (mencionada en el mensaje de error) se pueda ubicar en el eficaz ruta de clase.
  5. Tenga en cuenta que la sintaxis de classpath es una experiencia diferente para Windows frente a Linux y Mac OS. (El separador classpath es ; en Windows y : sobre los otros Si usa el separador incorrecto para su plataforma, no recibirá un mensaje de error explícito. En su lugar, obtendrá un archivo o directorio inexistente en la ruta que se ignorará en silencio).

Motivo #2a: el directorio incorrecto está en el classpath

Cuando coloca un directorio en el classpath, teóricamente corresponde a la raíz del espacio de nombres calificado. Las clases se encuentran en la estructura de directorios 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, entonces 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 el classpath, entonces la JVM no podría encontrar la clase.

Razón #2b: la ruta del subdirectorio no coincide con el 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 intentas rebautizar una clase al moverla, eso también fallará... pero la excepción stacktrace será diferente. Es probable que diga algo como esto:

    Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
    

    porque el FQN en el archivo de clase no coincide con lo que el cargador de clases espera encontrar.

Por poner un ejemplo concreto, suponiendo que:

  • quieres correr com.acme.example.Foon clase,
  • 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 -classpath La opción se puede acortar a -cp en la mayoría de las versiones de Java. Compruebe las entradas manuales respectivas para java, javac y así sucesivamente.
  • Piense con cuidado al elegir entre nombres de ruta absolutos y relativos en classpaths. Recuerde que un nombre de ruta relativo puede "romperse" si cambia el directorio actual.

Motivo n.° 2c: faltan dependencias en el classpath

El classpath necesita incluir todos los otros 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 debe encontrar:

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

Razón #3: la clase ha sido declarada en el paquete incorrecto

Ocasionalmente sucede que alguien coloca un archivo de código fuente en la carpeta incorrecta en su árbol de código fuente, o deja de lado el package declaración. Si hace esto en un IDE, el compilador del IDE le informará sobre esto inmediatamente. De manera similar, si usa una herramienta de compilación Java decente, la herramienta se 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 compilador no note el problema y el archivo ".class" resultante no esté en el lugar que esperaba.

¿Aún no encuentras el problema?

Hay un montón de cosas para comprobar, y es fácil pasar por alto algo. Intenta agregar el -Xdiag opción a la java línea de comando (como lo primero después de java). Mostrará varias cosas sobre la carga de clases, y esto puede ofrecerle pistas sobre cuál es el problema real.

Además, considere los posibles problemas causados ​​por copiar y pegar caracteres invisibles o no ASCII de sitios web, documentos, etc. Y considere los "homoglifos", donde dos letras o símbolos se ven iguales... pero no lo son.

Puede encontrarse con este problema si tiene firmas no válidas o incorrectas en META-INF/*.SF. Puede intentar abrir el .jar en su editor ZIP favorito y eliminar archivos de META-INF hasta que todo lo que tienes es tu MANIFEST.MF. Sin embargo, esto NO SE RECOMIENDA en general. (La firma no válida puede ser el resultado de que alguien haya inyectado malware en el archivo JAR original firmado. Si borra la firma no válida, ¡está infectando su aplicación con el malware!) El enfoque recomendado es obtener archivos JAR con archivos JAR válidos. firmas, o reconstruirlas a partir del código fuente original (auténtico).

Finalmente, aparentemente puede encontrarse con este problema si hay un error de sintaxis en el MANIFEST.MF archivo (ver https://stackoverflow.com/a/67145190/139985).


Sintaxis alternativas para java

Hay tres sintaxis alternativas para el lanzamiento de programas Java usando el java command.

  1. La sintaxis utilizada para iniciar un archivo JAR "ejecutable" es la siguiente:

    java [ <options> ] -jar <jar-file-name> [<arg> ...]
    

    p.ej

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

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

  2. La sintaxis para iniciar una aplicación desde un módulo (Java 9 y posterior) es la siguiente:

    java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
    

    El nombre de la clase de punto de entrada está definido por el <module> sí mismo, o está dado por el opcional <mainclass>.

  3. Desde Java 11 en adelante, puede usar el java comando para compilar y ejecutar un solo archivo de código fuente usando la siguiente sintaxis:

    java [ <options> ] <sourcefile> [<arg> ...]
    

    donde <sourcefile> es (típicamente) un archivo con el sufijo ".java".

Para obtener más detalles, consulte la documentación oficial de la java comando para la versión de Java que está utilizando.


IDEs

Un IDE de Java típico tiene soporte para ejecutar aplicaciones Java en el propio IDE JVM o en un JVM secundario. Estos son en general inmune a esta excepción en particular, porque el IDE usa sus propios mecanismos para construir el classpath en tiempo de ejecución, identificar la clase principal y crear el java línea de comando.

Sin embargo, todavía es posible que ocurra esta excepción, si hace las cosas a espaldas del IDE. Por ejemplo, si previamente configuró 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, sin darse cuenta, lanzaría la JVM con una ruta de clase incorrecta.

En resumen, si tiene este problema en un IDE, verifique cosas como el estado obsoleto del IDE, referencias de proyectos rotas o configuraciones de iniciador rotas.

También es posible que un IDE simplemente se confunda. Los IDE son piezas de software enormemente complicadas que comprenden muchas partes que interactúan. Muchas de estas partes adoptan varias estrategias de almacenamiento en caché para que el IDE responda en su conjunto. A veces, estos pueden salir mal, y un posible síntoma son los problemas al iniciar aplicaciones. Si sospecha que esto podría estar sucediendo, vale la pena probar otras cosas como reiniciar su IDE, reconstruir el proyecto, etc.


Otras referencias

respondido 28 nov., 21:03

Tuve este problema cuando intentaba ejecutar una clase con una biblioteca de terceros. Invoqué Java así: java -cp ../third-party-library.jar com.my.package.MyClass; esto no funciona, sino que también es necesario agregar la carpeta local a la ruta de clase (separada por :, Así: java -cp ../third-party-library.jar:. com.my.package.MyClass, entonces debería funcionar - lanoxx

Después de años de programación en Java, aún logré terminar en esta página. Para mi el problema era que la sintaxis de classpath depende del sistema operativo. Soy un poco nuevo en la programación en Windows y no tenía ni idea. - Keyser

Notas adicionales, punto 2 ¡sálvame! Es triste ver eso java no dice que no encuentra una clase importada, sino la clase principal que está intentando ejecutar. Esto es engañoso, aunque estoy seguro de que hay una razón para ello. Tuve el caso donde java sabía exactamente dónde está mi clase, sin embargo, no pudo encontrar una de las clases importadas. En lugar de decir eso, se quejó de no encontrar mi clase principal. Realmente, molesto. - MSX

Tuve este problema dos veces en Eclipse. La primera vez que la firma de main() fue incorrecta. La segunda vez que cambié el nombre de un .jar, y aunque agregué el nuevo a la ruta de compilación, Eclipse no encontró el anterior, por lo que el proyecto no se compiló, con este error. Tuve que eliminar el archivo .jar de Proyecto > Propiedades > Ruta de compilación de Java > Bibliotecas. - gregt

Lo he encontrado por tercera vez. Ejecuté el programa desde un archivo por lotes de Windows 10 y puse el nombre .jar en una variable (llamada con "-cp %jarname%;lib*"). Por error, puse un espacio adicional al final del nombre del jar, y eso provocó el error. Truco de sombrero :) - gregt

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

Obtendrá ese error si lo llama usando:

java HelloWorld.class

En su lugar, usa esto:

java HelloWorld

Respondido el 04 de Septiembre de 17 a las 15:09

El problema es que esta solución solo funciona para las clases de Java declaradas en el paquete predeterminado sin dependencias de archivos JAR. (E incluso entonces, no todo el tiempo.) La mayoría de los programas Java no son tan simples. - Stephen C

como dijo Stephen, esto solo funciona con el "paquete predeterminado", lo que significa no declaración del paquete en la parte superior del archivo. Para una prueba rápida de algún código, hice: javac TestCode.java seguido por java TestCode - Alguien en alguna parte

Esto no funcionó para mí. Todavía dice: "No se pudo encontrar o cargar la clase principal HelloWorld" - Jim

necesitaba hacer java -classpath . HelloWorld - principe chris

@ChrisPrince - Sí... eso funciona... a veces. Para comprender cuándo funciona y cuándo no, lea la respuesta más votada. - Stephen C

Si tus clases son en paquetes entonces tienes que cd al directorio raíz de su proyecto y ejecútelo usando el nombre completo de la clase (packageName.MainClassName).

Ejemplo:

Mis clases son aquí:

D:\project\com\cse\

El nombre completo de mi clase principal es:

com.cse.Main

Así que cd volver al directorio raíz del proyecto:

D:\project

Entonces emite el java mando:

java com.cse.Main

Esta respuesta es para rescatar a los programadores de Java novatos de la frustración causada por un error común. Le recomiendo que lea la respuesta aceptada para obtener un conocimiento más profundo sobre el classpath de Java.

Respondido 02 Feb 22, 19:02

Esta respuesta hace una gran cantidad de suposiciones. Y hay otras maneras de lograr esto. En lugar de seguir ciegamente los consejos anteriores, recomendaría que las personas se tomen el tiempo de leer los enlaces en mi Respuesta que explican cómo funciona el classpath de Java. Es mejor ENTENDER lo que estás haciendo... - Stephen C

Esta respuesta hace las suposiciones exactas que necesitaba :) Estaba ubicado en el directorio del archivo .class y java.exe no funcionaba. Una vez que cd-ed arriba y ejecuté con el nombre del paquete incluido en la línea de comando, funcionó. - Nick Constantino

Estoy de acuerdo con Nick Constantine. Igual aquí. Fue un ejemplo exacto que siguió los pasos que hice, y también funcionó para mí. El manejo de classpath de Java tiene cierta lógica, pero estoy seguro de que no lo habría diseñado de esa manera. - Tihamer

Gracias, tu respuesta me ayuda a ver que usé Main con Mayúsculas _! - Hernaldo González

Estoy escribiendo este comentario después de probar esto, pero no funcionó. Tengo un proyecto llamado Helloworld que consta solo de 1 archivo java, Helloworld/src/com/firstpackage/Test.java (idea de Windows 10. Intellij). Yo no tengo la variable ambiental CLASSPATH, quiero establecer classpath específicamente para este proyecto. correr java com.firstpackage.Test dentro del directorio Helloworld no funciona y tampoco el comando java -classpath C:\Users\matuagkeetarp\IdeaProjects\Helloworld\src\com\first‌​package Test.java establecer la variable classpath. ¿Puede usted ayudar? - Prateek Gautam

Con la palabra clave 'paquete'

Si usted tiene una package palabra clave en su código fuente (la clase principal se define en un paquete), debe ejecutarlo sobre el directorio jerárquico, usando el nombre completo de la clase (packageName.MainClassName).

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

C:\Usuarios\espacio de trabajo\testapp\com\test\Main.Java

Luego cambie el directorio actual de la terminal al directorio raíz del proyecto:

cd C:\Users\workspace\testapp

Y finalmente, ejecuta el código:

java com.test.Main

Sin palabra clave 'paquete'

Si no tiene ningún paquete en su nombre de código fuente, tal vez esté equivocado con el comando incorrecto. Suponga que su nombre de archivo Java es Main.java, después de compilar:

javac Main.java

su código compilado será Main.class

Obtendrá ese error si lo llama usando:

java Main.class

En su lugar, usa esto:

java Main

Respondido 03 Feb 22, 09:02

Consulte las "Notas adicionales n. ° 1" de mi respuesta. Para una mejor explicación de este problema. - Stephen C

@StephenC Sí, su respuesta es más completa (y, por supuesto, +1), pero esta respuesta en particular tenía la palabra "paquete", lo que me permitió encontrar lo que necesitaba rápidamente. Y funcionó. Así que +1 Razavi. StephenC, el tuyo carece del ejemplo de paquete simple que necesitaba ya que soy nuevo en Java. - kmort

Este era exactamente mi problema. He estado leyendo toneladas de documentos de Java y este ejemplo concreto es lo que necesitaba: Juan

Sí, el ejemplo concreto es bueno, esto funcionó perfectamente. Estoy seguro de que la respuesta principal es muy completa, pero fue difícil ver el árbol por el bosque. Buen día @Razavi - usuario1300214

¡Me gusta esta respuesta más corta y útil en lugar de la aceptada! - Mohsen

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

javac HelloWorld.java
java -cp . HelloWorld

Respondido el 14 de enero de 17 a las 16:01

Esta no es una buena recomendación. Depende de que la variable de entorno CLASSPATH no esté configurada o tenga un valor que sea consistente con ".". Sí, funciona en muchos casos, pero no en otros. - Stephen C

Bueno, ciertamente javac -classpath . HelloWorld.java hubiera funcionado! Y esa es una mejor solución en su caso. - Stephen C

Si tiene 'package com.some.address' como primera línea, esto no funcionará. Deberá comentar la 'dirección del paquete' .. - Joe

@Joe: ese truco (comentar el paquete) funcionará (en algunos casos), pero es una mala idea. Una mejor idea es aprender/comprender qué causó el problema e implementar la solución correcta. - Stephen C

desarmar la variable classpath básicamente funcionó para mí. - Amila Weerasinghe

Me ayudó especificar el classpath en la línea de comando. Por ejemplo:

  1. Crear una nueva carpeta, C:\temp

  2. Crear archivo Temp.java en C:\temp, con la siguiente clase en él:

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

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

     java -classpath C:\temp Temp Hello!
    

Respondido 02 Feb 22, 18:02

En Ubuntu, también tuve que especificar la ruta. No entiendo por qué no puede usar el Directorio de trabajo actual de forma predeterminada. ¡Estoy convencido de que Java está patrocinado por fabricantes de teclados! - pasado

@gone - La razón por la que "." no está en $PATH por defecto es que es una trampa de seguridad. seas.upenn.edu/cets/answers/dot-path.html - Stephen C

Muchas gracias por esto ... aunque no estoy seguro de por qué Java no pudo encontrar el classpath incluso después de configurarlo en las variables de entorno. - akash89

@ akash89 - Las razones más probables fueron: 1) java no estaba mirando $CLASSPATH (porque usó -classpath o -jar) o 2) la configuración de classpath no se estableció en el entorno que no era en vigor en el contexto que java fue corrido; por ejemplo, porque no "obtuvo" el archivo donde agregó los comandos setenv en el shell correcto. - Stephen C

Todavía tengo Error: no se pudo encontrar o cargar la clase principal Temp, ¿alguien podría ayudarme? - Alaa Jabre

Según 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 encontrado
  2. La clase Principal no pudo ser cargado (este caso no se discute completamente en la respuesta aceptada)

La clase Principal no pudo ser encontrado cuando hay un error tipográfico o sintaxis incorrecta en el nombre de clase completo o eso no existe en el classpath proporcionado.

La clase Principal no pudo ser cargado cuando no se puede iniciar la clase. Normalmente, 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 no se incluye el resorte de camello, se informará de este error.

Respondido 02 Feb 22, 18:02

"Básicamente" también hay muchas otras categorías. Y el problema de la superclase faltante es un subcaso muy inusual. (Tan inusual que nunca lo he visto ... en las preguntas formuladas en este sitio). - Stephen C

Hay DOS porque el error dice "No se pudo ENCONTRAR o CARGAR la clase principal". Si hay otras categorías, por favor avíseme. Lo he visto, así que solo quiero compartirlo aquí, tal vez alguien más lo necesite. - A los desarrolladores les encanta ZenUML

Lo habría revisado a algo como "Debe incluir todas las clases que se requieren para iniciar la clase principal para evitar este error en particular". No estoy tratando de convencerte. Es sólo una forma que me gustaría ver. Dejé la respuesta aquí solo para las personas a las que les gustaría leer las cosas de esta manera. No extiendamos más esta discusión :) Cambié mi declaración a "no discutido completamente en la respuesta aceptada" y espero que se sienta mejor. - A los desarrolladores les encanta ZenUML

Esta información es crucial y merece una mención explícita (esta es la única respuesta que menciona extends). Acabo de aprender por las malas que cuando la clase principal falla carga porque extiende otra que no pudo ser encontrado, Java no informa qué clase real no se encontró (diferente a NoClassDefFoundError). Así que sí sucede, y es una situación que tira de los pelos cuando no sabes esto. - Hugo M.

En esta situación, ¿hay alguna forma de saber exactamente qué clase de dependencia no se carga? - Carlos A.Ibarra

Utilice este comando:

java -cp . [PACKAGE.]CLASSNAME

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

java -cp . Hello

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

java -cp . com.demo.Hello

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

Respondido 06 Feb 18, 23:02

Esto solo funciona en casos simples. Los casos más complicados requieren un classpath más complicado. - Stephen C

Y para casos >>realmente<< simples, -cp . es innecesario, porque si $CLASSPATH está desarmado, entonces . es la ruta de clase predeterminada. - Stephen C

No Stephen, muchas veces en el classpath predeterminado de Windows no funciona. Lo probé en tres máquinas diferentes, tú también puedes probar eso. - shailu

Probablemente se deba a que en realidad ha configurado la variable de entorno %CLASSPATH% en alguna parte. Si hace eso, entonces no está usando el classpath predeterminado. (Que hace echo %CLASSPATH% salida?) Y no, no puedo verificar porque no tengo una PC con Windows. - Stephen C

Esto funcionó para mí cuando traté de ejecutar un programa simple desde la línea de comandos: SnuKies

Tuve un error de este tipo en este caso:

java -cp lib.jar com.mypackage.Main

Funciona con ; para Windows y : para Unix:

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

Respondido 09 Abr '17, 11:04

Sí. Lo más probable es que se deba a que su Main no está en el archivo JAR. -cp lib.jar; significa lo mismo que -cp lib.jar;. es decir, el directorio actual está incluido en el classpath. - Stephen C

Finalmente solucionó el problema para Unix... gracias (funciona con :) - Vicky

Intente -Xdiag.

La respuesta de Steve C. cubre muy bien los casos posibles, pero a veces para determinar si la clase no podría ser encontrado or cargado puede que no sea tan fácil. Usar java -Xdiag (desde JDK 7). Esto imprime un buen seguimiento de pila que proporciona una pista de lo que el mensaje Could not find or load main class significa el mensaje.

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

Respondido 06 Feb 18, 23:02

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 más difícil. Fue una biblioteca referenciada que moví, y me dio el:

No se pudo encontrar o cargar la clase principal xxx de Linux

Simplemente eliminé esa referencia, la agregué nuevamente y funcionó bien nuevamente.

Respondido el 14 de enero de 17 a las 16:01

Parece que el problema era que tenía un classpath incorrecto debido a una "referencia" rota en su proyecto en su IDE. Actualizaré mi respuesta para cubrir ese caso. - Stephen C

@StephenC y EduardoDennis, era que aquí también faltaba un jar, ese jar contenía una interfaz de la que dependía la clase principal para ser instanciada. Entonces, el mensaje de error es demasiado amplio. Debería decir "no se pudo encontrar" si no se encuentra el archivo de clase y "no se pudo cargar (faltan dependencias)" si falta algo más pero no el archivo en sí, por lo que el mensaje de error es demasiado amplio y es engañoso si solo se enfoca en la parte de "encontrar" :( - Poder de Acuario

@AquariusPower: debería haber un seguimiento de pila adicional "causado por" para la excepción de "causa" que decía que faltaba la clase. Si desea sugerir a los desarrolladores de Java que cambien un mensaje de error que ha estado diciendo eso durante más de 20 años... siéntase libre. (Creo que el mensaje de error es correcto. El problema fue que >>usted<< se limitó a la cláusula incorrecta). - Stephen C

@StephenC lo que quise decir es que seguramente tienen acceso a la información si el archivo de clase principal está disponible o no, entonces, ¿por qué no mostrarnos un mejor mensaje de error que diga que falta dicho archivo? Por otro lado, también podrían decir "El archivo se encontró pero no se pudo cargar" en ese momento, nos centraríamos rápidamente en las dependencias en lugar de perder medio día investigando y probando cosas para comprender. Solo eso quise decir :). ¡Pueden hacerlo de manera limitada durante más de 20 años, pero pueden mejorarlo y estamos aquí para admitir que eso sucederá a través de nuestras críticas y quejas! :D - Poder de Acuario

Por favor, comprenda lo que >>yo<< quise decir. Quejarse de eso en algún comentario oscuro sobre preguntas y respuestas de 3 años no va a lograr nada. Las personas que posiblemente podrían actuar sobre sus quejas no lo notarán. Si quieres hacer algo constructivo, envía un parche. (No califico tus posibilidades, pero serán mayores que si solo te quejas). - Stephen C

Tuve el mismo problema y finalmente encontré mi error :) Usé este comando para compilar y funcionó correctamente:

javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java

Pero este comando no me funcionó (no pude encontrar ni cargar la clase principal, qrcode):

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode

Finalmente agregué el carácter ':' al final del classpath y el problema se resolvió:

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode

Respondido el 12 de Septiembre de 19 a las 19:09

En este caso tienes:

No se pudo encontrar o cargar la clase principal ?ruta de clases

Es porque está usando "-classpath", pero el guión no es el mismo que usa java en el símbolo del sistema. Tuve este problema al copiar y pegar desde Bloc de notas a cmd.

Respondido el 14 de enero de 17 a las 16:01

¡Guau! ¡Esa es una causa totalmente extraña! (Pero te sirve para usar el Bloc de notas en lugar de un editor de texto real :-)) - Stephen C

Si utiliza Maven para compilar el archivo JAR, asegúrese de especificar la clase principal en el archivo pom.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>

Respondido 06 Feb 18, 23:02

En mi caso, el error apareció porque proporcioné 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.

Respondido 02 Feb 22, 18:02

Sí. ¡Vea mi ejemplo n. ° 2 de las formas incorrectas de especificar el nombre de la clase! - Stephen C

Esto podría ayudarlo si su caso es específicamente como el mío: como principiante, también me encontré con este problema cuando intenté ejecutar un programa Java.

Lo compilé así:

javac HelloWorld.java

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

java Helloworld.java

Cuando quité el .java y reescribió el comando como java HelloWorld, el programa funcionó perfectamente. :)

Respondido 06 Feb 18, 23:02

Esto se debe a que está ejecutando la versión compilada de su .java. En realidad, está ejecutando el archivo .class - Jason v

Para que conste, esto es lo mismo que la razón n.º 1, ejemplo n.º 5 en mi respuesta... - Stephen C

Parece que todas las respuestas aquí están dirigidas a los usuarios de Windows. Para Mac, el separador classpath es :no, ;. Como un error al establecer el classpath usando ; no se lanza, entonces esto puede ser difícil de descubrir si se trata de Windows a Mac.

Aquí está el comando Mac correspondiente:

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

Donde en este ejemplo está el paquete com.test y lib La carpeta también debe incluirse en classpath.

Respondido el 20 de enero de 17 a las 19:01

En Linux como en Mac. - Alex78191

¿Por qué /* ¿es necesario? - Alex78191

Es una sintaxis comodín. (No es obligatorio. Puede enumerar explícitamente los JAR si lo desea). - Stephen C

Ingrese la descripción de la imagen aquí

Ubicación del archivo de clase: C:\prueba\com\empresa

Nombre del archivo: Clase principal

Nombre de clase completamente calificado: com.empresa.principal

Comando de línea de comando:

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

Tenga en cuenta aquí que la ruta de clases no no incluir \com\empresa.

Respondido 02 Feb 22, 19:02

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.

Respondido 02 Feb 22, 18:02

He actualizado mi respuesta para tratar de abordar esa confusión. - Stephen C

Ninguno de estos es correcto. La clase debe ser dada como utilities.myapp.Cool o cualquiera que sea el nombre del paquete, si lo hay. - user207421

En Windows poner .; en el 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 set CLASSPATH=%CLASSPATH%;.. Esto durará mientras la ventana cmd esté abierta.

Respondido el 20 de enero de 17 a las 19:01

Este consejo puede o no ayudar. Ayudará si el árbol de clases contiene las clases en el directorio actual. No lo hará si no lo son. En realidad no haría esto. En su lugar, crearía una secuencia de comandos contenedora de una sola línea que funcionara tanto si el usuario está en el directorio "derecho" como si no. - Stephen C

Al ejecutar el java con el -cp opción como se anuncia en Windows PowerShell, es posible que obtenga un error similar a:

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

Para que PowerShell acepte el comando, los argumentos del -cp La opción debe estar entre comillas como en:

java -cp 'someDependency.jar;.' ClassName

Formar el comando de esta manera debería permitir que Java procese correctamente los argumentos de classpath.

contestado el 21 de mayo de 17 a las 09:05

Este es un caso específico:

Windows (probado con Windows 7) no acepta caracteres especiales (como á) en los nombres de clases y paquetes. Sin embargo, Linux sí.

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

Respondido 02 Feb 22, 19:02

Lo que solucionó el problema en mi caso fue:

Haga clic derecho en el proyecto/clase que desea ejecutar y luego Correr comoEjecutar configuraciones. Luego, debe corregir su configuración existente o agregar una nueva de la siguiente manera:

Abra la ruta de clases pestaña, haga clic en Avanzado... y luego agregue bin carpeta de tu proyecto.

Respondido 02 Feb 22, 19:02

Primero configure la ruta usando este comando;

set path="paste the set path address"

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

Respondido el 02 de diciembre de 13 a las 14:12

Esto no ayuda. Esta pregunta es sobre programas Java, no ejecutables ordinarios. Java no usa PATH para localizar nada, y si "cd" ayuda, es por suerte y no por juicio. - Stephen C

if "cd" helps then it by luck rather than by judgement. Esto está mal (creo), ya que java usa el directorio actual . como parte del classpath por defecto. - GKFX

@GKFX - Eso es lo que quiero decir. A menos que sepa que está utilizando el classpath predeterminado (o un classpath con "."), "cd" no tendrá ningún efecto. Esta solución funciona más por suerte (es decir, adivinar/esperar que "." esté en el classpath) que por juicio (es decir, comprobar que "." esté en el classpath). Además, está equivocado sobre el valor predeterminado. Java usa "." como el classpath por defecto, no como parte del classpath por defecto. - Stephen C

On Windows, presumiblemente? - Pedro Mortensen

En Java, cuando a veces ejecuta la JVM desde la línea de comando usando el ejecutable del intérprete de Java y está tratando de iniciar un programa desde un archivo de clase con public static void main (PSVM), es posible que se encuentre con el siguiente error aunque el parámetro classpath para JVM sea preciso y el archivo de clase esté presente en classpath:

Error: clase principal no encontrada o cargada

Esto sucede si no se pudo cargar el archivo de clase con PSVM. Una posible razón es que la clase puede estar implementando una interfaz o extendiendo otra clase que no está en el classpath. Normalmente, si una clase no está en el classpath, el error arrojado lo indica. Pero, si la clase en uso se amplía o implementa, Java no puede cargar la clase en sí.

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

Respondido 02 Feb 22, 19:02

¿Leíste la respuesta aceptada? ¿Su respuesta agrega algo nuevo? - Stephen C

@StephenC Intenté encontrar un motivo en su lista mirando las categorías de "Razón" y sus puntos. No pude encontrar el punto de coincidencia en el título "Razón n. ° 1" y "Razón n. ° 2" no se parecía a mi caso (porque estaba seguro de que no hay problema con classpath en sí). Encontré el motivo realizando experimentos y me sorprendió que, en mi caso, se mostrara el error "clase principal no encontrada" porque la interfaz de implementación no estaba en la ruta de clase. Claro que puedes decir "deberías leer todo lo que se describe en la publicación", pero me parece que tu lista de razones se puede mejorar. - Humkins

El vínculo está roto: "Hmm. Estamos teniendo problemas para encontrar ese sitio. No podemos conectarnos al servidor en www.computingnotes.net". - Pedro Mortensen

Realmente necesitas hacer esto desde el src carpeta. Allí escribes la siguiente línea de comando:

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

Digamos que tu clase se llama CommandLine.class, y el código se ve así:

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]);
            }
        }
    }

Entonces deberías cd a la carpeta src y el comando que debe ejecutar se vería así:

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

Y la salida en la línea de comando sería:

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

Respondido 02 Feb 22, 19:02

Una clase no se puede llamar "CommandLine.class". Eso sería un error de sintaxis de Java. (Lo que quiere decir es que el archivo que contiene la clase compilada se llama "CommandLine.class"...). El otro problema es que su instrucción de "cd al directorio fuente" solo funciona si compiló el código >>en<< el árbol del directorio fuente. Finalmente, si su compilación usó un argumento "-cp", entonces necesita un equivalente cuando ejecuta. - Stephen C

En mi proyecto tengo la carpeta src y la carpeta bin en la raíz. tuve que cd dentro src y luego ejecuta el comando java ../bin com.blah.blah.MyClass que funcionó para mí. ¡Así que gracias por el consejo! - tamj0rd2

De acuerdo, ya hay muchas respuestas, pero nadie mencionó el caso en el que los permisos de archivos pueden ser los culpables.

Cuando se ejecuta, es posible que un usuario no tenga acceso al archivo JAR o a uno de los directorios de la ruta. Por ejemplo, considere:

Archivo jar en /dir1/dir2/dir3/myjar.jar

El usuario 1 propietario del archivo JAR puede hacer lo siguiente:

# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar

Pero sigue sin funcionar:

# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram

Esto se debe a que el usuario que ejecuta (Usuario2) no tiene acceso a dir1, dir2, javalibs o dir3. Puede volver loco a alguien cuando el Usuario1 puede ver los archivos y puede acceder a ellos, pero el error sigue ocurriendo para el Usuario2.

Respondido el 12 de Septiembre de 19 a las 19:09

También enfrenté errores similares mientras probaba una conexión Java MongoDB JDBC. Creo que es bueno resumir mi solución final en pocas palabras para que en el futuro cualquiera pueda ver directamente los dos comandos y pueda continuar.

Suponga que se encuentra en el directorio donde existen su archivo Java y las dependencias externas (archivos JAR).

Compilar:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • -cp - argumento classpath; pasar todos los archivos JAR dependientes uno por uno
  • *.java: este es el archivo de clase Java que tiene el método principal. disco duro

Ejecutar:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • Observe los dos puntos (Unix) / coma (Windows) después de que finalicen todos los archivos JAR de dependencia
  • Al final, observe el nombre de la clase principal sin ninguna extensión (sin .class o .java)

Respondido 02 Feb 22, 19:02

Todo esto supone que 1) JavaMongoDBConnection no tiene paquete, y 2) no cambias de directorio. Es, por decir lo menos, frágil. Y al no explicar los problemas, llevará a los novatos a probar este enfoque. en situaciones en las que no funcionará. En resumen, fomenta las "técnicas de programación vudú": en.wikipedia.org/wiki/Voodoo_programming - Stephen C

No pude resolver este problema con las soluciones indicadas aquí (aunque la respuesta indicada, sin duda, ha aclarado mis conceptos). Enfrenté este problema dos veces y cada vez probé diferentes soluciones (en el IDE de Eclipse).

  • En primer lugar, me he encontrado con múltiples main métodos en diferentes clases de mi proyecto. Entonces, había borrado el main método de clases posteriores.
  • En segundo lugar, probé la siguiente solución:
    1. Haga clic derecho en el directorio de mi proyecto principal.
    2. Diríjase a la fuente, luego limpie y siga con la configuración predeterminada y en Finalizar. Después de algunas tareas en segundo plano, se le dirigirá al directorio principal de su proyecto.
    3. Después de eso, cierro mi proyecto, lo vuelvo a abrir y boom, finalmente resolví mi problema.

Respondido el 20 de enero de 17 a las 19:01

Eliminación main Los métodos no solucionarán el problema. No hay nada técnicamente malo con una aplicación que tiene múltiples puntos de entrada. - Stephen C

A veces, en algunos compiladores en línea que podría haber probado obtendrá este error si no escribe public class [Classname] pero solo class [Classname].

Respondido 18 ago 17, 19:08

Ejemplos (de compiladores ofensivos) por favor. Si bien es convencional/normal hacer una clase de "punto de entrada" public, las especificaciones de Java no requieren esto, y tampoco el Oracle / OpenJDK estándar java mando. - Stephen C

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.