Java Language
El Comando de Java - 'java' y 'javaw'
Buscar..
Sintaxis
java [ <opt> ... ] <class-name> [ <argument> ... ]
java [ <opt> ... ] -jar <jar-file-pathname> [ <argument> ... ]
Observaciones
El comando java
se utiliza para ejecutar una aplicación Java desde la línea de comandos. Está disponible como parte de cualquier Java SE JRE o JDK.
En los sistemas Windows hay dos variantes del comando java
:
- La variante de
java
inicia la aplicación en una nueva ventana de consola. - La variante
javaw
inicia la aplicación sin crear una nueva ventana de consola.
En otros sistemas (por ejemplo, Linux, Mac OSX, UNIX) solo se proporciona el comando java
y no se abre una nueva ventana de consola.
El símbolo <opt>
en la sintaxis denota una opción en la línea de comando java
. Los temas "Opciones de Java" y "Opciones de tamaño de pila y pila" cubren las opciones más utilizadas. Otros están cubiertos en el tema Banderas JVM .
Ejecutando un archivo JAR ejecutable
Los archivos JAR ejecutables son la forma más sencilla de ensamblar código Java en un solo archivo que se puede ejecutar. * (Nota editorial: la creación de archivos JAR debe estar cubierta por un tema separado.) *
Suponiendo que tiene un archivo JAR ejecutable con la ruta de acceso <jar-path>
, debería poder ejecutarlo de la siguiente manera:
java -jar <jar-path>
Si el comando requiere argumentos de línea de comandos, agréguelos después de <jar-path>
. Por ejemplo:
java -jar <jar-path> arg1 arg2 arg3
Si necesita proporcionar opciones de JVM adicionales en la línea de comandos de java
, deben ir antes que la opción -jar
. Tenga en cuenta que una opción -cp
/ -classpath
se ignorará si utiliza -jar
. La ruta de clase de la aplicación está determinada por el archivo JAR manifiesto.
Ejecutando aplicaciones Java a través de una clase "principal"
Cuando una aplicación no se ha empaquetado como un JAR ejecutable, debe proporcionar el nombre de una clase de punto de entrada en la línea de comandos de java
.
Ejecutando la clase HelloWorld
El ejemplo "HelloWorld" se describe en Crear un nuevo programa Java . Consiste en una clase única llamada HelloWorld
que satisface los requisitos para un punto de entrada.
Suponiendo que el archivo "HelloWorld.class" (compilado) está en el directorio actual, se puede iniciar de la siguiente manera:
java HelloWorld
Algunas cosas importantes a tener en cuenta son:
- Debemos proporcionar el nombre de la clase: no el nombre de ruta para el archivo ".class" o el archivo ".java".
- Si la clase se declara en un paquete (como la mayoría de las clases de Java), entonces el nombre de la clase que suministramos al comando
java
debe ser el nombre completo de la clase. Por ejemplo, si se declaraSomeClass
en el paquetecom.example
, entonces el nombre completo de la clase serácom.example.SomeClass
.
Especificando un classpath
A menos que estemos usando la sintaxis del comando java -jar
, el comando java
busca la clase que se cargará buscando la ruta de clase; ver el classpath . El comando anterior se basa en que la ruta de clase predeterminada es (o incluye) el directorio actual. Podemos ser más explícitos sobre esto especificando la ruta de -cp
que se usará usando la opción -cp
.
java -cp . HelloWorld
Esto dice que hacer que el directorio actual (que es a lo que "." Se refiere) sea la única entrada en el classpath.
El -cp
es una opción que es procesada por el comando java
. Todas las opciones destinadas al comando java
deben estar antes del nombre de clase. Cualquier cosa después de la clase se tratará como un argumento de línea de comando para la aplicación Java y se pasará a la aplicación en la String[]
que se pasa al método main
.
(Si no se proporciona la opción -cp
, java
usará la ruta de clase que proporciona la variable de entorno CLASSPATH
. Si esa variable no está establecida o está vacía, java
usa "." Como la ruta de clase predeterminada).
Clases de punto de entrada
Una clase de punto de entrada Java tiene un método main
con la siguiente firma y modificadores:
public static void main(String[] args)
Nota al margen: debido a cómo funcionan las matrices, también puede ser
(String args[])
Cuando el comando java
inicia la máquina virtual, carga las clases de punto de entrada especificadas e intenta encontrar las main
. Si tiene éxito, los argumentos de la línea de comando se convierten en objetos de String
Java y se ensamblan en una matriz. Si main
se invoca así, la matriz no será null
y no contendrá ninguna entrada null
.
Un método de clase de punto de entrada válido debe hacer lo siguiente:
- Ser nombrado
main
(distingue entre mayúsculas y minúsculas) - Sé
public
ystatic
- Tener un tipo de retorno
void
- Tener un solo argumento con una
String[]
. El argumento debe estar presente y no se permite más de un argumento. - Ser genérico: los parámetros de tipo no están permitidos.
- Tener una clase envolvente no genérica, de nivel superior (no anidada o interna)
Es convencional declarar la clase como public
pero esto no es estrictamente necesario. Desde Java 5 en adelante, el tipo de argumento del método main
puede ser una String
varargs en lugar de una cadena de cadenas. Opcionalmente, main
puede lanzar excepciones, y su parámetro puede tener cualquier nombre, pero convencionalmente es args
.
Puntos de entrada de JavaFX
Desde Java 8 en adelante, el comando java
también puede iniciar directamente una aplicación JavaFX. JavaFX está documentado en la etiqueta JavaFX , pero un punto de entrada de JavaFX debe hacer lo siguiente:
- Extender
javafx.application.Application
- Sé
public
y noabstract
- No ser genérico o anidado
- Tener un constructor no-args
public
explícito o implícito
Solución de problemas del comando 'java'
Este ejemplo cubre errores comunes con el uso del comando 'java'.
"Comando no encontrado"
Si recibe un mensaje de error como:
java: command not found
cuando intenta ejecutar el comando java
, esto significa que no hay un comando java
en la ruta de búsqueda de comandos de su shell. La causa podría ser:
- no tienes instalado un JRE o JDK de Java,
- no ha actualizado la
PATH
entornoPATH
(correctamente) en su archivo de inicialización de shell, o - no ha "obtenido" el archivo de inicialización relevante en el shell actual.
Consulte "Instalación de Java" para conocer los pasos que debe seguir.
"No se pudo encontrar o cargar la clase principal"
Este mensaje de error es generado por el comando java
si no ha podido encontrar / cargar la clase de punto de entrada que ha especificado. En términos generales, hay tres razones generales por las que esto puede suceder:
- Ha especificado una clase de punto de entrada que no existe.
- La clase existe, pero la has especificado incorrectamente.
- La clase existe y la ha especificado correctamente, pero Java no puede encontrarla porque la ruta de clase es incorrecta.
Aquí hay un procedimiento para diagnosticar y resolver el problema:
Averigüe el nombre completo de la clase de punto de entrada.
- Si tiene un código fuente para una clase, entonces el nombre completo consiste en el nombre del paquete y el nombre de la clase simple. La instancia de la clase "Main" se declara en el paquete "com.example.myapp" y su nombre completo es "com.example.myapp.Main".
- Si tiene un archivo de clase compilado, puede encontrar el nombre de la clase ejecutando
javap
en él. - Si el archivo de clase está en un directorio, puede inferir el nombre completo de la clase a partir de los nombres de directorio.
- Si el archivo de clase está en un archivo JAR o ZIP, puede inferir el nombre completo de la clase a partir de la ruta del archivo en el archivo JAR o ZIP.
Mira el mensaje de error del comando
java
. El mensaje debe terminar con el nombre completo de la clase quejava
está tratando de usar.- Compruebe que coincida exactamente con el nombre de clase completo para la clase de punto de entrada.
- No debe terminar con ".java" o ".class".
- No debe contener barras o ningún otro carácter que no sea legal en un identificador de Java 1 .
- La carcasa del nombre debe coincidir exactamente con el nombre completo de la clase.
Si está utilizando el nombre de clase correcto, asegúrese de que la clase esté realmente en la ruta de clase:
- Calcula el nombre de ruta al que se asigna el nombre de clase; ver Asignar nombres de clases a rutas de acceso
- Averigua cuál es el classpath; Vea este ejemplo: Diferentes maneras de especificar la ruta de clase.
- Mire cada uno de los archivos JAR y ZIP en la ruta de clase para ver si contienen una clase con la ruta de acceso requerida.
- Mire cada directorio para ver si la ruta de acceso se resuelve en un archivo dentro del directorio.
Si la comprobación del classpath a mano no encontró el problema, puede agregar las opciones -Xdiag
y -XshowSettings
. La primera lista todas las clases que se cargan, y la última imprime configuraciones que incluyen la ruta de clase efectiva para la JVM.
Finalmente, hay algunas causas oscuras para este problema:
- Un archivo JAR ejecutable con un atributo de
Main-Class
que especifica una clase que no existe. - Un archivo JAR ejecutable con un atributo de
Class-Path
incorrecto. - Si se equivoca 2 las opciones antes de que el nombre de la clase, el
java
comando puede tratar de interpretar uno de ellos como el nombre de clase. - Si alguien ha ignorado las reglas de estilo de Java y ha usado identificadores de paquete o clase que difieren solo en letras mayúsculas, y está ejecutando en una plataforma que trata las letras mayúsculas en los nombres de archivo como no significativas.
- Problemas con homoglifos en los nombres de clase en el código o en la línea de comando.
"El método principal no se encuentra en la clase <nombre>"
Este problema ocurre cuando el comando java
puede encontrar y cargar la clase que usted nominó, pero luego no puede encontrar un método de punto de entrada.
Hay tres posibles explicaciones:
- Si está intentando ejecutar un archivo JAR ejecutable, entonces el manifiesto de JAR tiene un atributo "Clase principal" incorrecto que especifica una clase que no es una clase de punto de entrada válida.
- Le ha dicho al comando
java
una clase que no es una clase de punto de entrada. - La clase de punto de entrada es incorrecta; ver Clases de punto de entrada para más información.
Otros recursos
- ¿Qué significa "no se pudo encontrar o cargar la clase principal"?
- http://docs.oracle.com/javase/tutorial/getStarted/problems/index.html
1 - Desde Java 8 y java
posteriores, el comando java
asignará de manera útil un separador de nombre de archivo ("/" o "") a un punto ("."). Sin embargo, este comportamiento no está documentado en las páginas del manual.
2 - Un caso muy oscuro es si copia y pega un comando de un documento formateado donde el editor de texto ha usado un "guión largo" en lugar de un guión normal.
Ejecutando una aplicación Java con dependencias de biblioteca
Esta es una continuación de los ejemplos de "clase principal" y "JAR ejecutable" .
Las aplicaciones Java típicas consisten en un código específico de la aplicación y varios códigos de biblioteca reutilizables que ha implementado o que ha sido implementado por terceros. Estas últimas se conocen comúnmente como dependencias de bibliotecas y, por lo general, se empaquetan como archivos JAR.
Java es un lenguaje enlazado dinámicamente. Cuando ejecuta una aplicación Java con dependencias de biblioteca, la JVM necesita saber dónde están las dependencias para poder cargar las clases según sea necesario. En términos generales, hay dos maneras de lidiar con esto:
La aplicación y sus dependencias se pueden volver a empaquetar en un solo archivo JAR que contiene todas las clases y recursos necesarios.
Se le puede decir a la JVM dónde encontrar los archivos JAR dependientes a través del classpath de tiempo de ejecución.
Para un archivo JAR ejecutable, la ruta de clase de tiempo de ejecución se especifica mediante el atributo de manifiesto "Class-Path". (Nota editorial: Esto se debe describir en un Tema separado en el comando jar
). De lo contrario, la ruta de -cp
tiempo de ejecución debe suministrarse mediante la opción -cp
o la variable de entorno CLASSPATH
.
Por ejemplo, supongamos que tenemos una aplicación Java en el archivo "myApp.jar" cuya clase de punto de entrada es com.example.MyApp
. Supongamos también que la aplicación depende de los archivos JAR de la biblioteca "lib / library1.jar" y "lib / library2.jar". Podríamos iniciar la aplicación usando el comando java
como sigue en una línea de comando:
$ # Alternative 1 (preferred)
$ java -cp myApp.jar:lib/library1.jar:lib/library2.jar com.example.MyApp
$ # Alternative 2
$ export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
$ java com.example.MyApp
(En Windows, usaría ;
lugar de :
como el separador de classpath, y establecería la variable CLASSPATH
(local) usando set
lugar de export
).
Si bien un desarrollador de Java se sentiría cómodo con eso, no es "fácil de usar". Por lo tanto, es una práctica común escribir un script de shell simple (o un archivo por lotes de Windows) para ocultar los detalles que el usuario no necesita conocer. Por ejemplo, si coloca el siguiente script de shell en un archivo llamado "myApp", lo convierte en ejecutable y lo coloca en un directorio en la ruta de búsqueda de comandos:
#!/bin/bash
# The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar
java com.example.MyApp
entonces podrías ejecutarlo de la siguiente manera:
$ myApp arg1 arg2 ...
Cualquier argumento en la línea de comando se pasará a la aplicación Java a través de la expansión "$@"
. (Puedes hacer algo similar con un archivo por lotes de Windows, aunque la sintaxis es diferente).
Espacios y otros caracteres especiales en argumentos.
En primer lugar, el problema de manejar espacios en argumentos NO es realmente un problema de Java. Más bien, es un problema que debe ser manejado por el comando shell que está utilizando cuando ejecuta un programa Java.
Como ejemplo, supongamos que tenemos el siguiente programa simple que imprime el tamaño de un archivo:
import java.io.File;
public class PrintFileSizes {
public static void main(String[] args) {
for (String name: args) {
File file = new File(name);
System.out.println("Size of '" + file + "' is " + file.size());
}
}
}
Ahora supongamos que queremos imprimir el tamaño de un archivo cuyo nombre de ruta tiene espacios en él; Por ejemplo, /home/steve/Test File.txt
. Si ejecutamos el comando así:
$ java PrintFileSizes /home/steve/Test File.txt
el shell no sabrá que /home/steve/Test File.txt
es en realidad un nombre de ruta. En su lugar, pasará 2 argumentos distintos a la aplicación Java, que intentará encontrar sus respectivos tamaños de archivo, y fallará porque los archivos con esas rutas (probablemente) no existen.
Soluciones usando un shell POSIX
Las carcasas POSIX incluyen sh
, así como derivados, como bash
y ksh
. Si está utilizando uno de estos shells, puede resolver el problema citando el argumento.
$ java PrintFileSizes "/home/steve/Test File.txt"
Las comillas dobles alrededor de la ruta de acceso le indican al shell que se debe pasar como un solo argumento. Las citas serán eliminadas cuando esto suceda. Hay un par de otras maneras de hacer esto:
$ java PrintFileSizes '/home/steve/Test File.txt'
Las comillas simples (rectas) se tratan como comillas dobles, excepto que también suprimen varias expansiones dentro del argumento.
$ java PrintFileSizes /home/steve/Test\ File.txt
Una barra invertida escapa al siguiente espacio y hace que no se interprete como un separador de argumentos.
Para obtener una documentación más completa, incluidas las descripciones de cómo tratar otros caracteres especiales en los argumentos, consulte el tema de cita en la documentación de Bash .
Solución para Windows
El problema fundamental para Windows es que, a nivel del sistema operativo, los argumentos se pasan a un proceso secundario como una sola cadena ( fuente ). Esto significa que la responsabilidad final de analizar (o volver a analizar) la línea de comandos recae en el programa o en sus bibliotecas de tiempo de ejecución. Hay mucha inconsistencia.
En el caso de Java, para acortar una larga historia corta:
Puede colocar comillas dobles alrededor de un argumento en un comando
java
, y eso le permitirá pasar argumentos con espacios en ellos.Aparentemente, el comando
java
sí está analizando la cadena de comandos, y lo hace más o menos correctoSin embargo, cuando intenta combinar esto con el uso de
SET
y la sustitución de variables en un archivo por lotes, se vuelve realmente complicado si se eliminan las comillas dobles.El shell
cmd.exe
aparentemente tiene otros mecanismos de escape; por ejemplo, duplicar las comillas dobles y usar^
escapes.
Para más detalles, consulte la documentación de Batch-File .
Opciones de Java
El comando java
soporta una amplia gama de opciones:
Todas las opciones comienzan con un único guión o signo menos (
-
): no se admite la convención de GNU / Linux de usar--
para opciones "largas".Las opciones deben aparecer antes del
<classname>
o del-jar <jarfile>
para ser reconocido. Cualquier argumento posterior a ellos se tratará como argumentos que se pasarán a la aplicación Java que se está ejecutando.Las opciones que no comienzan con
-X
o-XX
son opciones estándar. Puede confiar en todas las implementaciones de Java 1 para admitir cualquier opción estándar.Las opciones que comienzan con
-X
son opciones no estándar y pueden retirarse de una versión de Java a la siguiente.Las opciones que comienzan con
-XX
son opciones avanzadas y también se pueden retirar.
Configurando las propiedades del sistema con -D
La opción -D<property>=<value>
se usa para establecer una propiedad en el objeto Properties
del sistema. Este parámetro se puede repetir para establecer diferentes propiedades.
Opciones de memoria, pila y recolector de basura
Las opciones principales para controlar los tamaños de pila y pila se documentan en Configuración de los tamaños de pila, PermGen y Pila . (Nota editorial: las opciones del recolector de basura se deben describir en el mismo tema).
Habilitar y deshabilitar aserciones
El -ea
y -da
opciones respectivamente habilitar y deshabilitar Java assert
comprobación:
- Todas las comprobaciones de aserción están deshabilitadas por defecto.
- La opción
-ea
permite verificar todas las aserciones. - El
-ea:<packagename>...
habilita la verificación de aserciones en un paquete y todos los subpaquetes . - El
-ea:<classname>...
habilita la verificación de aserciones en una clase. - La opción
-da
desactiva la comprobación de todas las aserciones - El
-da:<packagename>...
deshabilita la verificación de aserciones en un paquete y todos los subpaquetes . - El
-da:<classname>...
deshabilita la verificación de aserciones en una clase. - La opción
-esa
permite verificar todas las clases del sistema. - La opción
-dsa
desactiva la comprobación de todas las clases del sistema.
Las opciones se pueden combinar. Por ejemplo.
$ # Enable all assertion checking in non-system classes
$ java -ea -dsa MyApp
$ # Enable assertions for all classes in a package except for one.
$ java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyApp
Tenga en cuenta que habilitar la verificación de afirmaciones puede alterar el comportamiento de una programación Java.
- Es probable que la aplicación sea más lenta en general.
- Puede hacer que los métodos específicos demoren más en ejecutarse, lo que podría cambiar el tiempo de los subprocesos en una aplicación de subprocesos múltiples.
- Puede introducir relaciones fortuitas antes de que desaparezcan las anomalías de la memoria.
- Un implementado incorrectamente
assert
declaración podría tener efectos secundarios no deseados.
Seleccionando el tipo de máquina virtual
Los -client
y -server
opciones le permiten seleccionar entre dos formas diferentes de la HotSpot VM:
- El formulario "cliente" está optimizado para las aplicaciones de usuario y ofrece un inicio más rápido.
- El formulario "servidor" está optimizado para aplicaciones de larga ejecución. La estadística de captura lleva más tiempo durante el "calentamiento" de JVM, lo que permite al compilador JIT hacer un mejor trabajo de optimización del código nativo.
De forma predeterminada, la JVM se ejecutará en modo de 64 bits si es posible, dependiendo de las capacidades de la plataforma. Las opciones -d32
y -d64
permiten seleccionar el modo explícitamente.
1 - Verifique el manual oficial del comando java
. A veces, una opción estándar se describe como "sujeto a cambio".