Compilar y ejecutar Java desde el terminal

El modelo de ejecución de Java se inicia con el código fuente del programa escrito en lenguaje Java y almacenado en ficheros .java. Dicho código fuente se compila a un código intermedio llamado bytecode, que se guarda en ficheros .class. Finalmente, la máquina virtual de Java (JVM, Java Virtual Machine) ejecuta dicho código. La figura siguiente esquematiza este modelo de ejecución.

La utilización de Eclipse facilita la tarea de compilar y ejecutar nuestros programas Java, aunque hace perder un poco la perspectiva del proceso de compilación y ejecución. En otro artículo anterior ya comente cómo configurar Eclipse para sortear, al menos en parte, este inconveniente.

Creo que es bueno practicar la compilación y ejecución de programas escritos en Java utilizando el terminal. Además de redundar en el dominio de las herramientas, cuando hay que ejecutar un programa con parámetros de entrada, resulta más sencillo hacerlo desde el terminal que desde Eclipse.

En este artículo voy a explicar cómo hacerlo en distintas circunstancias, desde un programa sencillo compuesto de una única clase, hasta programas complejos con varias clases distribuidas en paquetes y que utilizan bibliotecas externas .jar.

Programa con una única clase

El caso más sencillo es cuando tenemos una única clase, Main.java, dentro del directorio del proyecto. La estructura sería la de la siguiente figura:

Para compilar el programa, tendremos que abrir un terminal situado en la carpeta del proyecto y teclear la siguiente instrucción:

javac Main.java

Si todo va bien y el programa no tiene errores, el resultado será que el compilador de Java (javac) creará el fichero Main.class, que es el compilado bytecode de Main.java. La estructura de la carpeta del proyecto quedará:

Puedes comprobarlo tú mismo listando los archivos de la carpeta con la orden dir.

Para ejecutar el programa, hay que utilizar la máquina virtual de Java (JVM) de nuestro sistema, que es el programa java. A la JVM hay que decirle el nombre de la clase que contiene el método main() ejecutable, en este caso:

java Main

Observa que se indica el nombre de la clase, sin extensiones.

Programa con varias clases

Podría suceder que el programa tuviera más de una clase, pero todas en el mismo directorio del proyecto. Por ejemplo, supón que nuestro programa, además de la clase Main.java, utiliza una clase auxiliar llamada Punto.java y que las dos clases están en el directorio del proyecto:

Para compilar, tendremos que indicar a javac el nombre de todas las clases que queramos compilar:

javac Main.java Punto.java

Cuando queremos compilar todos los ficheros .java de una carpeta también se puede usar el comodín * (asterisco), que se puede leer como “todos“:

javac *.java

Esta instrucción compilaría todos los ficheros .java que haya en el directorio. En ambos casos, el resultado será que se crearán los ficheros .class correspondientes:

Para ejecutar el programa, la instrucción sería la misma que antes. Aunque haya varios .class, al invocar la JVM solo hay que pasarle el nombre de la clase que contiene el método main():

java Main

Esta estructura, con los ficheros .java y los ficheros .class en el mismo directorio, es la que resulta al crear el proyecto con Eclipse y seleccionar la opción “Use project folder as root for sources and class files”, como muestra la siguiente figura:

Redirigir los .class al directorio bin

En el apartado anterior, el fichero .class que se genera al compilar, lo hemos guardado en el mismo directorio del proyecto donde teníamos los ficheros .java. Es habitual que los ficheros compilados de un proyecto se guarden en un directorio diferente, por ejemplo en el directorio bin.

Podemos indicar al compilador de Java en qué directorio queremos que ponga los ficheros .class compilados, utilizando el parámetro -d. La orden que habría que teclear en el terminal sería:

javac -d bin *.java

Con esta orden, se compilarán todos los ficheros .java que haya en la carpeta del proyecto y los ficheros .class resultantes se pondrán en el directorio bin. La estructura de carpetas y ficheros, despues de compilar, quedaría:

Para ejecutar el programa resultante, hay que indicar a la JVM el nombre de la clase que contiene el método main(). Además, hay que indicar a la JVM la ruta donde tiene que buscar las clases compiladas, utilizando el parámetro -classpath o su forma abreviada -cp. Si ejecutamos la instrucción desde el directorio del proyecto, la orden que hay que teclear es:

java -cp bin Main

La instrucción anterior le dice a la máquina virtual: “Las clases compiladas están en la carpeta bin y tienes que ejecutar la clase Main”.

