La plataforma Java
Qué hay dentro de una instalación de Java, en qué se diferencia el kit de desarrollo del entorno de ejecución, cómo funciona por dentro la máquina virtual y qué separa la edición estándar de la empresarial.
Qué es la plataforma Java y qué es el JDK
Java no es solo un lenguaje. Una plataforma Java son tres cosas a la vez: una infraestructura de ejecución (la máquina virtual y sus utilidades), un lenguaje de programación orientado a objetos y un catálogo enorme de librerías, unas de la propia plataforma y otras de terceros. Cuando en un examen se habla de «la plataforma Java» se habla del conjunto, no del lenguaje suelto.
El JDK (Java Development Kit) es el paquete de quien programa. Trae el compilador, el lanzador y un conjunto de herramientas de línea de comandos para empaquetar, documentar, depurar, firmar y analizar. Instalar un JDK basta para desarrollar y ejecutar; instalar solo el entorno de ejecución basta para ejecutar, pero no para compilar.
El ciclo es siempre el mismo: se escribe el código fuente en ficheros .java, el compilador javac lo traduce a ficheros .class y el lanzador java arranca la máquina virtual, que ejecuta ese contenido. Lo que produce el compilador no es código nativo del procesador, sino un código intermedio llamado bytecode.
# compilar el fuente del catálogo de temas
javac -d destino com/llegandoalcorte/temario/Tema.java
# lo que queda es bytecode, no código de la máquina
# destino/com/llegandoalcorte/temario/Tema.class
# ejecutarlo: arranca la JVM y le da esa clase
java -cp destino com.llegandoalcorte.temario.TemaJava es compilado e interpretado a la vez, y esa doble condición es la pregunta clásica: javac compila a bytecode y la máquina virtual ejecuta ese bytecode. Ni «solo compilado» ni «solo interpretado».
Para el examen
Naturaleza de Java: compilado E interpretado
javac: traduce el fuente .java a bytecode .class
Quién ejecuta el bytecode: la máquina virtual
JDK frente a JRE: el JDK trae compilador y herramientas; el JRE solo ejecuta
Las herramientas de línea de comandos del JDK
Un JDK no es solo un compilador: es una caja de herramientas. En un examen tipo test lo que se pregunta es para qué sirve cada una, así que conviene tenerlas asociadas a una función de una sola línea.
| Herramienta | Para qué sirve |
|---|---|
| javac | Compila el fuente .java a bytecode .class |
| java | Lanza la máquina virtual y ejecuta el bytecode |
| jshell | Consola interactiva de Java para probar líneas sueltas, desde Java 9 |
| javadoc | Genera documentación HTML a partir de los comentarios del fuente |
| jar | Empaqueta clases compiladas y recursos en un único fichero .jar |
| jarsigner | Firma digitalmente un .jar y verifica su firma |
| keytool | Gestiona el almacén de claves y certificados de la plataforma |
| javap | Desensambla un .class y reconstruye su declaración a partir de los metadatos |
| jdb | Depurador de línea de comandos |
| jdeps | Analiza de qué clases, paquetes o módulos depende un programa |
| jlink | Monta un runtime a medida solo con los módulos que el programa usa, desde Java 9 |
| jpackage | Genera el instalable nativo (msi, deb, dmg) de una aplicación, desde Java 16 |
| jconsole y jmc | Monitorizan una máquina virtual en marcha: memoria, hilos, rendimiento |
| wsimport | Genera las clases del cliente de un servicio web SOAP a partir de su WSDL |
| xjc | Genera clases Java a partir de un esquema XSD |
Dos matices de versión que se prestan a confusión: la herramienta jjs y el motor de JavaScript Nashorn que la sostenía se marcaron obsoletos en Java 11 y se eliminaron en Java 15, mientras que JDK Mission Control (jmc) no desapareció, sino que dejó de venir dentro del JDK y se distribuye aparte.
Para el examen
javac y java: compila y ejecuta
jar y javadoc: empaqueta y documenta
keytool y javap: gestiona claves y desensambla
jdb y jshell: depurador y consola interactiva, esta desde Java 9
El JRE, la máquina virtual y el CLASSPATH
El JRE (Java Runtime Environment) es lo mínimo para ejecutar: la máquina virtual más las librerías de clases básicas de la plataforma. Es lo que se instalaba en los entornos de producción, donde no hace falta compilar nada. Históricamente esas clases base viajaban en un fichero rt.jar; desde el sistema de módulos de Java 9 viven en el módulo java.base.
La JVM (Java Virtual Machine) es el software que ejecuta el bytecode. Es la pieza que hace que el mismo .class funcione en Windows, en Linux o en un mainframe: lo que cambia de un sistema a otro es la máquina virtual, no el programa.
El CLASSPATH es la ruta de búsqueda de clases: le dice a la máquina virtual dónde encontrar las clases que el programa necesita y que no son las suyas propias ni las de la biblioteca base. Si una clase no está en el classpath, el programa compila pero revienta en ejecución al intentar cargarla.
| Pieza | Qué contiene | A quién le hace falta |
|---|---|---|
| JDK | JRE más compilador y herramientas de desarrollo | Quien programa |
| JRE | JVM más las librerías de clases base | Quien solo ejecuta la aplicación |
| JVM | El motor que carga y ejecuta el bytecode | Está dentro del JRE, no se instala suelta |
JDK contiene al JRE, y el JRE contiene a la JVM. Es una relación de muñecas rusas, y confundir el orden es el error más repetido del tema.
Para el examen
Relación de las tres: el JDK contiene al JRE y el JRE contiene a la JVM
CLASSPATH: la ruta donde la máquina virtual busca las clases
Si falta una clase: el fallo aparece en ejecución, no al compilar
La máquina virtual por dentro y las formas de fijar el classpath
La máquina virtual no es una caja negra: está especificada públicamente en el documento «Java Virtual Machine Specification», precisamente para que cualquiera pueda fabricar una máquina virtual propia compatible. De ahí sale el lema de la plataforma: escribir una vez y ejecutar en cualquier sitio, porque los programas no se compilan contra un procesador concreto sino contra uno virtual.
- Cargador de clases (class loader): localiza los ficheros .class y los trae a memoria cuando hacen falta, no todos de golpe al arrancar.
- Montón (heap): la zona de memoria donde viven los objetos. Es compartida por todos los hilos, y por eso es donde aparecen los problemas de concurrencia.
- Pila (stack): una por hilo. Guarda las llamadas a métodos en curso y sus variables locales, que por tanto son privadas de cada hilo.
- Motor de ejecución: interpreta el bytecode y, cuando detecta código que se repite mucho, lo pasa al compilador JIT (Just In Time), que lo traduce a código nativo para que vaya más rápido.
- Recolector de basura (Garbage Collector): libera la memoria de los objetos a los que ya no apunta nadie. En Java no se libera memoria a mano.
Sobre el classpath, hay tres formas de indicárselo a la máquina virtual, y conviene distinguirlas porque se preguntan juntas: la variable de entorno CLASSPATH del sistema, la opción de la línea de comandos en el momento de lanzar la aplicación, y la entrada Class-Path del fichero de manifiesto que va dentro de un .jar.
# 1. variable de entorno (afecta a todo lo que se lance en esa sesión)
export CLASSPATH=/opt/llegandoalcorte/lib/temario.jar
# 2. al lanzar (lo habitual: solo afecta a esta ejecución)
java -classpath lib/temario.jar:lib/tests.jar com.llegandoalcorte.Simulacro
# 3. dentro del propio .jar, en META-INF/MANIFEST.MF
# Class-Path: lib/temario.jar lib/tests.jarPara el examen
Sus piezas: cargador de clases, montón, pila, motor de ejecución y recolector de basura
Montón (heap): los objetos; compartido
Pila (stack): una por hilo
JIT: el compilador dentro del motor de ejecución
Cómo se fija el classpath: variable de entorno, línea de comandos o manifiesto del .jar
Ediciones de Java: SE, EE y ME
AMPLIADO (el enunciado oficial contrapone la edición estándar y la empresarial, y los PDF no lo desarrollan). La plataforma Java se reparte en ediciones, que no son versiones distintas del lenguaje sino conjuntos distintos de APIs sobre el mismo lenguaje y la misma máquina virtual.
| Edición | Qué es | Para qué se usa |
|---|---|---|
| Java SE (Standard Edition) | El lenguaje, la máquina virtual y la API básica: colecciones, entrada y salida, red, concurrencia, JDBC | Aplicaciones de escritorio, utilidades, servicios, y base de todo lo demás |
| Jakarta EE (Enterprise Edition, antes Java EE) | Un conjunto de especificaciones que se añaden encima de Java SE y que implementa un servidor de aplicaciones | Aplicaciones empresariales de servidor: web, transacciones, mensajería, persistencia |
| Java ME (Micro Edition) | Subconjunto reducido para dispositivos con poca memoria | Dispositivos empotrados y, en su día, teléfonos |
La edición empresarial no sustituye a la estándar: la presupone. Un servidor de aplicaciones Jakarta EE se ejecuta sobre una JVM normal y sobre la API de Java SE, y lo que aporta encima son los servicios que una aplicación de empresa da por hechos: gestión de peticiones HTTP, transacciones distribuidas, colas de mensajes, inyección de dependencias y persistencia.
En el lado del cliente, la historia dio un giro. En los años noventa el modelo era el applet, un programa Java que se descargaba en el navegador y se ejecutaba en la máquina virtual del puesto del usuario. Los applets están descatalogados y ya no funcionan en ningún navegador actual; hoy Java en el mundo web es un asunto de servidor.
Jakarta EE no es «otro Java»: es Java SE más un catálogo de especificaciones de servidor. Todo lo del subtema «La plataforma Java» (JVM, bytecode, classpath) sigue valiendo igual dentro de un servidor de aplicaciones.
Para el examen
Java SE: el lenguaje, la JVM y la API básica
Jakarta EE: especificaciones de servidor, ENCIMA de Java SE
Java ME: subconjunto para dispositivos
Applets: descatalogados