Llegamos a ustedes gracias a:



Reportajes y análisis

¿Qué podemos esperar de Java SE 7?

Balance del año

[19/12/2008] Desde inicios del 2007, Alex Miller recopila y comparte información sobre los JSR propuestos para ser incluidos en Java SE 7. En esta entrega de Balance del año, resume los frutos de su labor: un logrado retrato de la próxima especificación de dicha plataforma, incluyendo algunos de los más recientes anuncios de Sun Microsystems. Los invitamos a dar un vistazo a los aportes claves que podría ofrecer Java SE 7, y a descubrir cuáles de los más prometedores JSR corren el riesgo de quedar relegados.

Casi inmediatamente después del lanzamiento de Java SE 6, en diciembre del 2006, los desarrolladores comenzaron a pronosticar qué JSR serían incluidos en Java SE 7. En enero del 2007, comencé a rastrear estas proyecciones y a catalogar las discusiones en torno a ellas, muchas de las cuales tuvieron por escenario la blogósfera. Conforme pasó el tiempo, algunas ideas habían engendrado JSR, especificaciones y prototipos; mientras que otras se habían marchitado y perdido fuerza hasta quedar fuera de carrera.
Para entonces, ya tenía un panorama bastante claro de los cambios de lenguaje y JSR con mayores chances de ser incluidos debido a su madurez, importancia y aceptación en la comunidad. Sin embargo, la decisión final no se tomará hasta que Danny Coward, arquitecto en jefe de SUN para Java SE, apruebe la plataforma de JSR y se forme un grupo de expertos. Como parte de esta plataforma de JSR serán aprobados todos los cambios de bibliotecas Java y de lenguaje que, en su conjunto, le darán unidad a los JSR para formar el paquete completo de atributos. Por ahora, la fecha prevista para Java SE 7 es inicios del 2010, y es posible que una plataforma JSR llegue en el primer trimestre de este año. 
En adelante, este artículo abordará los atributos que, en mi opinión, tienen mayores posibilidades de ser incluidos en Java SE 7, con muestras de código para demostrar los cambios en relación a la codificación actual. Todos los JSR que mencionaré tienen especificaciones y prototipos de trabajo, es decir que ya han alcanzado una madurez razonable. 
Mejor administración de dependencias
Por mucho tiempo, los desarrolladores de Java (todos los desarrolladores, en realidad) han padecido administrando las dependencias de los -cada vez más grandes- conjuntos de bibliotecas comerciales y de fuente abierta. Actualmente, una aplicación corporativa típica se basa en docenas de archivos JAR externos y, a su vez, puede comprender docenas de proyectos internos más pequeños a cargo de diferentes equipos de trabajo. Por ahora, seguimos buscando mejores maneras de administrar este expansiva madeja de dependencias con el fin de que nuestras estructuras sean repetibles y nuestros despliegues tengan sentido. Esta tendencia se refleja en la irrupción de sistemas para manejar dependencias, como Maven, y sistemas de despliegue de runtime, como OSGi. 
A comienzos del ciclo Java SE 7, dos importantes JSR trataron de impulsar el progreso de la administración de dependencias:  JSR 294: Improved Modularity Support in the Java Programming Language. Ambos se concentraban en los aspectos de desarrollo y despliegue, respectivamente, de la noción de módulos de Java.
Un módulo es un conjunto de clases interrelacionadas que generalmente sirven para un propósito común, similar a un JAR que, por lo general, sería producido por un proyecto Open Source interno administrado en un IDE. Como sea, una proyección de módulos podría ser parte de un JAR o un grupo de varios JAR, dependiendo de las necesidades de desarrollo y despliegue. A mediados de 2008, el JSR 294 fue simplificado y fusionado con el JSR 277 de manera que el mismo grupo de expertos pudiera trabajar en ambos aspectos al mismo tiempo. 
En diciembre del 2008, Sun replanteó una vez más este plan, anunciando que Java SE 7 se concentraría únicamente en la modularización del JDK como Project Jigsaw en el OpenJDK. Tanto el JSR 277 como el Java Module System quedarán en suspenso hasta después del Java SE 7. En cambio, el JSR 294 será resucitado para modularizar el JDK. Sun ha dado a conocer su intención de trabajar estrechamente con la OSGi Alliance de manera que los módulos JSR 294 puedan ser usados por OSGi.  
Aunque circula diversa información sobre esta novedad para la modularidad de Java, aún es un muy pronto para analizar la ola de anuncios en términos de lo que realmente significaran para Java SE 7. En todo caso, queda la impresión de que Sun está colocando la barra un poco abajo al descomponer el mismo JDK en módulos, Sun y brindar soporte a estos módulos directamente en la máquina virtual de Sun (pero no como parte de un nuevo estándar de plataforma). 
Project Jigsaw y la clave del módulo
Una pregunta que pide respuesta a gritos en Java SE 7 es cómo se las arreglará Sun con la clave del módulo, piedra angular del JSR 294 original que, según todas las expectativas, debería estar incluido en la próxima plataforma.
Imagínese un proyecto ficticio hecho de varios paquetes, al que llamaremos Flapjack. El proyecto abarca un API público en el paquete de base y varios, paquetes internos que implementan el API:  
org.flapjack - public API classes
org.flapjack.impl - implementation classes
org.flapjack.util - utility classes
En Java SE 6, si uno necesita colocar una factory class en la base del paquete para crear instancias del API en los paquetes internos de implementación, tiene que hacer públicas las clases de implementación para que puedan ser vistas desde el paquete API. No hay un nivel de visibilidad que permita que la fábrica de API cree instancias de clase sin permitir, a la vez, que las clases externas lo implementen directamente, porque rebasan los límites del paquete.
Los módulos JSR 294 permitirían que el usuario declare el conjunto completo de paquetes como un módulo. Para ello se necesitaría una nueva declaración en el código fuente:
module org.flapjack;
Es posible agregar esta nueva declaración en cada archivo fuente del proyecto o en el paquete de información del archivo java. Aunque módulo es una nueva clave, se trata de una clave restringida que es tratada como clave solo donde corresponde, de manera que puede ser usada como un identificador Java normal en otras aplicaciones. Esta capacidad extiende el lenguaje y, al mismo tiempo, limita la compatibilidad.  
Además de la nueva declaración, también puede usar la clave de módulo con un nuevo modificador de visibilidad que puede ser colocado en una clase para declarar que la clase es visible solo por otras clases dentro del mismo módulo. El listado 1 demuestra este uso de la clave de módulo:
Listado 1. Usar el módulo como modificador de visibilidad
module org.flapjack;
package org.flapjack.impl;
import org.flapjack.Flapjack; 
module class FlapjackImpl implements Flapjack {
}
Finalmente, es posible definir un nuevo module-info.java pseudo-class para anotar el módulo con metadata como clase principal (para ejecución), módulos importados por dependencias, recursos exportados, y otras anotaciones de módulo predefinidas o personalizadas. Cabe destacar que al igual que el existente package-info.java file, el nuevo archivo module-info.java usa un nombre de archivo fuente de Java inválido para evitar posibles cruces con archivos preexistentes.
En cuanto al tiempo de compilación, el JSR 294 requiere compilar las clases con javac (que ahora sabe de módulos y archivos module-info.java). Queda por ver la manera en que Project Jigsaw especificará la composición, el proceso de carga y la verificación de módulos en el JVM. 
(Más) NIO API
El JSR 203: NIO 2 extiende y complementa el trabajo iniciado en JDK 1.4 en las mejoras NIO originales. El aporte más obvio en NIO 2 es el replanteamiento completo de los API de archivo de acceso. La mayoría de desarrolladores han usado java.io.File y están al tanto de la larga lista de defectos:
-Ausencia de soporte para links simbólicos
-Ausencia de soporte para movimientos rectos o atómicos y operaciones de copia.
-Engorrosos API para recorrer y filtrar directorios
-Soporte muy limitado para acceder a autorizaciones y atributos de archivo.
-No necesita API para ver directorios o archivos
-Capacidades restringidas para manejar errores (se limita a señales de retorno poco llamativas y IOExceptions genéricas)
Afortunadamente, el JSR 203 mejora todas estas áreas y más. El API ha sido diseñado de manera que puede extenderse desde el comienzo, aplicando la idea de los FileSystems enchufables, además del Filesystem por defecto. Asimismo, tiene sets de opción flexible para acciones como abrir y copiar archivos, y para definiciones de atributos dependientes del sistema.
El Listado 2 muestra cómo se puede usar el JSR 203 para algunas operaciones comunes. Path está en el centro mismo del API, se le puede considerar como el nuevo File. 
Listado 2. Algunos usos para JSR 203
import java.nio.file.*; 
// FileSystems -> FileSystem -> Path
FileSystem fileSystem = FileSystems.getDefault();
Path homeDir = fileSystem.getPath("/Users/lskywalker"); 
// Shortcut with Paths helper class
Path homeDir = Paths.get("/Users/lskywalker");
Path secrets = homeDir.resolve("secrets.txt"); 
// Steal secrets
secrets.moveTo(Paths.get("/Users/dvader/secrets.txt"));
Además de los API de filesystem, el JSR 203 complementa varios de los API que se iniciaron con la primera encarnación de NIO, suministrando más soporte para tareas multicast (multipunto) y un nuevo conjunto de API para IO asíncrono en archivos y files and conexiones.  
Enfrentar la dimensión de tiempo
Hace rato que las clases Java Date y Calendar necesitaban una revisión. El API JSR 310: Date and Time se ocupa de esa tarea pendiente proponiendo una nueva biblioteca que se hace cargo de la siempre traicionera dimensión del tiempo. 
En efecto, el JSR 310 ofrece soporte tanto para tiempo continuo como para tiempo a escala humana. La primera define el tiempo como una serie de discretas señales en una resolución de nanosegundos. El API define un Instante como un punto en el tiempo, y un Intervalo como el tiempo entre un Instante y otro (incluyendo tanto intervalos abiertos como cerrados). Asimismo, una Duración es una extensión de tiempo continuo que no está enlazada a ningún instante particular.  El Listado 3 presenta algunos ejemplos de tiempo continuo:
Listado 3. Tiempo continuo
// Create some instants in seconds (Ojo: no sé si cabe traducir porque es código, y como tal suele ir en inglés, creo, pero traducido sería como sigue: Crear algunos instantes en segundos. He dejado sin traducir el resto del código, pero si hace falta solo me indicas para completarlo, por fa)
Instant start2008 = Instant.instant(1199167200);
Instant start2009 = Instant.instant(1230789600);
assert start2008.isBefore(start2009); 
// Create an interval - [inclusive, exclusive] by default
InstantInterval year2008 = 
 InstantInterval.between(start2008, start2009);
