Panorama del mundo Java

Introducción

No sólo somos lo que somos, somos lo que hemos sido. Y esto se aplica también a Java. Para entender un poco de qué se habla, qué palabras se usan y qué se está comparando hace falta un poco de enumeración, pero también un poco de historia. La situación de Java actual es un palimpsesto, una acumulación de capas geológicas. Tecnologías, denominaciones y estilos que se fueron sucediendo unos a otros. Vamos a hacer un recorrido de un poco de eso para poner al día al que se inicie hoy en esto de Java y no tenga que andar poniendo falsa cara de conocedor en las charlas de la oficina.

Versiones de Java

Después de muchas betas, que fueron públicas, Java apareció con su flamante versión 1.0. En ese momento la idea fue usar el primer número como un indicador de compatibilidad y sólo cambiarlo en una versión de Java que sea incompatible con la anterior. El enorme éxito alcanzado por Java haría que a Sun ni se le pase por la cabeza romper compatibilidad con la enorme cantidad de software que se iba generando, por lo que Java quedó atado al "1.x". El software que los programadores podían bajarse para trabajar con este lenguaje se llamó "JDK", por "Java Development Kit". Este nombre prendió y fue utilizado aun más tarde, cuando Sun pedía a gritos que se le llame de otras extrañas maneras.

La versión 1.1 de Java fue muy importante, agregó la serialización de objetos, RMI y facilidades para implementar interfaces gráficas enteramente en Java en lugar de utilizar "AWT".

La versión 1.2 fue una de las que más radicalmente cambió la plataforma. Se introdujo Swing, la api de collections. Se marcaron como obsoletas clases que eran muy usadas, como Hashtable y Vector. Sun consideró al cambio importante que quizo dejarlo bien en claro e inventó la idea de que Java 1.2 ya no era "Java", sino que era "Java 2". Entonces teníamos una plataforma "Java 2" versión 1.2. "Java 2" entonces no es otra cosa que cualquier Java posterior a esta versión. El nombre "Java 2" fue dejado de utilizar recientemente, pero se usó tantos años que es probable que lo sigamos viendo algún tiempo más, de pura inercia.

Las liberaciones subsiguientes de Java 1.3 y 1.4 fueron añadiendo muchísimas APIs y mejoras. Cuando fue la hora de llegar a la próxima versión, Sun decidió que se cansó de poner "1." delante de todas estas versiones. La nueva versión sería "Java 5". La decisión, de todos modos, fue bastante tímida. Fuera de los manuales y de las páginas web, la versión que aparecía en el software fue 1.5. Por eso no es claro si esta versión se debe llamar 5 o 1.5 y estos nombres deben tratarse como sinónimos. Cuando salió la siguiente versión Sun la llamó Java 6, y avanzó un poco en reemplazar el "1.", pero aún se puede encontrar menciones a Java 1.6 por todos lados.

Hay que aclarar que las denominaciones "Java 5" y "Java 6" siguen otra lógica que la que dio lugar a la denominación "Java 2". Podríamos decir que ambos, "Java 5" y "Java 6" son "Java 2", ya que son posteriores a Java 1.2. ¿Ya los confundí?

Para terminar con este tema de las versiones, a las revisiones menores de Java 6 Sun las denomina "updates" y, en vez de cambiar el número de versión menor (tipo 6.1), lo que hace es llamar a estas versiones 6uX (6u6, 6u7, 6u10...).

Las "editions"

En medio de toda la ensalada que conté, como parte de una estrategia comercial a Sun se le ocurrió hablar de diferentes ediciones de Java. Basicamente dividió la tecnología en tres ediciones:

Java Standard Edition o Java SE
Esto da el nombre a la distribución normal de Java, que existía antes de estos nuevos cartelitos. Es lo que todos conocemos por Java, es lo que uno se tiene que bajar si le dicen "bajate Java".
Java Enterprise Edition o Java EE
Es la edición estándar anterior, pero con el agregado de distintas tecnologías asociadas a la creación de aplicaciones consideradas "empresariales" (como si los únicos que necesitan de la computación fueran empresas). Todas estas tecnologías están disponibles por separado, así que da lo mismo usar esto o bajar el Java normal y simplemente bajar las APIs extra que uno necesite. Un uso interesante, sin embargo, de esta denominación es poder hacer referencia a una colección de números de versión, ya que estos números son disintos para cada API. Es decir que hablando de una versión en particular de la plataforma "Java EE" uno está siendo claro acerca de qué versiones de JavaMail, servlets y EJB habla.

