Un problema común que experimentan los nuevos desarrolladores de Java es que sus programas no se ejecutan con el mensaje de error No se pudo encontrar o cargar la clase principal ...
¿Qué significa esto, qué lo causa y cómo debe solucionarse?
java <nombre de la clase>
.En primer lugar, hay que entender la forma correcta de lanzar un programa utilizando el comando java
(o javaw
).
La sintaxis normal1 es esta:
java [ <option> ... ] <class-name> [<argument> ...]
donde <opción>
es una opción de la línea de comandos (que comienza con un carácter "-"), <nombre de la clase>
es un nombre de clase Java completamente calificado, y <argumento>
es un argumento arbitrario de la línea de comandos que se pasa a su aplicación.
1 - Hay una segunda sintaxis para los archivos JAR "ejecutables" que describiré al final.
El nombre completamente calificado (FQN) para la clase se escribe convencionalmente como lo haría en el código fuente de Java; por ejemplo
packagename.packagename2.packagename3.ClassName
Sin embargo, algunas versiones del comando java
permiten utilizar barras en lugar de puntos; por ejemplo
packagename/packagename2/packagename3/ClassName
que (confusamente) parece un nombre de ruta de archivo, pero no lo es. Tenga en cuenta que el término nombre completamente cualificado es terminología estándar de Java ... no algo que me haya inventado para confundirle :-)
Este es un ejemplo de cómo debería ser un comando java
:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Lo anterior hará que el comando java
haga lo siguiente
com.acme.example.ListUsers
.main
con firma, tipo de retorno y modificadores dados por public static void main(String[])
. (Nota, el nombre del argumento del método NO forma parte de la firma).String[]
.
Razones por las que Java no puede encontrar la clasejava
no ha podido encontrar la clase. Y de hecho, el "..." en el mensaje será el nombre de la clase completamente calificado que java
está buscando.
Entonces, ¿por qué no puede encontrar la clase?La primera causa probable es que hayas proporcionado un nombre de clase incorrecto. (O ... el nombre de clase correcto, pero en la forma incorrecta.) Considerando el ejemplo anterior, aquí hay una variedad de formas incorrectas de especificar el nombre de la clase:
Ejemplo #1 - un nombre de clase simple:
java ListUser
Cuando la clase está declarada en un paquete como com.acme.example
, entonces debes usar el nombre completo de la clase incluyendo el nombre del paquete en el comando java
; por ejemplo
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 el casing incorrecto: java com.acme.example.listuser
Ejemplo #4 - un error tipográfico java com.acme.example.mistuser
Ejemplo #5 - un nombre de archivo fuente java ListUser.java
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, es necesario entender el concepto de "classpath". Esto se explica bien en la documentación de Oracle:
El tutorial de Java - PATH y CLASSPATH Así que ... si ha especificado el nombre de la clase correctamente, lo siguiente que hay que comprobar es que ha especificado el classpath correctamente:
java
. 2. Comprueba que los nombres de los directorios y de los archivos JAR son correctos.java
.;
en Windows y :
en los demás. Si utiliza el separador incorrecto para su plataforma, no obtendrá un mensaje de error explícito. En su lugar, obtendrá un archivo o directorio inexistente en la ruta que será ignorado silenciosamente).
Razón #2a - el directorio equivocado está en el classpathCuando se pone un directorio en el classpath, éste corresponde teóricamente a la raíz del espacio de nombres cualificados. Las clases se ubican en la estructura de directorios debajo de esa raíz, mapeando el nombre completamente calificado a un nombre de ruta. Así, por ejemplo, si "/usr/local/acme/classes" está en la ruta de clases, 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 el FQN de sus clases es com.acme.example.Foon
, entonces la JVM va a buscar "Foon.class" en el directorio "com/acme/example":
com.acme.example.Foon
,/usr/local/acme/classes/com/acme/example/Foon.class
,/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
puede acortarse a -cp
en la mayoría de las versiones de Java. Compruebe las respectivas entradas del manual para java
, javac
, etc.
El classpath necesita incluir todas las otras clases (no del sistema) de las que depende su aplicación. (Las clases del sistema se localizan automáticamente, y rara vez necesitas preocuparte por esto). Para que la clase principal se cargue correctamente, la JVM necesita encontrar:
la propia clase.
todas las clases e interfaces en la jerarquía de superclases (por ejemplo, ver https://stackoverflow.com/questions/42880748)
paquete
. Si haces esto en un IDE, el compilador del IDE te lo dirá inmediatamente. Del mismo modo, si utiliza una herramienta de compilación de Java decente, la herramienta ejecutará javac
de manera que detectará el problema. Sin embargo, si construyes tu código Java a mano, puedes hacerlo de tal manera que el compilador no note el problema, y el archivo ".class" resultante no esté en el lugar que esperas.
¿Sigues sin encontrar el problema?-Xdiag
a la línea de comandos java
(como la primera cosa después de java
). Esta opción mostrará varias cosas sobre la carga de clases, y esto puede ofrecerte pistas sobre cuál es el verdadero problema.
Además, considere los posibles problemas causados por copiar y pegar caracteres invisibles o no ASCII de sitios web, documentos, etc. Y ten en cuenta los "homoglifos", cuando dos letras o símbolos parecen iguales... pero no lo son.java -jar <archivojar>
.La sintaxis alternativa utilizada para los archivos JAR "ejecutables" es la siguiente:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
por ejemplo
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
com.acme.example.ListUser
) y el classpath se especifican en el MANIFIESTO del archivo JAR.java
.
Sin embargo, todavía es posible que esta excepción ocurra, si usted hace cosas a espaldas del IDE. Por ejemplo, si has configurado previamente un lanzador de aplicaciones para tu aplicación Java en Eclipse, y luego has movido el archivo JAR que contiene la clase "main" a un lugar diferente en el sistema de archivos sin decírselo a Eclipse, Eclipse lanzaría involuntariamente la JVM con un classpath incorrecto.
En resumen, si tienes este problema en un IDE, comprueba cosas como el estado del IDE, referencias de proyecto rotas o configuraciones del lanzador rotas.
También es posible que un IDE simplemente se confunda. Los IDEs son piezas de software enormemente complicadas que comprenden muchas partes que interactúan. Muchas de estas partes adoptan varias estrategias de almacenamiento en caché con el fin de hacer que el IDE en su conjunto responda. A veces pueden fallar, y un posible síntoma son los problemas al lanzar las aplicaciones. Si sospechas que esto puede estar ocurriendo, vale la pena probar cosas como reiniciar tu IDE y reconstruir el proyecto.A veces lo que puede estar causando el problema no tiene nada que ver con la clase principal, y tuve que descubrir esto de la manera más difícil. Era una biblioteca referenciada que moví, y me dio el:
No se pudo encontrar o cargar la clase principal xxx Linux
Simplemente borré esa referencia, la añadí de nuevo, y volvió a funcionar bien.
En primer lugar, establezca la ruta de acceso mediante este comando;
set path="paste the set path address"
A continuación, debe cargar el programa. Escriba "cd (nombre de la carpeta)" en la unidad almacenada y compilarlo. Por ejemplo, si mi programa almacenado en la unidad D, escriba "D:" pulse enter y escriba " cd (nombre de la carpeta)".