Capítulo 1. Primeros pasos: Compilar y ejecutar Java

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

1.0 Introducción

Este capítulo abarca algunas tareas básicas que debes saber hacer antes de poder continuar. Se dice que hay que gatear antes de poder andar, y andar antes de poder montar en bicicleta. Antes de que puedas probar nada en este libro, tienes que ser capaz de compilar y ejecutar tu código Java, así que empiezo por ahí, mostrando varias formas de hacerlo: a la manera del JDK, a la manera del Entorno de Desarrollo Integrado (IDE) y a la manera de las herramientas de compilación (Ant, Maven, etc.). Otro problema con el que se encuentra la gente es la configuración correcta de CLASSPATH, así que lo trataré a continuación. Después vienen las advertencias de desaprobación, porque es probable que te las encuentres al mantener código Java antiguo. El capítulo termina con información general sobre compilación condicional, pruebas unitarias, aserciones y depuración.

Si aún no tienes Java instalado, tendrás que descargarlo. Ten en cuenta que hay varias descargas diferentes. La JRE (Java Runtime Environment) era, hasta Java 8, una descarga más pequeña para los usuarios finales. Dado que hay mucho menos Java de escritorio que antes, la JRE se eliminó en favor de jlink para hacer una descarga personalizada (ver Receta 15.8). La descarga del JDK o Java SDK es el entorno de desarrollo completo, que querrás si vas a desarrollar software Java.

Las descargas estándar de la versión actual de Java están disponibles en, en el sitio web de Oracle.

A veces puedes encontrar versiones preliminares de la siguiente versión principal de Java en http://jdk.java.net. Todo el JDK se mantiene como un proyecto de código abierto, y el árbol de código fuente de OpenJDK se utiliza (con cambios y añadidos) para crear los JDK comerciales y compatibles de Oracle.

Si ya estás contento con tu IDE, puede que quieras saltarte parte o todo este material. Está aquí para asegurarnos de que todo el mundo puede compilar y depurar sus programas antes de que avancemos.

1.1 Compilar y ejecutar Java: JDK estándar

Problema

Tienes que compilar y ejecutar tu programa Java.

Solución

Esta es una de las pocas áreas en las que el sistema operativo de tu ordenador influye en la portabilidad de Java, así que vamos a quitarnos estos problemas de encima primero.

JDK

Utilizar el Kit de Desarrollo de Java (JDK) desde la línea de comandos puede ser la mejor manera de estar al día de las últimas mejoras de Java. Suponiendo que tengas el JDK estándar instalado en la ubicación estándar y/o hayas establecido su ubicación en tu PATH, deberías poder ejecutar las herramientas JDK de la línea de comandos. Utiliza los comandosjavac para compilar y java para ejecutar tu programa (y, sólo en Windows, javaw para ejecutar un programa sin una ventana de consola), de esta forma:

C:\javasrc>javac HelloWorld.java

C:\javasrc>java HelloWorld
Hello, World

C:\javasrc>

Si el programa hace referencia a otras clases cuyo código fuente está disponible (en el mismo directorio) y no existe un archivo .class compilado, javac lo compilará automáticamente por ti. A partir de Java 11, para los programas sencillos que no necesiten esa co-compilación, puedes combinar las dos operaciones pasando simplemente el archivo fuente de Java al comando java:

	$ java HelloWorld.java
	Hello, Java
	$
	

Como puedes ver por la (falta de) salida del compilador, tanto javac como la compilación java funcionan según la filosofía Unix de "ninguna noticia es una buena noticia": si un programa ha sido capaz de hacer lo que le has pedido, no debería molestarse en parlotearte para decirte que lo ha hecho.

Existe un ajuste opcional llamado CLASSPATH , comentado en la Receta 1.5, que controla dónde busca Java las clases. CLASSPATH, si se establece, es utilizado tanto por javac como por java. En versiones antiguas de Java, tenías que configurar tu CLASSPATH para que incluyera "." incluso para ejecutar un programa sencillo desde el directorio actual; esto ya no es así en las implementaciones actuales de Java .

El compilador javac de Sun/Oracle es la implementación oficial de referencia. Hubo varios compiladores alternativos de línea de comandos de código abierto, como Jikes y Kaffe, pero, en su mayor parte, ya no se mantienen activamente.

También ha habido algunos clones del runtime de Java, como Apache Harmony, Japhar, el IBM Jikes Runtime (del mismo sitio que Jikes), e incluso JNode, un sistema operativo completo e independiente escrito en Java; pero desde que la JVM de Sun/Oracle es de código abierto (GPL), la mayoría de estos proyectos han dejado de mantenerse. Harmony fue retirado por Apache en noviembre de 2011.

macOS

El JDK es pura línea de comandos. En el otro extremo del espectro en términos de teclado versus visual, tenemos el Macintosh de Apple. Se han escrito libros sobre lo genial que es la interfaz de usuario del Mac, y no voy a entrar en ese debate. macOS (versión 10.x del SO) está construido sobre una base BSD Unix (y "Mach"). Como tal, tiene una línea de comandos normal (la aplicación Terminal, oculta en /Aplicaciones/Utilidades), así como las herramientas de línea de comandos tradicionales de Unix y las herramientas gráficas de Mac. Si utilizas macOS, puedes utilizar las herramientas JDK de línea de comandos o cualquiera de las herramientas de compilación modernas. Las clases compiladas pueden empaquetarse en aplicaciones clicables utilizando el Jar Packager del que se habla en la Receta 15.6. Los aficionados a Mac pueden utilizar una de las muchas herramientas IDE completas que se comentan en la Receta 1.3. Apple proporciona XCode como IDE, pero fuera de la caja no es muy compatible con Java.

1.2 Compilar y ejecutar Java: GraalVM para un mejor rendimiento

Problema

Has oído que Graal es una JVM de Oracle más rápida que el JDK estándar, y quieres probarla. Graal promete ofrecer mejor rendimiento, y ofrece la posibilidad de mezclar y combinar lenguajes de programación y precompilar tu código Java en forma ejecutable para una plataforma determinada.

Solución

Descarga e instala GraalVM.

Debate

GraalVM se presenta como "una máquina virtual universal para ejecutar aplicaciones escritas en JavaScript, Python, Ruby, R, lenguajes basados en JVM como Java, Scala, Clojure, Kotlin, y lenguajes basados en LLVM como C y C++".

Ten en cuenta que Graal está experimentando rápidos cambios. Aunque esta receta refleja la información más reciente en el momento de su publicación (finales de 2019), es posible que haya versiones más recientes y funcionalidades modificadas para cuando estés listo para instalarlo.

Al cierre de esta edición, GraalVM se basa en OpenJDK 11, lo que significa que puedes utilizar Módulos y otras características de Java 9, 10 y 11, pero no tiene soporte para las características de Java 12, 13 o 14. Puedes construir tu propio Graal en versiones posteriores, ya que el código fuente completo está en GitHub.

Consulta el sitio web de GraalVM para obtener más información sobre GraalVM. Consulta tambiénesta presentaciónde Chris Thalinger, que ha trabajado en JVMs durante década y media.

Comienza en la página de descargas.Tendrás que elegir entre la Community Edition y la Enterprise Edition. Para evitar problemas de licencias, esta receta comienza con la Community Edition. Puedes descargar un tarball para Linux, macOS y Windows. En este momento no existe un instalador formal. Para instalarlo, abre una ventana de terminal e intenta lo siguiente (el directorio elegido es para macOS):

$ cd /Library/Java/JavaVirtualMachines
$ tar xzvf ~/Downloads/graalvm-ce-NNN-VVV.tar.gz # replace with actual version
$ cd
$ /usr/libexec/java_home -V # macOS only
11.0.2, x86_64:	"OpenJDK 11.0.2"
	/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home
   1.8.0_221, x86_64:	"GraalVM CE 19.2.0.1"
	/Library/Java/JavaVirtualMachines/graalvm-ce-19.2.0.1/Contents/Home
$

En otros sistemas, haz la instalación en un lugar sensato. En la mayoría de las versiones de Linux, después de instalar un JDK, puedes utilizar elcomando estándar de Linuxalternatives para convertirlo en tu JVM por defecto. En MacOS, la salida del comando java_home confirma que has instalado GraalVM, pero que aún no es tu JVM por defecto. Para ello, tienes que configurar tu PATH:

export JAVA_HOME=<where you installed GraalVM>/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH

Asegúrate de incluir el :$PATH al final de la línea -sin espacios- o todas tus herramientas estándar de la línea de comandos parecerán desaparecer (si cometiste este error, simplemente cierra la sesión y vuelve a entrar para restaurar tu ruta). Te sugiero que no actualices tus scripts de inicio de sesión hasta que estés seguro de que la configuración que tienes es correcta.

Ahora deberías estar ejecutando la versión Graal de Java. Esto es lo que deberías ver:

$ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build
  1.8.0_222-20190711112007.graal.jdk8u-src-tar-gz-b08)
OpenJDK 64-Bit GraalVM CE 19.2.0.1 (build 25.222-b08-jvmci-19.2-b02, mixed mode)

El resultado puede ser distinto, pero si pone "GraalVM", todo irá bien.

Graal incluye una serie de herramientas útiles, como native-image, que en algunos casos puede traducir un archivo de clase en un ejecutable binario para la plataforma en la que se ejecuta, optimizando la velocidad de inicio y reduciendo también el tamaño de descarga necesario para ejecutar una sola aplicación. La herramienta native-image debe descargarse por separado mediantegu install native-image.

Exploraremos la ejecución de algunos de los otros lenguajes que no son Java en la Receta 18.4.

1.3 Compilar, ejecutar y probar con un IDE

Problema

