java - returned - no se encontraron clases principales netbeans
Java no puede encontrar la clase principal (5)
Ejecuta el siguiente comando
java -cp . com.Hello
He escrito el siguiente archivo fuente de Java ( Hello.java
):
package com;
public class Hello {
public static void main(String[] args) {
System.out.println("Hello!");
}
}
C:/tmpjava/Hello.java
esto en C:/tmpjava/Hello.java
.
Desde la línea de comandos, javac Hello.java
a ese directorio y ejecuto javac Hello.java
. Entonces corro dir
:
-
Hello.class
-
Hello.java
Luego, desde el mismo directorio del que acabo de ejecutar javac
, ejecuto java Hello.class
y obtengo:
Exception in thread "main" java.lang.NoClassDefFoundError: Hello/class
Caused by: java.lang.ClassNotFoundException: Hello.class
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: Hello.class. Program will exit.
¿¡¿Que está pasando aqui?!? ¿Cómo puede javac
funcionar bien, pero no java
?
La clase debe estar en C:/tmpjava/com/Hello.class
Y debes ejecutar desde C:/tmpjava
: java -cp . com.Hello
java -cp . com.Hello
Cuando pones una clase en un paquete, define la estructura de archivos de la clase. Es decir, su clase que en el paquete com
debería estar en la carpeta com
La sintaxis del comando de Java es:
java [classname]
no
java [filename]
Java busca en su ruta de clase una clase del nombre que ha proporcionado. Por lo general, el classpath incluye el directorio actual, por lo que:
java Hello
... encontrará Hello.class en el directorio actual y ejecutará su método main ().
Sin embargo, si la clase está en otro lugar (como en un .jar, o en otro lugar en el sistema de archivos), puede especificarla con la variable de entorno CLASSPATH, o en la línea de comandos:
java -cp build/classes Hello
java -cp build/jars/myjar.jar Hello
Tu clase Hello
pertenece al paquete com
. Así que el nombre completo de su clase es com.Hello
. Cuando invocas un programa usando java en la línea de comandos, debes proporcionar el nombre de clase completamente calificado de la clase que contiene tu método main
y omitir el .class , de esta manera:
java com.Hello
El programa java necesita este nombre de clase completamente calificado para comprender a qué clase se refiere.
Pero tienes otro problema. El programa java localiza paquetes, subpaquetes y las clases que pertenecen a ellos usando el sistema de archivos. Entonces, si tiene una estructura de paquete como com.Hello
, el programa java espera encontrar un archivo de clase llamado Hello.class en un directorio llamado com , como este: com / Hello.class . De hecho, puede observar este comportamiento en la Exception
que ve; has usado incorrectamente Hello.class , que java interpreta como un paquete llamado Hello
, y una clase llamada class
, y busca la estructura de directorios Hello / class :
java.lang.NoClassDefFoundError: Hello / class
Pero el compilador javac no configura esta estructura de directorios por defecto. Consulte la documentación de javac , pero el bit importante es este: cuando hace sus compilaciones, puede especificar un directorio de destino usando la -d
:
directorio -d
Establecer el directorio de destino para los archivos de clase. El directorio de destino ya debe existir; javac no creará el directorio de destino. Si una clase es parte de un paquete, javac coloca el archivo de clase en un subdirectorio que refleja el nombre del paquete, creando directorios según sea necesario. Por ejemplo, si especifica -dc: / myclasses y la clase se llama com.mypackage.MyClass, entonces el archivo de clase se llama c: / myclasses / com / mypackage / MyClass.class.
Si no se especifica -d, javac coloca el archivo de clase en el mismo directorio que el archivo de origen.
El último bit en negrita es la fuente de mucha confusión para los principiantes, y es parte de su propio problema.
Así que tienes dos alternativas:
En su caso, está bien si proporciona el directorio actual como el directorio de destino, así (el punto significa el directorio actual ):
javac -d . Hello.java
Si invoca el compilador de esta manera, creará el directorio com por usted y colocará su archivo de clase compilado en la forma en que el programa Java espera encontrarlo. Luego, cuando ejecute java como antes, desde c: / tmpJava , su programa debería ejecutarse.
Puede configurar su código fuente utilizando una estructura de directorios que refleje la estructura de su paquete: coloque su archivo fuente Hello.java dentro de un directorio llamado com , en su caso: c: / tmpJava / com / Hello.java . Ahora, desde c: / tmpJava puede ejecutar su compilación javac de la siguiente manera:
javac com/Hello.java
No ha suministrado el indicador
-d
, pero está bien, porque usted mismo creó la estructura del directorio y vuelve a cotizar en la documentación anterior:Si no se especifica -d, javac coloca el archivo de clase en el mismo directorio que el archivo de origen.
Nuevamente, cuando ejecute java como anteriormente, su programa debería ejecutarse.
Tenga en cuenta que esta segunda alternativa es la que comúnmente emplean los programadores de Java: los archivos de código fuente están organizados en una estructura de directorio que refleja la estructura del paquete.
En esta explicación hemos ignorado el concepto del classpath . También deberá entender eso para escribir programas java, pero en el caso de simplemente compilar un programa en el directorio actual, si sigue una de las dos alternativas anteriores al compilar su clase, puede escapar sin establecer una ruta de clase porque De forma predeterminada, el programa java tiene el directorio actual como classpath. Otra cita, esta de la documentación para java :
-cp classpath
Especifique una lista de directorios, archivos JAR y archivos ZIP para buscar archivos de clase. Las entradas de la ruta de clases están separadas por punto y coma (;). La especificación de -classpath o -cp anula cualquier configuración de la variable de entorno CLASSPATH.
Si -classpath y -cp no se utilizan y CLASSPATH no se configura, la ruta de clase de usuario consiste en el directorio actual (.).
Tenga en cuenta que cuando usa un IDE como Eclipse para ejecutar su código Java, esto se maneja principalmente por usted, pero aún tendrá problemas de classpath.
java -classpath c: / tmpjava com.Hello