java - scanner - que es main class
¿Qué significa "No se pudo encontrar o cargar la clase principal"? (30)
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 arreglarlo?
La sintaxis del comando java <class-name>
En primer lugar, debe comprender la forma correcta de iniciar un programa utilizando el comando java
(o javaw
).
La sintaxis normal 1 es la siguiente:
java [ <option> ... ] <class-name> [<argument> ...]
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 <argument>
es un argumento de línea de comando arbitrario que se pasa a su aplicación.
1 - Hay una segunda sintaxis 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 diagonales en lugar de puntos; p.ej
packagename/packagename2/packagename3/ClassName
que (confusamente) parece un nombre de archivo, pero no lo es. Tenga en cuenta que el término nombre completo es terminología estándar de Java ... no es algo que acabo de hacer para confundirlo :-)
Aquí hay un ejemplo de cómo debería verse un comando java
:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Lo anterior hará que el comando java
haga lo siguiente:
- Busque la versión compilada de la clase
com.acme.example.ListUsers
. - Carga la clase.
- Verifique que la clase tenga un método
main
con firma , tipo de retorno y modificadores dados porpublic static void main(String[])
. (Tenga en cuenta que el nombre del argumento del método NO forma parte de la firma). - Llame a ese método pasándole los argumentos de la línea de comando ("fred", "joe", "bert") como una
String[]
.
Razones por las que Java no puede encontrar la clase
Cuando aparece el mensaje "No se pudo encontrar o cargar la clase principal ...", 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 completo que java
está buscando.
Entonces, ¿por qué no podría encontrar la clase?
Razón # 1: cometiste un error con el argumento del nombre de clase
La primera causa probable es que puede haber proporcionado el nombre de clase incorrecto. (O ... el nombre correcto de la clase, pero en la forma incorrecta.) Teniendo en cuenta el ejemplo anterior, aquí hay una variedad de formas 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
, debe usar el nombre de clase completo, incluido el nombre del paquete en el comandojava
; p.ejjava 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 # 4 - un error tipográfico
java com.acme.example.mistuser
Ejemplo # 5 - un nombre de archivo fuente
java ListUser.java
Ejemplo # 6 - olvidó el nombre de la clase por completo
java lots of arguments
Razón # 2 - la ruta de clase de la aplicación está especificada incorrectamente
La segunda causa probable es que el nombre de la clase es correcto, pero que el comando java
no puede encontrar la clase. Para entender esto, necesitas entender el concepto del "classpath". Esto se explica bien en la documentación de Oracle:
- La documentación del comando
java
- Configuración de la Classpath .
- El Tutorial de Java - PATH y CLASSPATH
Entonces ... si ha especificado el nombre de la clase correctamente, lo siguiente que debe verificar es que ha especificado la ruta de clase correctamente:
- Lea los tres documentos vinculados arriba. (Sí ... LEAlas. Es importante que un programador de Java entienda al menos los conceptos básicos de cómo funcionan los mecanismos de Java classpath).
- Mire la línea de comandos y / o la variable de entorno CLASSPATH que está vigente cuando ejecuta el comando
java
. Compruebe que los nombres de directorio y los nombres de archivo JAR son correctos. - Si hay rutas de acceso relativas en el classpath, verifique que se resuelvan correctamente ... desde el directorio actual que está vigente cuando ejecuta el comando
java
. - Verifique que la clase (mencionada en el mensaje de error) pueda ubicarse en la ruta de clase efectiva .
- Tenga en cuenta que la sintaxis de classpath es diferente para Windows en comparación con Linux y Mac OS. (El separador de 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, corresponde teóricamente a la raíz del espacio de nombre calificado. Las clases se ubican en la estructura de directorios debajo de esa raíz, asignando el nombre completo a un nombre de ruta . Por ejemplo, si "/ usr / local / acme / classes" está en la ruta de clases, entonces cuando la JVM busque una clase llamada com.acme.example.Foon
, buscará un archivo ".class" con esto ruta de acceso:
/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 la FQN
Si sus clases FQN son com.acme.example.Foon
, la JVM buscará "Foon.class" en el directorio "com / acme / example":
Si su estructura de directorios no coincide con la denominación del paquete según el patrón anterior, la JVM no encontrará su clase.
Si intenta cambiar el nombre de una clase moviéndolo, eso también fallará ... pero la excepción stacktrace será diferente.
Para dar un ejemplo concreto, suponiendo 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 abreviar a-cp
en la mayoría de las versiones de Java. Verifique las entradas manuales respectivas parajava
,javac
, etc. - Piense con cuidado cuando elija entre rutas de acceso absolutas y relativas en classpaths. Recuerde que una ruta relativa puede "romperse" si el directorio actual cambia.
Razón # 2c - faltan dependencias de la ruta de clase
La ruta de clase debe incluir todas las otras clases (no de sistema) de las que depende su aplicación. (Las clases del sistema se ubican automáticamente, y rara vez debe preocuparse por esto.) Para que la clase principal se cargue correctamente, la JVM debe encontrar:
- la clase en si
- todas las clases e interfaces en la jerarquía de superclase (por ejemplo, ver clase de 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 variable o variable, o expresiones de acceso a campos o llamadas de método.
(Nota: las especificaciones JLS y JVM permiten cierto alcance para que una JVM cargue las clases "perezosamente", y esto puede afectar cuando se lanza una excepción del 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 la declaración del package
. Si hace esto en un IDE, el compilador del IDE le informará sobre esto inmediatamente. De manera similar, si utiliza una herramienta de compilación Java decente, la herramienta ejecutará javac
de una manera que detectará el problema. Sin embargo, si crea su código Java a mano, puede hacerlo de tal manera que el compilador no note el problema, y el archivo ".class" resultante no se encuentre en el lugar que espera.
¿Todavía no puedes encontrar el problema?
Hay muchas cosas para verificar, y es fácil perderse algo. Intente agregar la opción -Xdiag
a la línea de comando de java
(como la primera cosa después de java
). Producirá varias cosas sobre la carga de clases, y esto puede ofrecerle pistas sobre cuál es el problema real.
Además, tenga en cuenta los posibles problemas causados por copiar y pegar caracteres invisibles o no ASCII de sitios web, documentos, etc. Y considere "homoglifos", donde dos letras o símbolos tienen el mismo aspecto ... pero no lo son.
La java -jar <jar file>
La sintaxis alternativa utilizada para los archivos JAR "ejecutables" es la siguiente:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
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 el classpath se especifican en el MANIFEST del archivo JAR.
IDEs
Un IDE Java típico tiene soporte para ejecutar aplicaciones Java en la JVM IDE o en una JVM secundaria. Estos son generalmente inmunes a esta excepción en particular, porque el IDE utiliza sus propios mecanismos para construir el classpath del tiempo de ejecución, identificar la clase principal y crear la línea de comando java
.
Sin embargo, aún es posible que ocurra esta excepción, si hace cosas detrás del IDE. Por ejemplo, si 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 avisar a Eclipse , Eclipse iniciaría sin darse cuenta el JVM. con un classpath incorrecto.
En resumen, si obtienes este problema en un IDE, comprueba si el estado del IDE está obsoleto, las referencias de proyectos rotos o las configuraciones del iniciador no funcionan.
También es posible que un IDE simplemente se confunda. Los IDE son piezas de software enormemente complicadas que comprenden muchas partes interactivas. Muchas de estas partes adoptan diversas estrategias de almacenamiento en caché para que el IDE en su totalidad responda. A veces, esto puede salir mal, y un síntoma posible es un problema al iniciar aplicaciones. Si sospecha que esto podría estar sucediendo, vale la pena reiniciar su IDE.
Otras referencias
- De los tutoriales de Java de Oracle: problemas comunes (y sus soluciones)
A veces, lo que podría estar causando el problema no tiene nada que ver con la clase principal, y tuve que descubrirlo por el camino difícil. Me mudé a una biblioteca de referencia y me dio:
No se pudo encontrar o cargar la clase principal xxx Linux
Acabo de eliminar esa referencia, la agregué nuevamente y funcionó bien otra vez.
Cuando el mismo código funciona en una PC, pero muestra el error en otra, la mejor solución que he encontrado es compilar como la siguiente:
javac HelloWorld.java
java -cp . HelloWorld
En mi caso, apareció un error porque había proporcionado el nombre del archivo de origen en lugar del nombre de la clase.
Necesitamos proporcionar el nombre de la clase que contiene el método principal al intérprete.
Este es un caso específico, pero desde que vine a esta página en busca de 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
NetBeans e intenté ejecutarlo en la línea de comandos. Se ejecutó en NetBeans pero no en la línea de comandos.
Esto podría ayudarte si tu 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 correr también con la misma extensión:
java Helloworld.java
Cuando quité el .java
y reescribí el comando como java HelloWorld
, el programa funcionó perfectamente. :)
Intenta -Xdiag .
La respuesta de Steve C cubre muy bien los posibles casos, pero a veces para determinar si no se pudo encontrar o cargar la clase no podría ser tan fácil. Utilice java -Xdiag
(desde JDK 7). Esto imprime un buen seguimiento de pila que proporciona una pista de lo que significa el mensaje Could not find or load main class
mensaje de la Could not find or load main class
.
Por ejemplo, puede apuntar a otras clases utilizadas por la clase principal que no se pudieron encontrar e impidió que se cargara la clase principal.
Lo que me ayudó fue especificar la ruta de clase en la línea de comandos, por ejemplo:
Crea una nueva carpeta,
C:/temp
Cree 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]); } }
Abra una línea de comando en la carpeta
C:/temp
, y escriba el siguiente comando para compilar la clase Temp:javac Temp.java
Ejecute la clase Java compilada, agregando la opción
-classpath
para que JRE sepa dónde encontrar la clase:java -classpath C:/temp Temp Hello!
Lo que solucionó el problema en mi caso fue:
Haga clic derecho en el proyecto / clase que desea ejecutar, luego Run As
-> Run Configurations
. Entonces deberías arreglar tu configuración existente o agregar una 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.
Pasé una cantidad decente 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 completamente calificado significaba incluir el nombre completo de la ruta en lugar del nombre completo del paquete.
Primero establezca la ruta usando este comando;
set path="paste the set path address"
Entonces necesitas cargar el programa. Escriba "cd (nombre de carpeta)" en la unidad almacenada y compílela. Por ejemplo, si mi programa está almacenado en la unidad D, escriba "D:" presione enter y escriba "cd (nombre de carpeta)".
Según el mensaje de error ("No se pudo encontrar o cargar la clase principal"), hay dos categorías de problemas:
- Clase principal no se pudo encontrar
- No se pudo cargar la clase principal (este caso no se trata completamente en la respuesta aceptada)
No se pudo encontrar la clase principal cuando hay un error tipográfico o una sintaxis incorrecta en el nombre de clase completo o no existe en el classpath proporcionado .
La clase principal no se pudo cargar cuando la clase no se puede iniciar , generalmente la clase principal extiende otra clase y esa clase no existe en la ruta de clase proporcionada.
Por ejemplo:
public class YourMain extends org.apache.camel.spring.Main
Si no se incluye el resorte del camello, se informará este error.
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
Si su método principal está en la clase bajo 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 usa java com.test.Main
.
Si sus clases están en paquetes, entonces debe cd
al directorio principal y ejecutar con 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 vuelvo al directorio principal:
D:/project
Luego ejecute el comando java
:
java com.cse.Main
Si usa 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>
Todas las respuestas aquí están dirigidas a los usuarios de Windows que parece. Para Mac, el separador de classpath es :
no ;
. Como error al configurar el classpath usando ;
no se lanza, entonces esto puede ser difícil de descubrir si viene de Windows a Mac.
Aquí está el comando correspondiente de Mac:
java -classpath ".:./lib/*" com.test.MyClass
Donde en este ejemplo el paquete es com.test
y una carpeta lib
también se incluirá en classpath.
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
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 comando java
espera classpath y por este motivo agregamos -cp .
para tomar la carpeta actual como referencia para classpath.
En Java, cuando a veces ejecuta la JVM desde la línea de comandos utilizando el ejecutable java y está intentando iniciar un programa desde un archivo de clase con una red pública estática vacía (PSVM), es posible que se encuentre con el error siguiente, aunque el parámetro classpath La JVM es precisa y el archivo de clase está presente en la ruta de clase:
Error: main class not found or loaded
Esto sucede si no se pudo cargar el archivo de clase con PSVM. Una posible razón para esto 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 la ruta de clase, el error lanzado indica como tal. Pero, si la clase en uso se extiende o implementa, java no puede cargar la clase en sí.
Referencia: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/
Tuve una extraña
Error: No se pudo encontrar o cargar la clase principal mypackage.App
Resultó que tenía una configuración pom (padre) en el pom.xml de mi proyecto (el pom.xml de mi proyecto estaba apuntando a un pom.xml del padre) y el relativePath estaba apagado / incorrecto.
A continuación se muestra un parcial de pom.xml de mi proyecto
<parent>
<groupId>myGroupId</groupId>
<artifactId>pom-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../badPathHere/pom.xml</relativePath>
</parent>
Una vez que resolví el pom relativePath, el error desapareció.
Imagínate.
A veces, en algunos compiladores en línea que podría haber intentado, obtendrá este error si no escribe, public class [Classname]
solo class [Classname]
.
Al ejecutar el java
con la -cp
opción como se anuncia en Windows PowerShell, puede obtener un error similar al siguiente:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
Para que PowerShell acepte el comando, los argumentos de la -cp
opción deben estar entre comillas como en:
java -cp ''someDependency.jar;.'' ClassName
Formar el comando de esta manera debería permitir a Java procesar los argumentos de classpath correctamente.
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 puedes configurarlo "una vez" con set CLASSPATH=%CLASSPATH%;.
. Esto durará tanto como su ventana cmd esté abierta.
En mi caso, recibí el error porque había mezclado los nombres de paquetes en mayúsculas y minúsculas en un sistema Windows 7. Cambiar los nombres de los paquetes a minúsculas resolvió el problema. Tenga en cuenta también que en este escenario no obtuve ningún error al compilar el archivo .java en un archivo .class; simplemente no se ejecutaría desde el mismo directorio (sub-sub-sub- sub).
Muy bien, ya hay muchas respuestas, pero nadie mencionó el caso donde el permiso de archivo puede ser el culpable. Cuando el usuario en ejecución no tiene acceso al archivo jar o uno de los directorios de la ruta. Por ejemplo considera:
Archivo jar en /dir1/dir2/dir3/myjar.jar
El usuario 1 que posee el tarro puede hacer:
# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
Pero todavía no funciona:
# 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 en ejecución (Usuario2) no tiene acceso a dir1, dir2 o javalibs o dir3. Puede volver loco a alguien cuando User1 puede ver los archivos y puede acceder a ellos, pero el error sigue ocurriendo para User2
Realmente necesitas hacer esto desde la src
carpeta. Allí escribes la siguiente línea de comando:
[name of the package].[Class Name] [arguments]
Digamos que su 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]);
}
}
}
Luego deberías cd
ir a la carpeta src y el comando que necesitas para 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
También me enfrenté a errores similares al probar una conexión Java MongoDB JDBC. Creo que es bueno resumir mi solución final en breve para que en el futuro cualquiera pueda mirar directamente los dos comandos y sea bueno para 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. sdsd
Correr:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
- Observe los dos puntos (Unix) / coma (Windows) después de que todos los archivos JAR de dependencia terminen
- Al final, observe el nombre de la clase principal sin ninguna extensión (no .class o .java)