Es engorroso utilizar varias herramientas para las distintas tareas de desarrollo.

Solución

Utiliza un Entorno de Desarrollo Integrado (IDE), que combina edición, pruebas, compilación, ejecución, depuración y gestión de paquetes.

Debate

Muchos programadores consideran que utilizar un puñado de herramientas separadas -un editor de texto, un compilador y un programa de ejecución, por no hablar de un depurador- es demasiado. Un IDE integra todas ellas en un único conjunto de herramientas con una interfaz gráfica de usuario. Existen muchos IDE, y los mejores son herramientas totalmente integradas con sus propios compiladores y máquinas virtuales. Los navegadores de clases y otras funciones de los IDE completan el conjunto de características de facilidad de uso de estas herramientas. Hoy en día, la mayoría de los desarrolladores utilizan un IDE debido a las ganancias de productividad. Aunque yo empecé siendo un adicto a la línea de comandos, creo que las funciones de IDE como las siguientes me hacen más productivo:

Completar código:: La Regla de Ian aquí es que nunca escribo más de tres caracteres de ningún nombre conocido por el IDE; ¡deja que el ordenador escriba!Funciones de compilación incremental:: Anota e informa de los errores de compilación mientras escribes, en lugar de esperar a que hayas terminado de escribir.Refactorización:: La capacidad de hacer cambios de gran alcance, pero que preserven el comportamiento, en una base de código sin tener que editar manualmente docenas de archivos individuales.

Aparte de eso, no pretendo debatir los méritos del IDE frente al proceso de línea de comandos; yo utilizo ambos modos en momentos distintos y en proyectos diferentes. Sólo voy a mostrar algunos ejemplos de uso de un par de IDE basados en Java.

Los tres IDE de Java más populares, que funcionan en todas las plataformas informáticas principales y en bastantes de nicho, son Eclipse, NetBeans e IntelliJ IDEA. Eclipse es el más utilizado, pero cada uno de los otros ocupa un lugar especial en el corazón y la mente de algunos desarrolladores. Si desarrollas para Android, la ADT se ha desarrollado tradicionalmente para Eclipse, pero ahora ha pasado a IntelliJ como base para Android Studio, que es el IDE estándar para Android, y para la otra plataforma móvil de Google, Flutter. Los tres IDE se basan en plug-ins y ofrecen una amplia selección de plug-ins opcionales y de terceros para mejorar el IDE, como la compatibilidad con otros lenguajes de programación, marcos y tipos de archivos. Aunque el párrafo siguiente muestra la creación y ejecución de un programa con Eclipse, los IDE IntelliJ IDEA y NetBeans ofrecen capacidades similares.

Uno de los IDE multiplataforma y de código abierto más populares para Java es Eclipse, originario de IBM y ahora dirigido por la Fundación Eclipse, sede de muchos proyectos de software, como Jakarta, la continuación de Java Enterprise Edition. La plataforma Eclipse también se utiliza como base de otras herramientas, como SpringSource Tool Suite (STS) y Rational Application Developer (RAD) de IBM. Todos los IDE hacen básicamente lo mismo cuando empiezas. El ejemplo de la Figura 1-1 muestra el inicio de un nuevo proyecto.

jcb4 0101
Figura 1-1. Iniciar un nuevo proyecto con el Asistente para nueva clase Java de Eclipse

El Asistente para nueva clase Java de Eclipse que se muestra enla Figura 1-2 muestra la creación de una nueva clase.

jcb4 0102
Figura 1-2. Creación de una nueva clase con el Asistente para nueva clase Java de Eclipse

Eclipse, como todos los IDE modernos, incorpora una serie de funciones de refactorización, que se muestran en la Figura 1-3.

jcb4 0103
Figura 1-3. Refactorización en Eclipse

Y, por supuesto, todos los IDE te permiten ejecutar y/o depurar tu aplicación.La Figura 1-4 muestra la ejecución de una aplicación; por variedad y neutralidad, se muestra utilizando IntelliJ IDEA.

macOS incluye las herramientas para desarrolladores de Apple. El IDE principal es Xcode. Por desgracia, las versiones actuales de Xcode no son realmente compatibles con el desarrollo Java, por lo que no puedo recomendarlo para nuestros fines; es principalmente para quienes construyen aplicaciones no portables (sólo para iOS o sólo para OS X) en los lenguajes de programación Swift u Objective-C. Así que, aunque estés en OS X, para desarrollar en Java debes utilizar uno de los tres IDE de Java.

Microsoft VSCode (antes parte de Visual Studio) ha estado recibiendo cierta atención en los círculos Java últimamente, pero no es un IDE específico de Java. Pruébalo si quieres.

¿Cómo eliges un IDE? Quizá lo dicte tu organización o lo elijan por mayoría tus compañeros desarrolladores. Dado que los tres IDE principales (Eclipse, NetBeans e IntelliJ) pueden descargarse gratuitamente y son 100% de código abierto, ¿por qué no probarlos todos y ver cuál se adapta mejor al tipo de desarrollo que haces? Independientemente de la plataforma que utilices para desarrollar Java, si tienes un runtime Java, deberías tener un montón de IDE entre los que elegir.

jcb4 0104
Figura 1-4. Salida del programa IntelliJ

Ver también

El sitio web de cada IDE mantiene una lista actualizada de recursos, incluidos libros. Consulta la Tabla 1-1 para conocer el sitio web de cada una.

Tabla 1-1. Los tres principales IDE de Java y sus sitios web
Nombre del producto URL del proyecto Nota

Eclipse

https://eclipse.org/

Base del STS, RAD

Idea IntelliJ

https://jetbrains.com/idea/

Bases de Android Studio

Netbeans

https://netbeans.apache.org

Ejecutar en cualquier lugar JavaSE

Estos IDE principales son extensibles; consulta su documentación para obtener una lista de los muchísimos plug-ins disponibles. La mayoría de ellos te permiten buscar e instalar plug-ins desde el IDE. En el caso de Eclipse, utiliza Eclipse Marketplace, cerca de la parte inferior del menú Ayuda. Como último recurso, si necesitas/quieres escribir un plug-in que amplíe la funcionalidad de tu IDE, también puedes hacerlo, y en Java.

Para Eclipse, tengo información útil enhttps://darwinsys.com/java. El sitio incluye una lista de atajos para ayudar a la productividad de los desarrolladores.

1.4 Explorar Java con JShell

Problema