Caso general: directorios src y bin

El caso general sería el de un proyecto que tiene los ficheros fuente .java en el directorio src, repartidos en distintos paquetes. Además, queremos que los ficheros .class de las clases compiladas se guarden en el directorio bin. La estructura de ficheros antes de la compilación podría ser la siguiente:

Por supuesto, los ficheros .java de las clases tendrán que tener indicadas las instrucciones package que les corresponda en cada caso.

Con el terminal situado en la carpeta del proyecto, la orden para compilar todo y hacer la salida de los .class al directorio bin es la siguiente:

javac -d bin src\geometria\*.java src\principal\*.java 

En este caso, le estamos pidiendo al compilador que compile todos los ficheros .java que haya en las carpetas src\geometria y src\principal y coloque los ficheros compilados en la carpeta bin.

El resultado sería el siguiente:

Observa que los ficheros compilados .class quedan dentro de la carpeta bin, organizados con la misma estructura de paquetes que tienen en la carpeta src del código fuente.

Para ejecutar el programa, habrá utilizar el parámetro -cp, para indicar a la JVM la ruta donde tiene que buscar las clases compiladas y decirle el nombre de la clase que queremos ejecutar:

java -cp bin principal.Main

Fíjate en que el nombre de la clase que queremos ejecutar tiene que llevar como prefijo el paquete en el que se encuentre dicha clase. Lo que le decimos a la máquina virtual de Java es: “busca las clases compiladas en la carpeta bin y ejecuta la clase principal.Main”.

Esta estructura de carpetas es la que crea Eclipse al crear un proyecto cuando elegimos la opción “Create separate folders for sources and class files“.

Ejecutar programas con parámetros de entrada

La primera vez que queramos ejecutar desde Eclipse un programa que requiere parámetros de entrada, habrá que crear una configuración de ejecución (Run configuration). Se accede a través de la opción de menú “Run -> Run configurations” o pichando sobre la clase que tiene el método main() con el botón derecho del ratón y seleccionando “Run as -> Run configurations“.

Dentro del diálogo que aparece, habrá que seleccionar la pestaña “Arguments” y poner el valor de los argumentos que queramos pasar al programa dentro del recuadro “Program arguments“, como muestra la figura siguiente:

Cada vez que queramos ejecutar el programa, cambiando el valor de los argumentos, habrá que abrir la configuración de ejecución y modificar el valor de los mismos. Es un proceso ineficiente y tedioso.

Si ejecutamos el programa desde el terminal, es mucho más sencillo. Refiriéndonos al ejemplo utilizado anteriormente, si quisiéramos ejecutar Main y pasarle dos argumentos, la orden que habría que teclear en el terminal sería:

java -cp bin principal.Main argumento1 argumento2

Queda claro que el proceso es más sencillo. Ademas, no necesitaríamos compilar desde la consola. Podemos estar usando Eclipse, que se encargará de compilar automáticamente nuestros ficheros fuente y utilizar el terminal simplemente para ejecutar el programa.

Utilización de bibliotecas .jar

Algunos programas utilizan bibliotecas externas .jar que contienen clases compiladas. Imagina que la estructura de nuestro proyecto es la de la siguiente figura:

El proyecto, además de las clases propias, utiliza clases de biblioteca.jar. Para compilar este proyecto tendremos que decir al compilador:

  • En qué directorio queremos poner las clases compiladas: parámetro -d.
  • Dónde puede encontrar las clases compiladas que necesite: parámetro -cp.
  • Qué ficheros .java queremos que compile.

La orden que habría que teclear en la consola sería:

javac -d bin -cp lib\biblioteca.jar src\principal\*.java src\geometria\*.java

Como resultado, el compilador creará el directorio bin con las clases compiladas dentro de él, organizadas en los paquetes que corresponda, como muestra la figura siguiente:

Para ejecutar el programa, será necesario indicar a la JVM que hay clases compiladas que las tiene que buscar en el directorio bin y otras que están en biblioteca.jar. La orden sería la siguiente:

java -cp bin;lib\biblioteca.jar principal.Main

Observa que en el parámetro -cp se han puesto dos rutas para clases compiladas, separadas por punto y coma.

En Eclipse, para incorporar una biblioteca externa a nuestro proyecto hay que utilizar la opción de menú “Project -> Properties -> Java Build Path“. En la pestaña Libraries, habrá que añadir el fichero biblioteca.jar al classpath, como muestra la siguiente figura:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *