world - scanner java




¿Qué significa "No se pudo encontrar o cargar la clase principal"? (20)

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:

  1. Busque la versión compilada 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 forma parte de la firma).
  4. 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 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 # 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:

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

  1. 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).
  2. 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.
  3. 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 .
  4. Verifique que la clase (mencionada en el mensaje de error) pueda ubicarse en la ruta de clase efectiva .
  5. 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 para java , 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:

(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

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?


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.


En este caso tienes:

¿No se pudo encontrar o cargar la clase principal ? Classpath

Esto se debe a que está utilizando "-classpath", pero el guión no es el mismo guión que usa java en el símbolo del sistema. Tuve este problema al copiar y pegar desde el Notepad de Notepad a cmd.


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.


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 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.


Según el mensaje de error ("No se pudo encontrar o cargar la clase principal"), hay dos categorías de problemas:

  1. Clase principal no se pudo encontrar
  2. 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 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>

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.


Al ejecutar el javacon la -cpopció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 -cpopció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.


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 srccarpeta. 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 cdir 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




main