Quieres probar expresiones y API de Java rápidamente, sin tener que crear cada vez un archivo con public class X { public static void main(String[] args) { …​ }.

Solución

Utiliza JShell, el intérprete REPL (Read-Evaluate-Print-Loop) de Java.

Debate

A partir de Java 11, JShell se incluye como parte estándar de Java. Te permite introducir expresiones Java y hacer que se evalúen sin la molestia de crear una clase y un programa principal. Puedes utilizarlo para cálculos rápidos, para probar una API para ver cómo funciona, o para casi cualquier propósito; si encuentras una expresión que te guste, puedes copiarla en un archivo fuente regular de Java y hacerla permanente. JShell también puede utilizarse como lenguaje de scripting sobre Java, pero la sobrecarga de iniciar la JVM significa que no será tan rápido como awk, Perl o Python para un scripting rápido.

Los programas REPL son muy prácticos, y apenas son una idea nueva (los lenguajes LISP de los años 50 los incluían). Puedes pensar en los intérpretes de línea de comandos (CLI), como los shells Bash o Ksh en UNIX/Linux, o Command.com y PowerShell en Microsoft Windows, como REPLs para el sistema en su conjunto. Muchos lenguajes interpretados, como Ruby y Python, también pueden utilizarse como REPL. Java tiene por fin su propio REPL, JShell. Aquí tienes un ejemplo de uso:

$ jshell
|  Welcome to JShell -- Version 11.0.2
|  For an introduction type: /help intro

jshell> "Hello"
$1 ==> "Hello"

jshell> System.out.println("Hello");
Hello

jshell> System.out.println($1)
Hello

jshell> "Hello" + sqrt(57)
|  Error:
|  cannot find symbol
|    symbol:   method sqrt(int)
|  "Hello" + sqrt(57)
|            ^--^

jshell> "Hello" + Math.sqrt(57)
$2 ==> "Hello7.54983443527075"

jshell> String.format("Hello %6.3f", Math.sqrt(57)
   ...> )
$3 ==> "Hello  7.550"

jshell> String x = Math.sqrt(22/7) + " " + Math.PI +
   ...> " and the end."
x ==> "1.7320508075688772 3.141592653589793 and the end."

jshell>

Aquí puedes ver algunas características y ventajas evidentes:

  • El valor de una expresión se imprime sin necesidad de llamar cada vez a System.out.println, pero puedes llamarlo si quieres.

  • A los valores que no se asignan a una variable se les asignan identificadores sintéticos, como $1, que pueden utilizarse en sentencias posteriores.

  • El punto y coma al final de una declaración es opcional (a menos que escribas más de una declaración en una línea).

  • Si cometes un error, recibes inmediatamente un mensaje de ayuda.

  • Puedes obtener la finalización con una sola tabulación, como en la finalización del nombre de archivo del intérprete de comandos.

  • Puedes obtener la parte correspondiente de la documentación Javadoc sobre clases o métodos conocidos con sólo pulsar dos veces el tabulador.

  • Si omites un cierre de comillas, un paréntesis u otro signo de puntuación, JShell se limitará a esperarte, dando un aviso de continuación (…​).

  • Si cometes un error, puedes utilizar el "historial del intérprete de comandos" (es decir, la flecha hacia arriba) para recordar la declaración y poder repararla.

JShell también es útil para crear prototipos de código Java. Por ejemplo, quería uno de esos temporizadores con temas de salud que te recuerdan que debes levantarte y moverte un poco cada media hora:

$ jshell
|  Welcome to JShell -- Version 11.0.2
|  For an introduction type: /help intro

jshell> while (true) { sleep (30*60); JOptionPane.showMessageDialog(null,
  "Move it"); }
|  Error:
|  cannot find symbol
|    symbol:   method sleep(int)
|  while (true) { sleep (30*60); JOptionPane.showMessageDialog(null, "Move it");}
|                 ^---^
|  Error:
|  cannot find symbol
|    symbol:   variable JOptionPane
|  while (true) { sleep (30*60); JOptionPane.showMessageDialog(null, "Move it");}
|                                ^---------^

jshell> import javax.swing.*;

jshell> while (true) { Thread.sleep (30*60); JOptionPane.showMessageDialog(null,
"Move it"); }

jshell> while (true) { Thread.sleep (30*60 * 1000);
  JOptionPane.showMessageDialog(null, "Move it"); }

jshell> ^D

Luego puse la versión final de trabajo en un archivo Java llamado MoveTimer.java, puse una declaración class y un método main() alrededor de la línea principal, le dije al IDE que reformateara todo y lo guardé en mi repositorio darwinsys-api.

Así que adelante, experimenta con JShell. Lee el tutorial introductorio incorporado para obtener más detalles. Cuando obtengas algo que te guste, utiliza /save, o cópialo y pégalo en un programa Java y guárdalo.

Lee más sobre JShell en eltutorial de JShell deOpenJDK.

1.5 Utilizar CLASSPATH con eficacia

Problema

Necesitas mantener tus archivos de clase en un directorio común, o estarás luchando con CLASSPATH.

Solución

Establece en CLASSPATH la lista de directorios y/o archivos JAR que contienen las clases que deseas.

Debate

CLASSPATH es una lista de archivos de clases en cualquiera de una serie de directorios, archivos JAR o archivos ZIP. Al igual que el que utiliza tu sistema para encontrar programas, el es utilizado por el tiempo de ejecución de Java para encontrar clases. Incluso cuando escribes algo tan simple como PATH CLASSPATH java HolaMundo, el intérprete de Java busca en cada uno de los lugares nombrados en tu hasta que encuentra una coincidencia. Veamos un ejemplo. CLASSPATH

La CLASSPATH puede establecerse como una variable de entorno del mismo modo que estableces otras variables de entorno, como tu variable de entorno PATH. Sin embargo, normalmente es preferible especificar el CLASSPATH para un comando determinado en la línea de comandos:

C:\> java -classpath c:\ian\classes MyProg

Supón que tu CLASSPATH está configurado como C:\classes;. en Windows o ~/classes:. en Unix o Mac. Supón que acabas de compilar un archivo fuente llamado HelloWorld.java (sin declaración de paquete) en HelloWorld.class en el directorio por defecto (que es tu directorio actual) e intentas ejecutarlo. En Unix, si ejecutas una de las herramientas de rastreo del núcleo (trace, strace, truss, o ktrace), probablemente verías que el programa Java open o stat o access los siguientes archivos:

  • Algunos archivos del directorio JDK

  • Luego ~/classes/HelloWorld.class, que probablemente no encontraría

  • Por último, ./HelloWorld.class, que encontraría, abriría y leería en memoria

La imprecisión "algún(os) archivo(s) en el directorio JDK" depende de la versión. No deberías meterte con los archivos del JDK, pero si tienes curiosidad, puedes encontrarlos en las Propiedades del Sistema (véase la Receta 2.2). Antes había una variable llamada sun.boot.class.path, pero ya no se encuentra. Busquemos cualquier propiedad cuyo nombre sea boot:

jshell> System.getProperties().forEach((k,v) -> {
 ... if (((String)k).contains("boot")) System.out.println(k + "->" +v);})
sun.boot.library.path->/usr/local/jdk-11/lib

La razón por la que yo y otros sugerimos no establecer CLASSPATH como variable de entorno es que no nos gustan las sorpresas. Es fácil añadir un JAR a tu CLASSPATH y luego olvidar que lo has hecho; entonces un programa podría funcionar para ti pero no para tus colegas, debido a que desconocen tu dependencia oculta. Y si añades una nueva versión a CLASSPATH sin eliminar la antigua, puedes encontrarte con conflictos.

Ten en cuenta también que proporcionar el argumento -classpath hace que se ignore la variable de entorno CLASSPATH.

Si aún así quieres establecer CLASSPATH como variable de entorno, puedes hacerlo. Supón que también has instalado el archivo JAR que contiene las clases de soporte para programas de este libro, darwinsys-api.jar (el nombre real del archivo si lo descargas puede tener un número deversión como parte del nombre del archivo). Podrías entonces establecer tu CLASSPATH enC:\classes;C:\classes\darwinsys-api.jar;. en Windows o~/classes:~/classes/darwinsys-api.jar:. en Unix.

Ten en cuenta que tienes que indicar explícitamente el nombre completo del archivo JAR. A diferencia de un archivo de clase individual, colocar un archivo JAR en un directorio listado en tu CLASSPATH no hace que esté disponible.

Algunos programas especializados (como un servidor web que ejecute un contenedor Servlet ) podrían no utilizar ni bootpath ni CLASSPATH exactamente como se muestra; estos servidores de aplicaciones suelen proporcionar su propio ClassLoader (consulta la Receta 17.5 para obtener información sobre los cargadores de clases). Los contenedores Web EE, por ejemplo, configuran tu aplicación web CLASSPATH para que incluya el directorio WEB-INF/classes y todos los archivos JAR que se encuentran en WEB-INF/lib.

¿Cómo puedes generar fácilmente archivos de clase en un directorio de tu CLASSPATH? El comando javac tiene una opción -d dir, que especifica dónde debe ir la salida del compilador. Por ejemplo, si utilizo -d para colocar el archivo de clase HolaMundo en mi directorio $HOME/clases, sólo tengo que escribir lo siguiente (ten en cuenta que a partir de ahora utilizaré el nombre del paquete además del nombre de la clase, como un buen chico):

javac -d $HOME/classes HelloWorld.java
java -cp $HOME/classes starting.HelloWorld
Hello, world!

Mientras este directorio permanezca en mi CLASSPATH, puedo acceder al archivo de clase independientemente de mi directorio actual. Ésa es una de las principales ventajas de utilizar CLASSPATH.

Aunque estos ejemplos muestran el uso explícito de java con -classpath, en general es más cómodo (y reproducible) utilizar una herramienta de compilación como Maven(Receta 1.7) o Gradle, que proporcionan automáticamente el CLASSPATH tanto para la compilación como para la ejecución.

Ten en cuenta que Java 9 y posteriores también tienen una ruta de módulo (variable de entorno MODULEPATH, argumento de línea de comandos --module-path entry[:,…​]) con la misma sintaxis que la ruta de clase. La ruta de módulo contiene código que se ha modularizado; el sistema de módulos de Java se trata en la Receta 2.5 y en la Receta 15.9.

1.6 Descargar y utilizar los ejemplos de código

Problema

Quieres probar mi código de ejemplo y/o utilizar mis clases de utilidad.

Solución

Descarga el último archivo de los ficheros fuente del libro, descomprímelo y ejecuta Maven (ver Receta 1.7) para compilar los ficheros.

Debate

El código fuente utilizado como ejemplo en este libro está incluido en un par de repositorios de código fuente que han estado en continuo desarrollo desde 1995, y que se enumeran en la Tabla 1-2.

Tabla 1-2. Los principales repositorios de fuentes
Nombre del repositorio URL de GitHub Descripción del paquete Tamaño aprox.

javasrc

http://github.com/IanDarwin/javasrc

Ejemplos/demos de código Java

1.400 clases

darwinsys-api

http://github.com/Iandarwin/darwinsys-api

Una API publicada

200 clases

Puedes descargar estos repositorios desde las URL de GitHub que se muestran en la Tabla 1-2. GitHub te permite descargar un archivo ZIP con el estado actual de todo el repositorio, así como ver archivos individuales en la interfaz web. Es preferible descargarlo con git clone en lugar de como archivo comprimido, porque así puedes actualizarlo en cualquier momento con un simple comando git pull. Y con la cantidad de actualizaciones que ha sufrido esta base de código para la versión actual de Java, seguro que encontrarás cambios después de que se publique el libro.

Si no estás familiarizado con Git, consulta "CVS, Subversion, Git, ¡vaya!".

javasrc

Este es el repositorio más grande y consiste principalmente en código escrito para mostrar una función o API concreta. Los archivos están organizados en subdirectorios por temas, muchos de los cuales corresponden más o menos a capítulos del libro; por ejemplo, un directorio para ejemplos de cadenas(Capítulo 3), regex para expresiones regulares(Capítulo 4), números(Capítulo 5), etc. El archivo también contiene el índice por nombre y el índice por capítulo del sitio de descargas, para que puedas encontrar fácilmente los archivos que necesitas.

La biblioteca javasrc se desglosa a su vez en una docena de módulos Maven (que se muestran en la Tabla 1-3) para que no necesites todas las dependencias de todo en tu CLASSPATH todo el tiempo.

Tabla 1-3. Módulos JavaSrc Maven
Nombre del directorio/módulo Descripción

pom.xml

Pom padre de Maven

Rdemo-web

Demostración de R utilizando un framework web

escritorio

Cosas de AWT y Swing (ya no se tratan en el Libro de recetas de Java)

ee

Cosas de empresa (ya no se tratan en el Libro de recetas de Java)

graal

Demostraciones de GraalVM

jlink

Demostraciones JLink

json

Procesamiento JSON

principal

Contiene la mayoría de los archivos, es decir, aquellos que no es necesario que estén en uno de los otros módulos debido a CLASSPATH u otras cuestiones.

restdemo

Demostración del servicio REST

chispa

Demostración de Apache Spark

pruebas

Código para pruebas

inseguro

Demostración de la clase Unsafe

xml

Cosas de XML (ya no se tratan en el Libro de recetas de Java)

darwinsys-api

He creado una colección de cosas útiles en parte trasladando algunas clases reutilizables de javasrc a mi propia API, que utilizo en mis propios proyectos Java. Utilizo código de ejemplo de ella en este libro, e importo clases de ella en muchos de los otros ejemplos. Por tanto, si vas a descargar y compilar los ejemplos individualmente, primero debes descargar el archivo darwinsys-api-1.x.jar (para el último valor de x) e incluirlo en tu CLASSPATH. Ten en cuenta que si vas a compilar el código javasrc con Eclipse o Maven, puedes saltarte esta descarga porque el script de Maven de nivel superior comienza incluyendo el archivo JAR de esta API.

Hay un archivo JAR compilado de darwinsys-api disponible enMaven Central; encuéntralo buscando darwinsys. Éste es el artefacto Maven actual :

<dependency>
   <groupId>com.darwinsys</groupId>
   <artifactId>darwinsys-api</artifactId>
   <version>1.1.3</version>
</dependency>

Esta API consta de unas dos docenas de paquetes com.darwinsys , enumerados en la Tabla 1-4. La estructura es vagamente paralela a la API estándar de Java; esto es intencionado. Estos paquetes incluyen ahora unas 200 clases e interfaces. La mayoría de ellos tienen documentación javadoc que puede consultarse con la descarga del código fuente.

Tabla 1-4. Los paquetes com.darwinsys
Nombre del paquete Descripción del paquete

com.darwinsys.csv

Clases para archivos de valores separados por comas

com.darwinsys.database

Clases para tratar bases de datos de forma general

com.darwinsys.diff

Utilidades de comparación

com.darwinsys.genericui

Cosas genéricas de GUI

com.darwinsys.geo

Clases relativas a códigos de país, provincias/estados, etc.

com.darwinsys.graphics

Gráficos

com.darwinsys.html

Clases (sólo una hasta ahora) para tratar con HTML

com.darwinsys.io

Clases para operaciones de entrada y salida, utilizando las clases de E/S subyacentes de Java

com.darwinsys.jsptags

Etiquetas Java EE JSP

com.darwinsys.lang

Clases para tratar las características estándar de Java

com.darwinsys.locks

API de bloqueo pesimista

com.darwinsys.mail

Clases para tratar el correo electrónico, principalmente una clase de conveniencia para enviar correo

com.darwinsys.model

Modelos de datos de muestra

com.darwinsys.net

Red

com.darwinsys.preso

Presentaciones

com.darwinsys.reflection

Reflexión

com.darwinsys.regex

Cosas de expresiones regulares: un programa REDemo, una variante de Grep

com.darwinsys.security

Seguridad

com.darwinsys.servlet

Ayudantes de la API Servlet

com.darwinsys.sql

Clases para tratar con bases de datos SQL

com.darwinsys.swingui

Clases para ayudar a construir y utilizar GUIs Swing

com.darwinsys.swingui.layout

Algunas implementaciones interesantes de LayoutManager

com.darwinsys.testdata

Generadores de datos de prueba

com.darwinsys.testing

Herramientas de prueba

com.darwinsys.unix

Ayudantes Unix

com.darwinsys.util

Algunas clases de utilidades varias

com.darwinsys.xml

Utilidades XML

Muchas de estas clases se utilizan como ejemplos en este libro; sólo tienes que buscar archivos cuya primera línea empiece por lo siguiente

package com.darwinsys;

También verás que muchos de los otros ejemplos tienen importaciones de los paquetes com.darwinsys.

Notas generales

Tu mejor opción es utilizar git clone para descargar una copia de ambos proyectos Git y luego hacer un git pull cada pocos meses para obtener actualizaciones. Como alternativa, puedes descargar de lapágina de catálogo de este libro un único subconjunto de intersección de ambas bibliotecas que está formado casi exclusivamente por archivos utilizados realmente en el libro. Este archivo está hecho a partir de las fuentes que se incluyen dinámicamente en el libro en el momento de formatearlo, por lo que debería reflejar exactamente los ejemplos que ves en el libro. Pero no incluirá tantos ejemplos como los tres archivos individuales, ni se garantiza que todo vaya a compilar porque falten dependencias, ni se actualizará a menudo. Pero si lo único que quieres es copiar piezas en un proyecto en el que estás trabajando, éste puede ser el que debes conseguir. Puedes encontrar enlaces a todos estos archivos desde mi propio sitio web para este libro; sólo tienes que seguir el enlace Descargas.

Los dos repositorios separados contienen múltiples proyectos autocontenidos con soporte para la construcción tanto con Eclipse(Receta 1.3) como con Maven(Receta 1.7). Ten en cuenta que Maven buscará automáticamente un amplio conjunto de bibliotecas de requisitos previos cuando se invoque por primera vez a un proyecto determinado, así que asegúrate de que estás conectado a una conexión a Internet de alta velocidad. De este modo, Maven se asegurará de que todos los requisitos previos estén instalados antes de la construcción. Si decides construir las piezas individualmente, busca en el archivo pom.xmlla lista de dependencias. Lamentablemente, no podré ayudarte si utilizas herramientas distintas de Eclipse o Maven con los archivos de control incluidos en la descarga.

Si tienes una versión de Java anterior a Java 12, algunos archivos no compilarán. Puedes inventar elementos de exclusión para los archivos que se sabe que no compilan.

Todo mi código en los dos proyectos se libera bajo la licencia menos restrictiva de sólo crédito, la licencia BSD de dos cláusulas . Si te resulta útil, incorpóralo a tu propio software. No hace falta que me escribas para pedirme permiso; simplemente utilízalo, con crédito. Si te haces rico con ello, envíame algo de dinero.

Consejo

La mayoría de los ejemplos de la línea de comandos hacen referencia a archivos fuente, suponiendo que estás en src/main/java, y a clases ejecutables, suponiendo que estás en (o has añadido a tu CLASSPATH) el directorio de compilación (por ejemplo, normalmente target/classes). Esto no se mencionará con cada ejemplo, ya que hacerlo desperdiciaría mucho papel.

Caveat lector

Los repos llevan en desarrollo desde 1995. Esto significa que encontrarás algún código que no esté actualizado o que ya no refleje las buenas prácticas, lo cual no es sorprendente: cualquier cuerpo de código envejecerá si alguna de sus partes no se mantiene activamente. (Por eso, en este punto, invoco la canción de Culture Club "Do You Really Want to Hurt Me": "Dame tiempo para darme cuenta de mi crimen"). Cuando los consejos del libro no coincidan con algún código que hayas encontrado en el repositorio, ten esto en cuenta. Una de las prácticas de la Programación Extrema es la Refactorización Continua, la capacidad de mejorar cualquier parte de la base de código en cualquier momento. No te sorprendas si el código del directorio de fuentes en línea difiere de lo que aparece en el libro; es raro el mes en que no hago alguna mejora en el código, y los resultados se envían y publican con bastante frecuencia. Así que si hay diferencias entre lo que aparece en el libro y lo que obtienes de GitHub, alégrate, no te entristezcas, porque habrás recibido el beneficio de la retrospectiva. Además, la gente puede contribuir fácilmente en GitHub mediante pull requests; eso es lo que lo hace interesante. Si encuentras un error o una mejora, ¡envíame un pull request! El archivo consolidado de la página de este libro no se actualizará con tanta frecuencia.

1.7 Automatización de dependencias, compilación, pruebas e implementación con Apache Maven

Problema

Quieres una herramienta que lo haga todo automáticamente: descarga tus dependencias, compila tu código, compila y ejecuta tus pruebas, empaqueta la aplicación y la instala o despliega.

Solución

Utiliza Apache Maven.

Debate

Maven es una herramienta de creación centrada en Java que incluye un sofisticado sistema distribuido de gestión de dependencias que también le proporciona reglas para crear paquetes de aplicaciones como archivos JAR, WAR y EAR e implementarlos en una serie de objetivos diferentes. Mientras que las herramientas de creación más antiguas se centran en el cómo, los archivos Maven se centran en el qué, especificando lo que quieres que se haga.

Maven se controla mediante un archivo llamado pom. xml (de Modelo de Objetos del Proyecto). Un pom.xml de muestra podría tener este aspecto:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>my-se-project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>my-se-project</name>
  <url>http://com.example/</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Esto especifica un proyecto llamado mi-proyecto-se (mi proyecto de edición estándar) que se empaquetará en un archivo JAR; depende del framework JUnit 4.x para las pruebas unitarias (consulta la Receta 1.10), pero sólo lo necesita para compilar y ejecutar pruebas. Si escribo mvn install en el directorio con este POM, Maven se asegurará de que tiene una copia de la versión dada de JUnit (y de cualquier cosa de la que JUnit dependa). Luego compilará todo (estableciendo CLASSPATH y otras opciones para el compilador), ejecutará todas y cada una de las pruebas unitarias y, si todas pasan, generará un archivo JAR para el programa. A continuación, lo instalará en mi repositorio personal de Maven (en ~/.m2/repository) para que otros proyectos Maven puedan depender de mi nuevo archivo JAR del proyecto. Ten en cuenta que no he tenido que decirle a Maven dónde se encuentran los archivos fuente, ni cómo compilarlos: todo esto se gestiona mediante valores predeterminados sensatos, basados en una estructura de proyecto bien definida. Se espera que el código fuente del programa se encuentre en src/main/java, y las pruebas en src/test/java; si se trata de una aplicación web, se espera que la raíz web esté por defecto en src/main/webapp. Por supuesto, puedes anular esta configuración.

Ten en cuenta que ni siquiera el archivo de configuración anterior tiene que ser, ni fue, escrito a mano; las reglas de generación de arquetipos de Maven le permiten construir la versión inicial de cualquiera de varios cientos de tipos de proyectos. He aquí cómo se creó el archivo:

$ mvn archetype:generate \
    -DarchetypeGroupId=org.apache.maven.archetypes \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DgroupId=com.example -DartifactId=my-se-project

[INFO] Scanning for projects...
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/
    maven-deploy-plugin/2.5/maven-deploy-plugin-2.5.pom
[several dozen or hundred lines of downloading POM files and Jar files...]
[INFO] Generating project in Interactive mode
[INFO] Archetype [org.apache.maven.archetypes:maven-archetype-quickstart:1.1]
    found in catalog remote
[INFO] Using property: groupId = com.example
[INFO] Using property: artifactId = my-se-project
Define value for property 'version':  1.0-SNAPSHOT: :
[INFO] Using property: package = com.example
Confirm properties configuration:
groupId: com.example
artifactId: my-se-project
version: 1.0-SNAPSHOT
package: com.example
 Y: : y
[INFO] ------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype:
    maven-archetype-quickstart:1.1
[INFO] ------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: packageName, Value: com.example
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: artifactId, Value: my-se-project
[INFO] Parameter: basedir, Value: /private/tmp
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /private/tmp/
    my-se-project
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6:38.051s
[INFO] Finished at: Sun Jan 06 19:19:18 EST 2013
[INFO] Final Memory: 7M/81M
[INFO] ------------------------------------------------------------------------

Alternativamente, puedes hacer mvn archetype:generate y seleccionar el predeterminado de una lista bastante larga de opciones. El predeterminado es un arquetipo Java de inicio rápido, que facilita el comienzo.

Los IDE (ver Receta 1.3) tienen soporte para Maven. Por ejemplo, si utilizas Eclipse, M2Eclipse (m2e) es un complemento de Eclipse que creará las dependencias de tu proyecto Eclipse a partir de tu archivo POM; este complemento se incluye por defecto con las versiones actuales de Eclipse para desarrolladores de Java. También está disponible para algunas versiones anteriores; consulta el sitio web de Eclipsepara obtener más información sobre el plug-in.

Un archivo POM puede redefinir cualquiera de los objetivos estándar. Los objetivos comunes de Maven (predefinidos por defecto para hacer algo sensato) incluyen los siguientes:

limpia

Elimina todos los artefactos generados

compila

Compila todos los archivos fuente

prueba

Compila y ejecuta todas las pruebas unitarias

paquete

Construye el paquete

instala

Instala el pom.xml y el paquete en tu repositorio local de Maven para que lo utilicen tus otros proyectos

implementación

Intenta instalar el paquete (por ejemplo, en un servidor de aplicaciones).

La mayoría de los pasos invocan implícitamente a los anteriores. Por ejemplo, packagecompilará los archivos .class que falten y ejecutará las pruebas si no se ha hecho ya en esta ejecución.

Existe un elemento opcional distributionManagement en el archivo POM o un -DaltDeploymentRepositoryen la línea de comandos para especificar una ubicación de implementación alternativa. Hay objetivos específicos de servidores de aplicaciones proporcionados por los proveedores de servidores de aplicaciones; como ejemplo único, con el servidor de aplicaciones WildFly (conocido como JBoss AS hace una década o más), instalarías algún(os) complemento(s) adicional(es) según su documentación y luego realizarías la implementación en el servidor de aplicaciones utilizando

mvn wildfly:deploy

en lugar de la implementación habitual. Como utilizo este encantamiento de Maven con frecuencia, tengo un alias de shell o un archivo por lotes mwd para automatizar incluso eso.

Pros y contras de Maven

Maven puede manejar proyectos complejos y es muy configurable. Construyo los proyectos darwinsys-api y javasrc con Maven y dejo que se encargue de encontrar las dependencias, haciendo que la descarga del código fuente del proyecto sea menor (en realidad, trasladando la sobrecarga de descarga a los servidores de los propios proyectos). Los únicos inconvenientes reales de Maven son que se tarda un tiempo en familiarizarse con él, y que puede ser difícil diagnosticar cuando las cosas van mal. Un buen buscador web es tu amigo cuando las cosas fallan.

Un problema que temo es que un pirata informático pueda acceder al sitio de un proyecto y modificar o instalar una nueva versión de un POM. Maven obtiene automáticamente las versiones actualizadas del POM. Sin embargo, utiliza firmas hash para verificar que los archivos no han sido manipulados durante el proceso de descarga, y todos los archivos que se suban deben estar firmados con PGP/GPG, por lo que un atacante tendría que comprometer tanto la cuenta de subida como las claves de firma. No obstante, no tengo constancia de que esto haya ocurrido nunca.

Ver también

Comienza en http://maven.apache.org.

1.8 Automatización de dependencias, compilación, pruebas e implementación con Gradle

Problema

Quieres una herramienta de compilación que no te obligue a utilizar un montón de XML en tu archivo de configuración.

Solución

Utiliza el sencillo formato de archivo de construcción de Gradle con configuración por convención para obtener archivos de construcción más cortos y construcciones rápidas.

Debate

Gradle es la última de la sucesión de herramientas de construcción (Make, Ant y Maven). Gradle se autodenomina "la herramienta de automatización empresarial" y se integra con las demás herramientas de construcción e IDE.

A diferencia de otras herramientas basadas en Java, Gradle no utiliza XML como lenguaje de scripting, sino un Lenguaje Específico de Dominio (DSL) basado en el lenguaje de scripting Groovy, basado en JVM y en Java.

Puedes instalar Gradle descargándolo del sitio web Gradle, descomprimiendo el ZIP y añadiendo su subdirectorio bin a tu ruta.

Entonces podrás empezar a utilizar Gradle. Suponiendo que utilices el directorio fuente estándar(src/main/java, src/main/test) que comparten Maven y Gradle, entre otras herramientas, el archivo build.gradle de ejemplo del Ejemplo 1-1 construirá tu aplicación y ejecutará tus pruebas unitarias.

Ejemplo 1-1. Ejemplo de archivo build.gradle
# Simple Gradle Build for the Java-based DataVis project
apply plugin: 'java'
# Set up mappings for Eclipse project too
apply plugin: 'eclipse'

# The version of Java to use
sourceCompatibility = 11
# The version of my project
version = '1.0.3'
# Configure JAR file packaging
jar {
    manifest {
        attributes 'Main-class': 'com.somedomainnamehere.data.DataVis',
        'Implementation-Version': version
    }
}

# optional feature: like -Dtesting=true but only when running tests ("test task")
test {
    systemProperties 'testing': 'true'
}

Puedes arrancar la gran inversión de la industria en infraestructura Maven añadiendo líneas como éstas en tu build.gradle:

# Tell Gradle to look in Maven Central
repositories {
    mavenCentral()
}

# We need darwinsys-api for compiling as well as JUnit for testing
dependencies {
    compile group: 'com.darwinsys', name: 'darwinsys-api', version: '1.0.3+'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

Ver también

Hay mucha más funcionalidad en Gradle. Empieza en el sitio web de Gradle, y consulta la documentación.

1.9 Hacer frente a las advertencias de desaprobación

Problema

Tu código solía compilar limpiamente, pero ahora da advertencias de desaprobación.

Solución

Habrás parpadeado. O vives-peligrosamente-con las advertencias o revisas tu código para eliminarlas.

Debate

Cada nueva versión de Java incluye un montón de nuevas y potentes funcionalidades, pero a un precio: durante la evolución de este nuevo material, los mantenedores de Java encuentran algunas cosas antiguas que no se hicieron bien y que ya no deberían utilizarse porque realmente no pueden arreglarlas. En la primera gran revisión, por ejemplo, se dieron cuenta de que la clase java.util.Date tenía serias limitaciones en cuanto a la internacionalización. En consecuencia, muchos de los métodos y constructores de la clase Date están marcados como "obsoletos". Según el American Heritage Dictionary, obviar algo significa "expresar desaprobación hacia; deplorar", por lo que los desarrolladores de Java desaprueban la antigua forma de hacer las cosas. Prueba a compilar este código:

import java.util.Date;

/** Demonstrate deprecation warning */
public class Deprec {

    public static void main(String[] av) {

        // Create a Date object for May 5, 1986
        @SuppressWarnings("deprecation")
        // EXPECT DEPRECATION WARNING without @SuppressWarnings
        Date d = new Date(86, 04, 05);
        System.out.println("Date is " + d);
    }
}

¿Qué ha ocurrido? Cuando lo compilé (antes de añadir la anotación @SuppressWarnings() ), recibí esta advertencia:

C:\javasrc>javac Deprec.java
Note: Deprec.java uses or overrides a deprecated API.  Recompile with
"-deprecation" for details.
1 warning
C:\javasrc>

Por tanto, seguimos órdenes. Para más detalles, recompila con -deprecation para ver los detalles adicionales:

C:\javasrc>javac -deprecation Deprec.java
Deprec.java:10: warning: constructor Date(int,int,int) in class java.util.Date
has been deprecated
                Date d = new Date(86, 04, 05);          // May 5, 1986
                         ^
1 warning

C:\javasrc>

La advertencia es sencilla: el constructor Date que toma tres argumentos enteros ha quedado obsoleto. ¿Cómo solucionarlo? La respuesta es, como en la mayoría de las cuestiones de uso, consultar la documentación javadoc de la clase. La introducción de la página Date dice, en parte:

La clase Date representa un instante concreto en el tiempo, con precisión de milisegundos.

Antes del JDK 1.1, la clase Date tenía dos funciones adicionales. Permitía interpretar las fechas como valores de año, mes, día, hora, minuto y segundo. También permitía formatear y analizar cadenas de fechas. Por desgracia, la API de estas funciones no era apta para la internacionalización. A partir del JDK 1.1, la clase Calendar debe utilizarse para convertir entre fechas y campos de hora y la clase DateFormat debe utilizarse para formatear y analizar cadenas de fecha. Los métodos correspondientes de Date están obsoletos.

Y más concretamente, en la descripción del constructor de tres enteros, el javadoc de Date dice:

Date(int year, int month, int date)

Obsoleto. A partir de la versión 1.1 del JDK, sustituido por Calendar.set(year + 1900, month, date)o GregorianCalendar(year + 1900, month, date).

Por supuesto, la antigua clase Date ha sido sustituida por LocalDate y LocalDateTime (véase el Capítulo 6), por lo que sólo verías ese ejemplo concreto en código heredado, pero los principios para tratar las advertencias de depreciación son importantes, porque muchas nuevas versiones de Java añaden advertencias de depreciación a partes de la API que antes se podían utilizar "sin problemas".

Como norma general, cuando algo ha sido desaprobado, no debes utilizarlo en ningún código nuevo; y, al mantener el código, esfuérzate por eliminar las advertencias de desaprobación.

Además de Date (Java 8 incluye una API de fecha/hora completamente nueva; véase el Capítulo 6), las principales áreas de advertencias de desaprobación en la API estándar son el manejo de eventos realmente antiguo y algunos métodos (algunos de ellos importantes) de la clase Thread.

También puedes desaprobar tu propio código, cuando se te ocurra una forma mejor de hacer las cosas. Coloca una anotación @Deprecated inmediatamente antes de la clase o método que deseas desaprobar y/o utiliza una etiqueta@deprecated en un comentario javadoc (véase la Receta 15.2). El comentario javadoc te permite explicar la desaprobación, mientras que la anotación es más fácil de reconocer para algunas herramientas porque está presente en tiempo de ejecución (por lo que puedes utilizar Reflection; véase el Capítulo 17).

Ver también

Hay muchas otras herramientas que realizan comprobaciones adicionales en tu código Java. Consulta mi sitio web Comprobación de programas Java.

1.10 Mantener la corrección del código con pruebas unitarias: JUnit

Problema

No quieres tener que depurar tu código.

Solución

Utiliza pruebas unitarias para validar cada clase a medida que la desarrollas.

Debate

Detenerse para utilizar un depurador lleva mucho tiempo, ¡y encontrar un error en el código liberado es mucho peor! Es mejor probar de antemano. La metodología de las pruebas unitarias existe desde hace mucho tiempo; es un medio probado para probar tu código en pequeños bloques. Normalmente, en un lenguaje OO como Java, las pruebas unitarias se aplican a clases individuales, en contraste con las pruebas del sistema o de integración, en las que se prueba un trozo completo o incluso toda la aplicación.

Llevo mucho tiempo defendiendo esta metodología de pruebas tan básica. De hecho, los desarrolladores de la metodología de software conocida como Extreme Programming (XP para abreviar) abogan por Test-Driven Development (TDD): escribir las pruebas unitarias antes de escribir el código. También abogan por ejecutar tus pruebas casi cada vez que construyas tu aplicación. Y hacen una buena pregunta Si no tienes pruebas, ¿cómo sabes que tu código (aún) funciona? Este grupo de defensores de las pruebas unitarias cuenta con algunos líderes conocidos, como Erich Gamma, famoso por su libro Design Patterns, y Kent Beck, famoso por su libro eXtreme Programming (ambos de Addison-Wesley). Estoy totalmente de acuerdo con su defensa de las pruebas unitarias.

De hecho, muchas de mis clases solían venir con una prueba unitaria "incorporada". Las clases que no son programas principales por derecho propio solían incluir un método main que simplemente probaba o al menos ejercitaba la funcionalidad de la clase. Lo que me sorprendió es que, antes de conocer XP, solía pensar que hacía esto a menudo, pero una inspección real de dos proyectos indicó que sólo un tercio de mis clases tenían casos de prueba, ya fuera interna o externa. Está claro que lo que se necesita es una metodología uniforme. Eso lo proporciona JUnit.

JUnit es una metodología centrada en Java para proporcionar casos de prueba, y se puede descargar gratuitamente. Es una herramienta de pruebas muy sencilla pero útil. Es fácil de usar: sólo tienes que escribir una clase de prueba que tenga una serie de métodos y anotarlos con @Test (la versión anterior de JUnit 3.8 exigía que los nombres de los métodos de prueba empezaran por test). JUnit utiliza la introspección (ver Capítulo 17) para encontrar todos estos métodos y luego los ejecuta por ti. Las extensiones de JUnit se encargan de tareas tan diversas como las pruebas de carga y las pruebas de componentes empresariales; el sitio web de JUnit proporciona enlaces a estas extensiones. Todos los IDE modernos ofrecen soporte integrado para generar y ejecutar pruebas JUnit.

¿Cómo empezar a utilizar JUnit? Todo lo que necesitas es escribir una prueba. Aquí he escrito una prueba sencilla de mi clase Person y la he colocado en una clase llamada PersonTest (fíjate en el patrón de nombres obvio):

public class PersonTest {

    @Test
    public void testNameConcat() {
        Person p = new Person("Ian", "Darwin");
        String f = p.getFullName();
        assertEquals("Name concatenation", "Ian Darwin", f);
    }
}

JUnit 4 existe desde hace años y funciona bien. JUnit 5 sólo tiene unos pocos años y presenta algunas mejoras. Una prueba sencilla como esta clase PersonTest será la misma en JUnit 4 o 5 (pero con importaciones diferentes). Utilizar funciones adicionales, como métodos de configuración que se ejecuten antes de cada prueba, requiere anotaciones diferentes entre JUnit 4 y 5.

Para mostrarte cómo ejecutar PersonTest manualmente, compilo la prueba e invoco el arnés de pruebas de línea de comandos TestRunner:

$ javac PersonTest.java
$ java -classpath .:junit4.x.x.jar junit.textui.TestRunner testing.PersonTest
.
Time: 0.188

OK (1 tests)

$

En la práctica, ejecutar las pruebas de ese modo es increíblemente tedioso, así que yo simplemente pongo mis pruebas en la estructura de directorios estándar (es decir, src/test/java/) con el mismo paquete que el código que se está probando y ejecuto Maven (véasela Receta 1.7), que compilará y ejecutará automáticamente todas las pruebas unitarias y detendrá la compilación si falla alguna prueba, cada vez que intentes compilar, empaquetar o implementar tu aplicación. Gradle también lo hará.

Todos los IDE modernos ofrecen soporte integrado para ejecutar pruebas JUnit; en Eclipse, puedes hacer clic con el botón derecho en un proyecto en el Explorador de paquetes y seleccionar Ejecutar como→Prueba JUnit para que encuentre y ejecute todas las pruebas JUnit de todo el proyecto. El complemento MoreUnit (gratuito en el Marketplace de Eclipse) pretende simplificar la creación y ejecución de pruebas.

Los emparejadores Hamcrest te permiten escribir pruebas más expresivas a costa de una descarga adicional. La compatibilidad con ellos está integrada en JUnit 4 con el método estático assertThat , pero tienes que descargar los emparejadores de Hamcrest o mediante el artefacto de Maven.

Aquí tienes un ejemplo de utilización de los emparejadores Hamcrest:

public class HamcrestDemo {

    @Test
    public void testNameConcat() {
        Person p = new Person("Ian", "Darwin");
        String f = p.getFullName();
        assertThat(f, containsString("Ian"));
        assertThat(f, equalTo("Ian Darwin"));
        assertThat(f, not(containsString("/"))); // contrived, to show syntax
    }
}

Ver también

JUnit ofrece una documentación propia considerable; descárgala del sitio web indicado anteriormente.

Un marco alternativo de pruebas unitarias para Java es TestNG; consiguió cierta tracción temprana al adoptar características como las anotaciones de Java antes de que lo hiciera JUnit; pero desde que JUnit se puso con el programa de anotaciones, ha seguido siendo el paquete dominante para las pruebas unitarias de Java.

Otro paquete de interés esAssertJ, que parece ofrecer una potencia similar a la combinación de JUnit con Hamcrest.

Por último, a menudo es necesario crear objetos sustitutos para que los utilice la clase que se está probando (las dependencias de la clase que se está probando). Aunque puedes codificarlos a mano, en general animo a que se utilicen paquetes comoMockito, que puede generar objetos mock de forma dinámica, hacer que estos mocks proporcionen valores de retorno fijos, verificar que las dependencias se han llamado correctamente, etc.

Recuerda: ¡prueba pronto y a menudo!

1.11 Mantener tu código con integración continua

Problema

Quieres estar seguro de que toda tu base de código compila y pasa las pruebas periódicamente.

Solución

Utiliza un servidor de Integración Continua como Jenkins/Hudson.

Debate

Si no has utilizado antes la Integración Continua, te preguntarás cómo has podido vivir sin ella. La Integración Continua es simplemente la práctica de hacer que todos los desarrolladores de un proyectointegren periódicamente (por ejemplo, hagan commit) sus cambios en una única copia maestra del código fuente del proyecto y, a continuación, construyan y prueben el proyecto para asegurarse de que sigue funcionando y supera sus pruebas. Esto puede hacerse unas cuantas veces al día, o cada pocos días, pero no debería ser más que eso, o de lo contrario la integración probablemente se encontrará con obstáculos mayores cuando varios desarrolladores hayan modificado el mismo archivo.

Pero no sólo los grandes proyectos se benefician de la IC. Incluso en un proyecto de una sola persona, es estupendo tener un solo botón que puedas pulsar para comprobar la última versión de todo, compilarlo, enlazarlo o empaquetarlo, ejecutar todas las pruebas automatizadas y dar un indicador rojo o verde de pasa/no pasa. Y lo que es mejor, puede hacerlo automáticamente todos los días o incluso en cada confirmación de la rama maestra.

Si tienes varios sitios web pequeños, ponerlos todos bajo control de CI es uno de los pasos importantes para desarrollar una cultura DevOps automatizada en torno a la implementación y gestión de sitios web.

Si eres nuevo en la idea de la IC, no puedo hacer nada mejor que rogarte que leas el perspicaz (como siempre) artículo de de Martin Fowler sobre el tema. Uno de los puntos clave es automatizar tanto la gestión del código y todos los demás artefactos necesarios para construir tu proyecto, como automatizar el proceso real de construirlo, posiblemente utilizando una de las herramientas de construcción comentadas anteriormente en este capítulo.1

Existen muchos servidores CI, tanto gratuitos como comerciales. En el mundo del código abierto,CruiseControl y Jenkins/Hudson2 También existen soluciones alojadas, comoTravis CI,TeamCity oCircleCI. Estas soluciones alojadas eliminan la necesidad de configurar y ejecutar tu propio servidor CI. También suelen tener su configuración directamente en tu repositorio(travis.yml, etc.), por lo que su implementación se simplifica.

Jenkins se ejecuta como una aplicación web, ya sea dentro de un servidor Jakarta EE o en su propio servidor web independiente. Una vez iniciado, puedes utilizar cualquier navegador web estándar como interfaz de usuario. Instalar e iniciar Jenkins puede ser tan sencillo como desempaquetar una distribución e invocarla del siguiente modo:

java -jar jenkins.war

Si lo haces, ¡asegúrate de configurar la seguridad si tu máquina es accesible desde Internet!

A mucha gente le parece más seguro ejecutar Jenkins en un servidor web Java EE o Java con todas las funciones; cualquier cosa, desde Tomcat a JBoss, pasando por WebSphere o Weblogic, hará el trabajo y te permitirá imponer restricciones de seguridad adicionales.

Una vez que Jenkins esté en marcha y hayas activado la seguridad y estés conectado con una cuenta con suficientes privilegios, puedes crear trabajos en. Un trabajo suele corresponder a un proyecto, tanto en términos de origen (una comprobación del código fuente) como de resultados (un archivo .war, un ejecutable, una biblioteca, lo que sea). Configurar un proyecto es tan sencillo como hacer clic en el botón Nuevo trabajo, situado en la parte superior izquierda del panel de control, como se muestra en la Figura 1-6.

Puedes rellenar los primeros datos: el nombre del proyecto y una breve descripción. Ten en cuenta que todos y cada uno de los campos de entrada tienen al lado un icono con un signo de interrogación, que te dará pistas a medida que avances. ¡No tengas miedo de echar un vistazo a estas pistas! La Figura 1-7 muestra los primeros pasos para configurar un nuevo trabajo.

En las siguientes secciones del formulario, Jenkins utiliza HTML dinámico para hacer que aparezcan los campos de entrada en función de lo que hayas marcado. Mi proyecto de demostración "TooSmallToFail" comienza sin un repositorio de gestión del código fuente (SCM) en , pero tu proyecto real probablemente ya esté en Git, Subversion o algún otro SCM. No te preocupes si el tuyo no está en la lista; hay cientos de plug-ins para gestionar casi cualquier SCM. Una vez que hayas elegido tu SCM, introducirás los parámetros para obtener el código fuente del proyecto de ese repositorio SCM, utilizando campos de texto que piden los datos específicos necesarios para ese SCM: una URL para Git, un CVSROOT para CVS, etc.

jcb4 0106
Figura 1-6. El panel de control en Jenkins
jcb4 0107
Figura 1-7. Crear un nuevo trabajo en Jenkins

También tienes que decirle a Jenkins cuándo y cómo construir (y empaquetar, probar, implementar...) tu proyecto. En cuanto al cuándo, tienes varias opciones, como construirlo después de otro proyecto Jenkins, construirlo cada cierto tiempo según una programación tipo cron, o según un sondeo del SCM para ver si ha cambiado algo (utilizando la misma programación tipo cron). Si tu proyecto está en GitHub (no sólo en un servidor Git local), o en algún otro SCM, puedes hacer que el proyecto se construya cada vez que alguien introduzca cambios en el repositorio. Todo es cuestión de encontrar los plug-ins adecuados y seguir su documentación.

Luego tenemos el cómo, o el proceso de construcción. De nuevo, Jenkins incluye algunos tipos de compilación, y hay muchos más disponibles como complementos: He utilizado Apache Maven, Gradle, la herramienta tradicional de Unix make, e incluso líneas de comandos o shell. Como antes, los campos de texto específicos de la herramienta elegida aparecerán una vez que la selecciones. En el ejemplo de juguete, TooSmallToFail, sólo utilizo el comando shell /bin/false(que debería estar presente en cualquier sistema Unix o Linux) para asegurarme de que el proyecto, de hecho, no se construye, sólo para que veas qué aspecto tiene.

Puedes tener cero o más pasos de construcción; sólo tienes que seguir pulsando el botón Añadir y añadir otros, como se muestra en la Figura 1-8.

jcb4 0108
Figura 1-8. Configuración para SCM y adición de pasos de compilación en Jenkins

Cuando creas que has introducido toda la información necesaria, haz clic en el botón Guardar situado en la parte inferior de la página, y volverás a la página principal del proyecto. Aquí puedes hacer clic en el pequeño y gracioso iconoConstruir ahora, situado en el extremo izquierdo, para iniciar la construcción inmediatamente. O, si has configurado activadores de compilación, puedes esperar a que se activen; pero, ¿no preferirías saber de inmediato si lo has hecho bien? La Figura 1-9 muestra el inicio de la construcción.

En realidad, una construcción correcta muestra una bola azul por defecto (la bombilla de los semáforos japoneses, donde vive Kohsuke, es azul en lugar de verde), pero la mayoría de la gente de fuera de Japón prefiere el verde para el éxito, por lo que el complemento opcional Bolas Verdes suele ser uno de los primeros que se añaden a una nueva instalación.

Junto a la bola roja o verde, verás un informe meteorológico que va desde soleado (las últimas construcciones han tenido éxito) a nublado, lluvioso o tormentoso (ninguna construcción reciente ha tenido éxito).

Haz clic en el enlace al proyecto que ha fallado y, a continuación, en el enlace a la salida de la consola, y averigua qué ha fallado. El flujo de trabajo habitual consiste en realizar cambios en el proyecto, enviarlos al repositorio de código fuente y volver a ejecutar la compilación Jenkins.

jcb4 0109
Figura 1-9. Después de añadir un nuevo trabajo en Jenkins

Hay cientos de complementos opcionales para Jenkins. Para facilitarte la vida, casi todos ellos pueden instalarse haciendo clic en el enlace Gestionar Jenkins y luego yendo a Gestionar complementos. La pestaña Disponible enumera todos los que están disponibles en Jenkins.org; sólo tienes que hacer clic en la casilla de verificación junto a los que quieras, y hacer clic en Aplicar. También puedes encontrar actualizaciones allí. Si la adición o actualización de tu plug-in requiere un reinicio, verás una bola amarilla y palabras al respecto; de lo contrario, deberías ver una bola verde (o azul) que indica que el plug-in se ha realizado correctamente. También puedes ver la lista de plug-ins directamente en la web.

He mencionado que Jenkins comenzó su andadura con el nombre de Hudson. El proyecto Hudson sigue existiendo y está alojado en el sitio web de Eclipse. La última vez que lo comprobé, ambos proyectos habían mantenido la compatibilidad de plug-ins, por lo que muchos o la mayoría de los plug-ins de uno pueden utilizarse con el otro. De hecho, los plug-ins más populares aparecen en la pestaña Disponible de ambos, y la mayor parte de lo que se dice en esta receta sobre Jenkins se aplica igualmente a Hudson. Si utilizas un sistema de IC diferente, tendrás que consultar la documentación de ese sistema, pero los conceptos y las ventajas serán similares.

1.12 Obtener trazas de pila legibles

Problema

Obtienes un seguimiento de la pila de excepciones en tiempo de ejecución, pero la mayoría de las partes importantes no tienen números de línea.

Solución

Asegúrate de que has compilado con la depuración activada.

Debate

Cuando un programa Java lanza una excepción, ésta se propaga por la pila de llamadas hasta que haya una cláusula catch que coincida con ella. Si no se encuentra ninguna, el programa intérprete de Java que invocó tu método main() captura la excepción e imprime un seguimiento de la pila mostrando todas las llamadas a métodos que llegaron desde la parte superior del programa hasta el lugar donde se lanzó la excepción. Tú mismo puedes imprimir este rastreo en cualquier cláusula catch: la clase Throwable tiene varias sobrecargas del método llamado printStackTrace() .

El rastreo incluye los números de línea sólo si se han compilado. Cuando se utiliza javac, éste es el valor por defecto. Si añades la opción -g, javac también incluirá los nombres de las variables locales y otra información en el código compilado, lo que mejorará la información de depuración en caso de fallo.

1.13 Encontrar más código fuente Java

Problema

Quieres crear una gran aplicación y necesitas reducir al mínimo la codificación, evitando el síndrome "No inventado aquí".

Solución

Utiliza la fuente, Luke. Hay miles de aplicaciones, marcos y bibliotecas Java disponibles en código abierto.

Debate

El código fuente de Java está en todas partes. Como ya se ha mencionado, todos los ejemplos de código de este libro pueden descargarse: consulta la Receta 1.6.

Otro recurso valioso es el código fuente de la API Java . Puede que no te hayas dado cuenta, pero el código fuente de todas las partes públicas de la API de Java se incluye con cada versión del Kit de Desarrollo de Java. ¿Quieres saber cómo funciona realmente java.util.ArrayList? Tienes el código fuente. ¿Tienes algún problema para hacer que se comporte un JTable? El JDK estándar incluye el código fuente de todas las clases públicas. Busca un archivo llamado src.zip o src.jar; algunas versiones lo descomprimen y otras no.

Por si fuera poco, puedes obtener el código fuente de todo el JDK gratuitamente a través de Internet, ya sea mediante la biblioteca de código fuente Mercurial en openjdk.java.net o desde la réplica Git en AdoptOpenJDK en github.com. Esto incluye el código fuente de las partes públicas y no públicas de la API, así como el compilador (escrito en Java) y una gran cantidad de código escrito en C/C++ (el propio tiempo de ejecución y las interfaces con la biblioteca nativa). Por ejemplo,java.io.Reader tiene un método llamado read() , que lee bytes de datos de un archivo o de una conexión de red. Hay una versión de esto escrita en C para cada sistema operativo, porque llama a la llamada del sistema read() para Unix, Windows, macOS o lo que sea. El kit fuente del JDK incluye el código fuente de todo esto.

1.14 Encontrar bibliotecas Java ejecutables

Problema

Quieres reutilizar una biblioteca publicada en lugar de reinventar una solución conocida para el problema que tienes entre manos.

Solución

Utiliza Internet para encontrar software reutilizable.

Debate

Aunque la mayor parte de este libro trata de escribir código Java, esta receta no trata de escribir código, sino de utilizar código escrito por otros. Hay cientos de buenos marcos para añadir a tu aplicación Java: ¿por qué reinventar la rueda pinchada cuando puedes comprar una perfectamente redonda? Muchos de estos marcos de trabajo existen desde hace años y se han perfeccionado gracias a los comentarios de los usuarios.

Pero, ¿cuál es la diferencia entre una biblioteca y un framework? A veces es un poco vago, pero en general, un framework es un programa con agujeros que tú rellenas, mientras que una biblioteca es código que tú llamas. Es más o menos la diferencia entre construir un coche comprando un coche casi completo pero sin motor y construir un coche comprando todas las piezas y atornillándolas tú mismo.

Cuando te planteas utilizar un marco de terceros , hay muchas opciones y cuestiones a tener en cuenta. Una es el coste, que entra en la cuestión del código abierto frente al código cerrado. La mayoría de las herramientas de código abierto pueden descargarse gratuitamente y utilizarse, ya sea sin condiciones o con condiciones que debes cumplir. No hay espacio aquí para tratar estas cuestiones de licencias, así que te remitiré a Understanding Open Source and Free Software Licensing (O'Reilly).

Gran parte del software de código abierto está disponible en forma de biblioteca compilada en Maven Central, como se explica en "Maven Central: Mapeando el mundo del software Java".

En la Tabla 1-5 se enumeran algunas colecciones conocidas de marcos y bibliotecas de código abierto para Java. La mayoría de los proyectos de estos sitios están comisariados -es decir, juzgados y considerados dignos- por algún tipo de proceso comunitario.

Tabla 1-5. Colecciones Java de código abierto de buena reputación
Organización URL Notas

Fundación para el Software Apache

http://projects.apache.org

¡No sólo un servidor web!

Fundación de Software Eclipse

https://eclipse.org/projects

Sede del IDE y de Yakarta EE

Marco de trabajo Spring

http://spring.io/projects

Hogar de una docena de frameworks: Spring IOC (fábrica DI), Spring MVC (web), más

Comunidad JBoss

https://redhatofficial.github.io/

Enumera media docena de sus proyectos, además de una larga lista de proyectos actuales de código abierto que utilizan y/o apoyan.

Codehaus

-

Ver notaa

a propia Codehaus dejó de funcionar hace unos años. A partir de 2019, el dominio es propiedad de la Apache Software Foundation, pero no responde a las peticiones del navegador. También hay una cuenta de Codehaus en github que contiene algunos de los proyectos que antes estaban en Codehaus, algunos activos y otros no. Consulta este artículo para saber más sobre la historia de Codehaus.

También hay una gran variedad de repositorios de código fuente abierto, que no están comisariados: cualquiera que se registre puede crear un proyecto allí, independientemente del tamaño de la comunidad existente (si la hay). Los sitios de este tipo que tienen éxito acumulan demasiados proyectos como para tener una sola página que los enumere: tienes que buscar. La mayoría no son específicos de Java. La Tabla 1-6 muestra algunos de los repos de código fuente abierto.

Tabla 1-6. Repositorios de código fuente abierto
Nombre URL Notas

Sourceforge.net

https://sourceforge.net/

Una de las más antiguas

GitHub

http://github.com/

"Codificación Social"; probablemente el más utilizado, ahora propiedad de Microsoft

Bitbucket

https://bitbucket.org/

Repos públicos y privados; planes gratuitos y de pago

GitLab

https://gitlab.org/

Repos públicos y privados; planes gratuitos y de pago

Central Maven

https://search.maven.org/

Tiene jar compilado, jar fuente y jar javadoc para cada proyecto

No pretendo menospreciar estos repositorios; de hecho, la colección de programas de demostración de este libro está alojada en GitHub. Sólo digo que tienes que saber lo que buscas y tener un poco de cuidado antes de decidirte por un framework. ¿Existe una comunidad en torno a él, o es un callejón sin salida?

Mantengo un pequeño sitio Java que puede ser de utilidad. Incluye una lista de recursos Java y material relacionado con este libro.

Para el nivel empresarial o web de Java, hay dos marcos principales que también proporcionan inyección de dependencias: el primero es JavaServer Faces (JSF) y CDI, y el segundo es el paquete Spring Framework SpringMVC. JSF y el CDI (Contextos e Inyección de Dependencias) incorporado proporcionan DI, así como algunos contextos adicionales, como un contexto de Conversación Web muy útil que mantiene objetos a través de múltiples interacciones de páginas web. Spring Framework proporciona inyección de dependencias y las clases de ayuda de la capa web SpringMVC. La Tabla 1-7 muestra algunos recursos del nivel web. Spring MVC y JSF no son ni mucho menos los únicos marcos web; la lista de la Tabla 1-7incluye muchos otros, que pueden ser más adecuados para tu aplicación ¡Tienes que decidir!

Tabla 1-7. Recursos del nivel web
Nombre URL Notas

Lista de Ian de 100 Frameworks Web Java

http://darwinsys.com/jwf/

JSF

http://www.oracle.com/technetwork/java/javaee/overview/

Tecnología estándar Java EE para páginas web

Dado que JSF es un framework basado en componentes, existen muchos componentes adicionales que harán que tu sitio web basado en JSF sea mucho más capaz (y tenga mejor aspecto) que los componentes JSF predeterminados. La Tabla 1-8 muestra algunas de las bibliotecas de complementos de JSF.

Tabla 1-8. Bibliotecas complementarias JSF
Nombre URL Notas

BotasCaras

https://bootsfaces.net/

Combina BootStrap con JSF

Caras de mantequilla

http://butterfaces.org/

Biblioteca de componentes enriquecida

ICEfaces

http://icefaces.org/

Biblioteca de componentes enriquecida

OpenFaces

http://openfaces.org/

Biblioteca de componentes enriquecida

PrimeFaces

http://primefaces.org/

Biblioteca de componentes enriquecida

RichFaces

http://richfaces.org/

Componentes ricos; ya no se mantiene

Apache DeltaSpike

http://deltaspike.apache.org/

Numerosos complementos de código para JSF

JSFUnit

http://www.jboss.org/jsfunit/

Pruebas JUnit para JSF

OmniFaces

http://omnifaces.org/

Complemento JSF Utilities

Hoy en día existen frameworks y bibliotecas para casi todo. Si mis listas no te conducen a lo que necesitas, probablemente lo hará una búsqueda en la red. ¡Intenta no reinventar el pinchazo!

Como con todo el software libre, asegúrate de que comprendes las ramificaciones de los distintos esquemas de licencia. El código cubierto por la GPL, por ejemplo, transfiere automáticamente la GPL a cualquier código que utilice incluso una pequeña parte de él. Consulta a un abogado. Tu kilometraje puede variar. A pesar de estas advertencias, el código fuente es un recurso inestimable para quien quiera aprender más Java.

1 Si la implementación o compilación incluye un paso como "Haz que Smith procese el archivo X en su escritorio y lo copie en el servidor", probablemente no entiendas del todo la noción de prueba automatizada.

2 Jenkins y Hudson comenzaron como Hudson, escrito en gran parte por Kohsuke Kawaguchi mientras trabajaba para Sun Microsystems. Más tarde hubo una disputa cultural que hizo que Jenkins se separara de Hudson, creando una nueva bifurcación del proyecto. Kohsuke trabaja en la mitad que ahora se conoce como Jenkins. Me limitaré a utilizar el nombre Jenkins, porque es el que yo utilizo, y porque lleva demasiado tiempo decir "Jenkins/Hudson" todo el tiempo. Pero casi todo lo que hay aquí se aplica también a Hudson.

Get Libro de cocina de Java, 4ª edición now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.