La saga de las bibliotecas para interfaces gráficas

AWT

Las bibliotecas para crear interfaces gráficas son las que se encargan de proveer botones, menúes, controles, etc. Son también conocidas como toolkits, y a los componentes se los suele llamar widgets (palabras tomadas del mundo UNIX). AWT, por "Abstract Windowing Toolkit", fue la primera de estas bibliotecas y viene incluída desde Java 1.0. AWT es sólo una API, no una implementación. No hay en AWT nada que dibuje un botón. De ahí viene el adjetivo "abstract" de su sigla.

El problema fue que al no proveer una implementación de nada, AWT estuvo atado a proveer el mínimo denominador común provisto por todas las plataformas. Es decir que solamente podía tener algo si ese algo estaba disponible en UNIX, Windows, Mac, etc. Además las enormes diferencias en la funcionalidad de estos compoenentes no fue bien manejada y las aplicaciones debían ser probadas en todas las plataformas porque a veces los tamaños, comportamientos del teclado, etc. de una plataforma rompían una aplicación que en otra plataforma andaba bien.

Swing

Para solucionar eso Netscape desarrolló una biblioteca gráfica enteramente codificada en Java. Es decir que si uno se metía en el código Java podía llegar hasta la llamada que pintaba un botón. Todo era Java. Esa blbioteca fue parte de lo que se llamó "Java Foundation Classes" (en esa época era la moda hablar de "foundation classes", es la época de la MFC de Microsoft). Una versión mejorada de esa biblioteca fue incluída en Java 1.2 y fue llamada Swing.

Sin embargo, a pesar del que el diseño de Swing era moderno y la biblioteca era sumamente capaz, Sun se durmió en los laureles. A Sun no le interesaba demasiado emprender la tarea de pulir por completo los detalles y las aplicaciones Swing no fueron ni muy veloces, ni muy lindas. En especial en comparación con las nativas de los sistemas operativos.

SWT

Las deficiencias que en ese momento se percibía que existían en Swing llevaron a IBM a crear SWT (Standard Widget Toolkit). Este toolkit era un regreso a la obsoleta estrategia de AWT: usar botones de Windows en Windows y de Mac en Mac. Pero esta vez quisieron hacerlo bien y, por ejemplo, proveer implementaciones "puro Java" para las características que una plataforma no provee.

JavaFX

JavaFX es una nueva biblioteca gráfica, pero no sólo eso. Es también un nuevo lenguaje que compila a bytecode. Este lenguaje es más adecuado para hacer aplicaciones y applets mucho más fácilmente y con animaciones y es el arma que Sun espera utilizar para competir con Flash. Hay que aclarar que no es realmente parte oficial de la plataforma Java y, por ejemplo, no es software libre como el resto de Java lo es. Acaba de ser liberado en diciembre del 2008, y todavía es una incógnita el grado de éxito que tendrá. Además el lenguaje JavaFX es muy diferente a Java, si bien comparte las nociones de clase y objeto agrega otros elementos nuevos muy interesantes.

Bibliotecas gráficas ahora

La situación actual entonces es que tenemos estas dos bibliotecas en competencia. Sin embargo la mayoría adopta Swing, que tiene un diseño y una API mucho más elegantes y que recibió muchas mejoras que lo pusieron al día, ahora que tiene competencia. Sun se despertó y las aplicaciones Swing ahora se parecen mucho más a las aplicaciones nativas, en Windows y en Linux. Estos cambios podrían indicar que SWT está progresivamente perdiendo las razones que motivaron su existencia.

Sin embargo Sun parece haber suspendido el flujo de mejoras a Swing, y el futuro de Java del lado cliente parece venir más del lado de la nueva tecnología JavaFX.

Tecnologías Java varias

Bases de datos y persistencia

JDBC es la API que tiene Java para hacer queries SQL a una base de datos. Tiene de simpático el hecho de que casi todo lo que define son sólo interfaces, y los drivers de cada base son simplemente implementaciones de esas interfaces.

El modelo relacional, utilizado en las bases de datos, y la orientación a objetos son dos maneras diferentes de organizar información. Los objetos son una manera más moderna, más conceptual, y nos gustaría poder pensar que todos son objetos y olvidarnos de las tablas. Para eso fueron apareciendo "ORMs", es decir "Object-Relational" mappers. Estos frameworks nos permiten ver a los datos como si fueran objetos.