assert year2008.contains(start2008);
assert ! year2008.contains(start2009); 
// Create a duration in seconds
Duration minute = Duration.duration(60);
Duration hour = minute.multipliedBy(60);
Duration duration2008 = Duration.durationBetween(start2008, start2009);
Para el tiempo de escala humana, el JSR 310 define una serie de clases con información mejorada. El nivel más bajo es LocalDate (solo una fecha, como 21 de julio de 1969), LocalTime (solo una hora, como 6:00:00) y LocalDateTime, que combina las dos precedentes. Las clases Local no están enlazadas a ninguna zona ni a un Instante en la línea de tiempo continuo.
El OffsetDateTime agudiza la precisión especificando un ajuste hora-zona a partir de la hora universal coordinada (UTC), que define un punto en la línea de tiempo continua, pero no permite razonar sobre las reglas hora-zona, que suelen basarse en decisiones políticas y gubernamentales. Finalmente, el ZonedDateTime enlaza un ajuste específico a una hora-zona particular, permitiendo que el usuario razone sobre temas como Daylight Saving Time y otros tópicos específicos de hora-zona.  
El atributo Clock es una fachada para ingresar momentos vigentes, tanto en la escala de tiempo continua como en la humana. Una de las características más interesantes de Clock es que está definido como una clase abstracta con método de fábrica para obtener el sistema Clock. De todas maneras, por tratarse de una abstracción, el usuario puede definir su propia implementación de subclase Clock y acceder a la hora en cualquier otra fuente o tener más control para evaluarla. El listado 4 presenta un ejemplo de luso de clases de fecha y tiempo a escala humana:
Listado 4. Usando tiempo a escala humana y el atributo Clock
// Local human-scale (no ligado a HoraZona ni a Instante)
LocalDate dDay = LocalDate.date(1944, mesdelaño.Junio, 6);
LocalTime quittingTime = LocalTime.time(17, 0);
LocalDateTime start2008 = LocalDateTime.dateTime(2008, mesdelaño.ENERO, 1, 0, 0, 0); 
// Tie to time zone offset of -6 hours from UTC
OffsetDateTime start2008Offset = OffsetDateTime.dateTime(start2008, ZoneOffset.zoneOffset(-6)); 
// Tie to current local time zone
ZonedDateTime start2008Zoned = ZonedDateTime.dateTime(start2008, Clock.system().timeZone());
Finalmente, el JSR 310 ha sido construido para interactuar con las antiguas clases Date y Calendar, y tiene soporte completo para funciones como formateo, análisis, reglas de hora-zona y más.
Procesamiento paralelo
El JSR 166y es lo que se podría llamar una revisión de mantenimiento del JSR que nos abre las puertas para acceder a las utilidades de java.util.concurrent goodies incluidas en el J2SE 5.0 y que, al mismo tiempo, ofrece una actualización al Java SE 6. La principal novedad del JSR 166y es un nuevo paquete de procesamiento paralelo llamado fork/join. Entre sus particularidades, el fork/join brinda soporte para trabajar algoritmos del tipo divide y vencerás, que subdividen sucesivamente el trabajo hasta dejarlo en fracciones suficientemente pequeñas como para resolverlas secuencialmente. Además, el Fork/join ha sido implementado como un conjunto de colas de trabajo y una técnica conocida como work stealing (robo de trabajo), a través de la cual los trabajadores desocupados pueden robar trabajo de otras colas de espera. El punto medular de la biblioteca fork/join es una nueva clase, bautizada como ForkJoinPool (que vendría a ser el centro de la madeja de hilos) y un set de tipos de tareas para la descomposición de problemas.
En general, las aplicaciones típicas no suelen tener muchos usos para un marco de soluciones de computación intensiva basado en algoritmos divide y vencerás. De todas maneras, el  JSR 166y también presenta un nuevo API estilo funcional para trabajar en selecciones paralelas. En efecto, el ParallelArray es un conjunto de elementos de dominio cuyo trabajo es soportado por un ForkJoinPool. El usuario puede definir diversos operadores comunes funcionales -como filtro, map, etc.-, y aplicarlos a un ParallelArray. El beneficio real de este atributo radica en que dichas operaciones se ejecutan en paralelo a través del ForkJoinPool y, en el futuro, pueden aprovechar automáticamente el incremento de conteos del procesador sin necesidad de modificar las funciones. Todavía no se decide si el ParallelArray se incluirá como parte del JDK en Java SE 7 o si será lanzado como una biblioteca externa.  El Listado 5 muestra un ejemplo de cómo se puede administrar una vasta colección de donuts con un ParallelArray.  
Listado 5. Usando un ParallelArray
// Instantiate the ForkJoinPool with a concurrency level
ForkJoinPool fj = new ForkJoinPool(16);
Donut[] data = ...
ParallelArray<Donut> donuts = new ParallelArray(fj, data);
// Filter
Ops.Predicate<Donut> hasSprinkles = new Ops.Predicate<Donut>() {
public boolean op(Donut donut) {
return donut.hasSprinkles();
}
}; 
// Map from Donut -> Integer
Ops.Predicate<Donut> daysOld = new Ops.ObjectToInt<Donut>() {
public int op(Donut donut) {
return donut.age();
}
}; 
SummaryStatistics<Integer> summary =
orders.withFilter(hasSprinkles)
.withMapping(daysOld)
.summary(); 
System.out.println("with sprinkles: " + summary.size());
System.out.println("avg age: " + summary.average());
Las utilidades simultáneas introducidas en el J2SE 5.0 y mejoradas en el Java SE 6 proveen una base sólida para escribir aplicaciones concurrentes en las máquinas de núcleo cuatro a ocho que suelen tener los servidores en rack. La biblioteca fork/join nos permite ir un poco más lejos haciendo que nuestra lógica se pueda manejar en paralelo y de forma gradual entre un amplio número de núcleos, tales como las máquinas de núcleo 16 a 32 que estarán disponibles en un par de años. Esta funcionalidad nos da cierto margen de acción, pero de ninguna manera resuelve el problema de la simultaneidad. Todos en la industria buscan nuevas maneras de aprovechar y mejorar el mundo multicore en que vivimos. Aunque, Java tiene algunos cuerpos de avance en esta tendencia, todo indica que, dentro de una década, la simultaneidad de estado compartido resultará insuficiente. Fork/join es solo un paso más en este largo camino.
Mayor precisión entre anotaciones 
Desde que el J2SE 5.0 nos introdujo al mundo de las anotaciones, estas aún siguen dando que hablar como alternativa a la metadata de configuración externa XML. En Java SE 6, las anotaciones solo pueden ocurrir dentro de una clase, método, campo y declaraciones variables. El JSR 308: Annotations on Java Types permite que las anotaciones ocurran en cualquier situación posible, ofreciendo así la posibilidad de obtener sistemas de tipo más expresivo y preciso.
El JSR en sí mismo no define ninguna anotación adicional, pero abre las puertas para anotaciones como las que se podían definir en el JSR 305: Annotations for Software Defect Detection. El objetivo de las anotaciones del JSR 305 es que los desarrolladores puedan definir con mayor precisión la semántica de las llamadas de método, tales como aceptar entradas nulas o colecciones vacías, y así sucesivamente. El listado 6 muestra algunos ejemplos de la manera en que pueden usarse las anotaciones. 
Listado 6. Mayor precisión con las anotaciones
// A more precise class definition:
class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... } 
// A more precise variable declaration:
List<String> str = new @NonEmpty @Readonly ArrayList<String>(stringSet);
Los procesadores de anotación se pueden conectar al compilador mediante estas anotaciones en tiempo compilado. Si bien, de esta forma se obtiene mucha mayor especificidad y precisión, el costo verbal es muy alto y, sin duda, puede resultar intimidante para algunos usuarios.
Simplificar el balance
Ya se encuentra en el horno una terna de JSR relacionados con el balance. El JSR 296: Swing Application Framework provee el marco y la funcionalidad que necesita la mayoría de aplicaciones Swing para simplificar el desarrollo. Entre sus atributos específicos destacan:
-Un ciclo de vida bien definido para la aplicación.
-Inyección de recursos (como etiquetas, fuentes y colores) 
-Administración de acciones (incluyendo soporte para tareas de background)
-Información constante de sesiones, como ventana de ubicación.  
Desde la presentación de su primera especificación, en el 2008, pareciera que el JSR 296 se ha mantenido en una especie de limbo. Aunque ha dado algunas señales de vida, no son pocos los que se preguntan si esta propuesta será resucitada a tiempo para el Java SE 7.  
Tanto el JSR 295: Beans Binding como el JSR 303: Bean Validation apuntan a resolver problemas comunes de las aplicaciones Swing pero también se pueden usar en situaciones no-Swing. Así, el JSR 295 se hace cargo de la necesidad de enlazar una serie de campos dentro de dos (o más) objetos. Las propiedades se pueden enlazar ya sea en una como en ambas direcciones, y las extensiones soportan modelos comunes de Swing como listas y cuadros. El JSR 303 es un framework orientado a crear validaciones para campos y clases. El JSR define un conjunto de meta-anotaciones así como un conjunto de anotaciones restringidas.
Actualizaciones de Java Management Extensions (JMX)
El JSR 255: JMX 2.0 es una actualización integral a la especificación JMX, que aprovecha totalmente los atributos de lenguaje introducidos en el J2SE 5.0 agregando, a su vez, nuevos e importantes atributos entre los que se incluyen espacios de nombre, agrupación  de servidores remotos JMX, un nuevo servicio de eventos, un lenguaje query, y más.  
Por su parte, el JSR 262: Web Services Connector for JMX permite que los clientes se conecten a través de servicios web a un JMX MBean (que, obviamente, trabaja para clientes de servicio web que no son Java) 
Cambios de lenguaje
Teniendo en cuenta el limitado margen de tiempo que le queda al Java SE 7 y la aparente reticencia a incorporar nuevos atributos de lenguaje, cabe esperar que la especificación de plataforma Java SE 7 incluya solamente pequeños aportes en este sentido. Por el momento, se sabe que Joseph Darcy organizará un proyecto OpenJDK para reunir y evaluar estos cambios de lenguaje.
En todo caso, los Closures o cierres son el principal atributo de lenguaje propuesto para Java SE 7. Sin duda, su incorporación tendrá un gran impacto en el lenguaje, así como los otros JSR que hemos discutido hasta el momento. Una serie de propuestas ya se han dado a conocer, y tres de las más populares ya se encuentran en fase prototipo. Podemos mencionar particularmente el trabajo de Neal Gafter para cierres BGGA que, además de incluir especificaciones completas y una implementación terminada, es la propuesta que ha sido analizada con mayor profundidad.   
Dados los cada vez menores recursos disponibles en Sun, la cantidad de JSR interesantes, y la presión por sacarlos al mercado, resulta poco probable que los closures se incluyan en el lanzamiento de Java SE 7. En mi opinión, sería una lástima porque los closures podrían simplificar partes del API en el NIO 2, el fork/join y otras bibliotecas. Si el Java SE 7 prescinde los closures, esta posibilidad se anularía.
Entre las mejoras menores que podría presentar el lenguaje tenemos: 
-En el caso de un cambio de vía, se pueden usar series o Strings.
-Los operadores de comparación (<, >, etc.) trabajan directamente con constantes enum.
-Los métodos de invocación encadenada — vacío, devuelven  implícitamente lo mismo, permitiendo la concatenación de método.
-Los métodos de extensión y los métodos importados estáticamente también pueden ser llamados como si se tratara de métodos objeto, de manera que las API tienen la posibilidad de extenderse después del hecho mediante clases de utilidad estática.
-Detección mejorada de tipos de excepción múltiple a la vez y relanzamiento subsecuente de estos mismos tipos específicos.
Soporte de lenguaje dinámico
El JSR 292: Supporting Dynamically Typed Languages de la plataforma Java fue concebido inicialmente para introducir un nuevo código de bytes JVM, denominado invokedynamic, para ofrecer un mejor soporte a los lenguajes dinámicos. Posteriormente, John Rose usó el JSR como una especie de foro para explorar posibles mejoras a JVM que podrían ser útiles para lenguajes diferentes de Java  en JVM. 
Este trabajo terminó con la primera Cumbre de Lenguaje JVM, realizada en setiembre del 2008, en la que se discutió sobre atributos como la optimización de la cola de llamadas y la inyección de interfase. Para los lenguajes funcionales que utilizan intensivamente la recursividad, la importancia de la mencionada optimización radica en que les permite evitar quedarse sin espacio de almacenamiento. Scala resuelve este tema en el propio compilador. Clojure tiene un lenguaje para colas de llamada simuladas y acaba de agregar un soporte de lenguaje para pasar a un soporte de mutua recursividad. Si dicha optimización llega a incorporarse al JVM, Scala y Clojure podrían simplificar o eliminar estos atributos.
En la Cumbre de Lenguaje JVM, Mark Reinhold afirmó que el JSR 292 será incluido en el Java SE 7. Sin embargo, aún no se sabe a ciencia cierta si otros atributos, además de invokedynamic, serán considerados como parte del JSR 292. 
Java SE 7 y el futuro de Java
Pienso que el Java SE 7 plataforma JSR, que saldrá en el 2009, incluirá la mayoría los JSR reseñados en este artículo, pero solo muy pocos -o quizá ninguno- de los cambios de lenguaje. Queda aún un largo trecho para integrar todo este trabajo en el edificio OpenJDK y lanzarlo con Java SE 7 a inicios del 2010, como está programado hasta el momento. 
Algunos se preguntan si el Java SE 7 todavía es relevante y por qué alguien querría siquiera darse el trabajo de usarlo. Pues bien, aun a pesar de la llegada de lenguajes alternativos basados en JVM, Java sigue siendo uno de los lenguajes más importantes usados en la actualidad. En efecto, Java tiene una base instalada tan grande que tendrán que pasar generaciones de programadores antes de que deje de tener vigencia. JSR como el 294, el 310, y el 203 pretenden actualizar los API centrales o nucleares con cambios que resulten atractivos para los desarrolladores de software para empresas. Asimismo, el avance hacia la era multicore también hará que tanto el JSR 166 como las mejores de rendimiento JVM resulten más interesantes.
Creo que la adopción a gran escala del Java SE 7 será lenta pero segura. Asumiendo que la plataforma se lanzada a inicios del 2010, es muy probable que antes del 2011 la nueva versión ya haya ganado una significativa porción del mercado. Anteriormente, hemos sido testigos de la misma progresión lenta pero sostenida cuando Java SE 6. J2SE 1.4 incorporó el End of Service Lifecycle (fin del servicio de ciclo de vida) en noviembre del 2008, y J2SE 5.0 se le unirá a fines de este año. Para cuando eso ocurra, muchos de los negocios que hacen desarrollo basado en Java estarán buscando o desplegando ya en Java SE 6. Si bien los cambios de lenguaje en Java SE 7 son mínimos, como indicamos previamente, muchos negocios podrían saltar directamente del J2SE 5.0 al Java SE 7. 
Alex Miller, JavaWorld USA
Alex Miller trabaja en Tech Lead para Terracotta Inc, fabricante de Terracotta, el producto clustering de Java para fuente abierta. Previamente, trabajó en BEA Systems para la línea de productos AquaLogic y fue arquitecto en jefe de MetaMatrix. Su blog es http://tech.puredanger.com, ofrece conferencias a grupos de usuarios y participa en el tour No Fluff Just Stuff. Es un amante esposo y padre de tres hijos, y se declara también amante de la música y los nachos.