Entre las cosas que estas bibliotecas saben hacer podemos citar que permiten hacer corresponder una jerarquía de clases a un join de tablas, que incluyen un lenguaje de queries más sencillo y potente (porque ya conoce cómo se relacionan las clases) y que proveen una forma sencilla de utilizar cachés para el acceso a los datos.

Uno de los más populares ORMs es Hibernate. Tanto que fue la base de una nueva API de Java llamada JPA, que estandariza el uso de estas bibliotecas, de modo tal que una aplicación puede hacerse contra esta API y después funcionar contra cualquiera de estos "proveedores de persistencia" (entre los que está Hibernate).

JavaBeans

El caso de JavaBeans es muy singular. Es al mismo tiempo una de las especificaciones menos usadas y una de las más usadas. JavaBeans nace como una arquitectura para emular el modelo de componentes de las aplicaciones de escritorio. Como OLE (ahora ActiveX) en Windows. Pertenece al momento anterior a que Sun deje de enfocarse en tecnologías de escritorio y se concentre en el más exitoso mercado de software para servidores.

Esta API definió un mecanismo que permitía el desarrollo de componentes visuales (o "controles"), y que esos componentes puedan ponerse en una paleta del tipo de las popularizadas por Visual Basic. Definía una manera para que esos componentes guarden su estado, definía la noción de un "tiempo de edición" y un "tiempo de runtime", y la forma en la que ese componente debe proveer un iconito.

Al mismo tiempo definió la manera en la que un componente debía presentar propiedades, al estilo de las que aparecen en un componente VisualBasic. En vez de crear algo nuevo, la idea fue reutilizar la noción de "getters" y "setters" y se definió que si una clase tenía un "getColor()" y un "setColor()", entonces se daba por existente una propiedad "color". También definió una manera en la que otras partes de una aplicación podían suscribirse para recibir una notificación cuando los valores de las propiedades de un "bean" cambien o, más generalmente, cuando cualquier suceso relevante ocurriera.

Solamente las dos características que conté en el último párrafo sobrevivieron. Pero fueron tan pero tan exitosas que la palabra "bean" se popularizó, y la idea de bean (más que nada la palabra suelta: bean) fue llevada al mundo de código de servidores, cuando Sun creó los "Enterprise Java Beans". Éstos no tienen casi nada que ver con sus tocayos. Un EJB es un componente de servidor que puede correr dentro de un "contenedor" que le brinda servicios tales como "persistencia", "balance de carga", etc.

En general, la palabra "bean" quedó flotando en Java para hacer referencia a clases que hacen uso de "getters"/"setters" y al uso de "event listeners".

Aplicaciones web

Para permitir el uso de Java en la generación de páginas web, sun definió qué forma tiene que tener un objeto que recibe un request web y produce una respuesta. Haciendo un paralelo con el primer éxito de Java que fueron los applets, a esos objetos se los llamó "servlets". Un servlet es entonces una clase java que cumple con cierta interfaz mediante la cual un "contenedor de servlets" le delega la generación de contenido web.

Programar un servlet es fácil, pero puede ser molesto si se quiere generar HTML. Hay que poner todo el contenido generado en líneas del tipo "out.println();". Para facilitar esto Sun creó una tecnología llamada JSP (análogo al ASP ya existente en el mundo Microsoft), las "Java Server Pages". Esta funcionalidad no hace otra cosa que generar un servlet, compilarlo y ejecutarlo, dada una página JSP. Esta tecnología compite directamente con PHP, ofreciendo mayor rendimiento y un lenguaje más pensado (PHP fue creado a los golpes, escribí una comparación en inglés).

JSP se convirtió en una tecnología básica, central, en el mundo Java. Ya desde el inicio se vislumbraban sus límites, ya que en la especificación se recomendaba no poner el código en la página, y se hablaba de un "modelo 2" en el que se separa el procesamiento de la presentación. En la página web se debería solamente acceder a un objeto (un bean) que ya tenga cargado todo el resultado del procesamiento.

Este modelo de uso no tuvo demasiada visibilidad hasta que apareció el framework "Struts", que sobre esta idea construyó toda una infraestructura para la creación de sitios.

Pero no fue Struts la única tecnología que apareció. También estuvo el engine de templates Velocity, que permite crear la página en un lenguaje simple de templates que puede fácilemente acceder a beans, pero en el que no se puede crear programas. Otro framework web fue Cocoon, basado en la idea de construir pipelines en los que documentos XML van pasando por "transformadores" que los van procesando (mayormente usando XSLT).

El mundo de Java en la web floreció de frameworks. Los programadores nunca llegaron a ponerse de acuerdo en qué es más importante en un framework: si la simplicidad o la elegancia, si la capacidad de hacer mucho con poco o el permitir que un idiota haga páginas web. Y cada uno de los muchos framework que fue surgiendo ocupó un punto en el espacio dado por esos ejes.

Una nueva tendencia ahora son los frameworks que buscan esconder el estilo "conversacional" de la web. Hasta ahora, un componente reusable web no se puede aislar del hecho de que se lo va a mostrar en una página, y que debe comunicarse con otras apariciones de sí mismo via controles de formulario. El más importante y central de estos esquemas es JSF (Java Server Faces), caracterizado por la idea de que los componentes web (formularios, controles, etc.) se instancien en el servidor y permanezcan vivos durante las idas y vueltas de la "conversación" web. De esta manera el creador de componentes se aisla un poco de la web y puede programar en un estilo más parecido al usado en aplicaciones puramente locales (por ejemplo usando "listeners"). Otro framework alternativo que sigue un diseño similar, pero con una implementación más sencilla es Wicket.

Una nota extra sobre los frameworks: No son necesarios. Muchas personas, al comparar la conveniencia de utilizar Java o PHP han cometido el error de comparar peras con manzanas. PHP debe compararse con el uso de JSP pelado, sin nada, no con Struts. Y es muy difícil encontrar un caso en el que sea más conveniente el uso de PHP frente a JSP (con una gran excepción: hosting barato hay sólo para PHP).

Patrones de diseño populares

En el mundo Java se fueron poniendo de moda distintas maneras de organizar las aplicaciones. La API misma de Java emplea varios patrones, como por ejemplo el patrón "decorator", que es utilizado por InputStream, Reader, Writer, etc.

En su momento hicieron furor las estructuras de tres capas. No es que ahora ese sea un concepto en desuso, pero en una época se hablaba mucho más de eso, y asociado a las palabras "application server", que aparecían siempre. Y en la capa de "acceso a datos" siempre hizo furor el tener "Data Access Objects" (DAOs), es decir, objetos que sólo se dedican al acceso a datos.

Una idea que se usó mucho fue la de separar la configuración del código, y los frameworks se llenaron de complejos archivos XML, que había que entender y editar. Se crearon herramientas para generarlos, como XDoclet. Finalmente, todos nos dimos cuenta de lo feos que eran y, ayudados por las "annotations" empezamos a odiarlos. Ahora, mayormente, odiamos al XML para ese uso.

Una moda más o menos reciente es la del patrón "Inversion of Control" (o IoC). La idea está bien expresada por la frase "no me llames, yo te llamo" y consiste en que no sean los objetos los que extiendan sus tentáculos por toda la aplicación para buscar lo que necesitan. Es más elegante ahora que de alguna manera se le "inyecte" a un objeto lo que necesita. Esa inyección puede ser llamando a "setters" o a constructores, y se puede realizar manualmente o mediante un container especializado en eso. Lo lindo de usar uno de esos containers es que pueden automáticamente proveer a las clases de los componentes globales que necesitan. Este pattern es bueno para hacer test de los componentes aislados y reemplaza al viejo pattern singleton. El framework más conocido basado alrededor de esta idea es Spring.

Otra idea importante actual es la de volver a objetos simples y al buen uso de la herencia. Los estándares EJB 1 y 2 proponían una arquitectura compleja en la que los componentes debían heredar de clases especiales. Esto hacía que no se pueda utilizarlos fuera de ese framework y complicaba y afeaba todo. Entonces, como una reacción a eso, surgió la denominación POJO, que quiere decir "Plain Old Java Object". Posible traducción: "viejo y querido objeto Java". Ahora más elegantes y novedosos frameworks se jactan de funcionar con POJOs, o sea con simples objetos que no tienen que heredar nada.

¡Continuará!

Vea mis otros artículos sobre programación en Java.


Me encantaría recibir cualquier tipo de comentarios sobre esta página. ¿Qué pongo? ¿Qué saco? Hecho por Nicolás Lichtmaier.

HTML 4.01 estricto válido

Creative Commons License
Licenciado bajo la licencia Creative Commons Attribution 3.0.