blog de ezamudio
Java 8: mis primeros tropiezos
Pues ahora que ya salió oficialmente Java 8, lo instalé y empecé a hacer pruebas, con un proyecto grande que ya llevo desde hace varios años (empezó en Java 1.4 y lo he migrado a Java 5, 6, 7 y ahora seguirá la 8).
Cuando he migrado, las etapas suelen ser así:
Primero correr las aplicaciones tal cual están, sin modificar nada, sobre la nueva JVM. Eso parece que está funcionando bien (pero tendrán que estar en observación varios días obviamente).
Luego, compilar el código tal cual está, sin modificar nada, con el nuevo compilador. Aquí es donde me di de topes ya desde ahorita. Pasaron dos cosas:
Utilizo Lombok para reducir código en varios lugares y facilitarme la vida en general cuando programo en Java. Una de las cosas que trae es la anotación
, que permite tratar una excepción verificada como si fuera
al momento de compilar. Pero al compilar código que utiliza esta anotación en Java 8:
Y esto es usando la versión 1.12.6 que se supone ya trae soporte para Java 8.
Clases internas en Groovy
Acabo de toparme con un problema en Groovy. Tristemente la solución que todo mundo da en foros es simplemente "no lo hagas, es mejor si haces [cualquier otra solución]"; pero, qué tal si lo que necesitaba era esto?
Bueno y ¿cuál es el problema? Es simple: el soporte en clases internas tiene problemas con atributos heredados en la clase externa. Tiene solución, y es sencilla, pero me parece una leaky abstraction y honestamente la encontré por pura suerte, buscando maneras de darle vuelta al asunto.
El problema se da bajo estas circunstancias:
Web Services en Axis2 con Spring y Gradle
Recientemente en un proyecto un cliente nos dijo que la interfaz entre nuestros sistemas sería... esperen... sí... un web service. Un web service que ellos invocarían y que por lo tanto nosotros tenemos que implementar. Así que nos dieron un par de archivos WSDL y unos ejemplos de XML para asegurarnos que salga como debe ser (no entiendo para qué, si todas las herramientas de generación de web services se encargan de que el XML siempre salga como debe ser, ¿verdad?).
Cuando tengo que invocar un web service, generalmente uso Axis2. Me ha resultado de lo más sencillo porque consiste simplemente en ejecutar el script
dándole el URI del WSDL y con eso tengo una clase que puedo usar para invocar los servicios (junto con mil clases internas que envuelven los datos dentro de envoltorios intermedios porque parece que los de Axis entendieron OOP como Onion-Oriented Programming). Así que en esta ocasión decidí probar el otro lado de la implementación: publicar un servicio hecho con Axis2.
Comparativo de desempeño para formato de fechas
Comparto esto para los que tengan la misma duda que yo tenía: Saber si es más rápido usar
o un
para formatear una fecha.
Es claro que
puede ser más simple de codificar, sobre todo en ambientes concurrentes, ya que SimpleDateFormat no es thread-safe y por tanto hay que usarlo solamente de manera local o bien envolverlo en un
.
Pero pues hice un programa muy simple en Groovy para comparar el performance de ambos:
Game Of Life en Ceylon
En el Code Retreat que hubo en Agosto de 2012, el reto fue implementar el famoso Game of Life, en parejas. En mi equipo, @juwe y yo lo desarrollamos en Ceylon (no me impuse; él se animó, jejej).
Apenas hoy lo pude subir a un repositorio que tenemos en GitHub especialmente para ejemplos de Ceylon, después de darle una buena actualizada al código porque han habido varios cambios en la sintaxis y en el módulo de lenguaje desde que escribimos esto originalmente: ya teníamos comprensiones, funciones de orden superior, funciones anónimas y varias otras cosas, pero no teníamos por ejemplo el
, tuplas, ni la sintaxis actual para secuencias y colecciones iterables; la sintaxis para funciones anónimas cambió ligeramente, al igual que la de parámetros variádicos (los famosos varargs).
Migrar de Subversion a Git, sin mirar atrás
Este post no es realmente acerca de Java, pero quiero dejarlo en este sitio de todas maneras, ya que realmente no tengo otro blog y además no deja de ser algo muy técnico.
En mi trabajo desde hace varios años utilizamos Subversion, pero decidimos pasarnos a Git. El mismo Git incluye herramientas para integración con svn, pero son algo limitadas. Además creo que es un buen pretexto para aprovechar y reorganizar el repositorio, partiéndolo en varios repositorios distintos, abandonando algunas cosas obsoletas, ramas que llevan años abandonadas, etc.
En mi búsqueda por lograr esto, me encontré con esta herramienta llamada svn2git:
Parece que la desarrolló el equipo de KDE, para realizar lo mismo que yo estaba buscando: migrarse de una buena vez de svn a git, sin mirar atrás, reorganizando su código en varios repositorios, etc.
Esta herramienta está hecha en C++ y requiere Qt para poderse compilar, aunque no tiene interfaz gráfica. Debe ejecutarse en el servidor que contiene el repositorio de Subversion que se quiere migrar (no una copia de trabajo).
Comprehensiones en Ceylon
Las comprehensiones (o algo que se les parezca) son una característica ya prácticamente obligatoria en los nuevos lenguajes, al menos si quieren ser considerados cool. Y Ceylon no se queda atrás.
Las comprehensiones en Ceylon funcionan usando una variante especial de
, la cual acepta una sola expresión, en vez de un bloque de código. La expresión puede ser a su vez otro
, o bien un
, que actúa como un filtro, o cualquier otra expresión que devuelva algún valor. Todo eso termina siendo azúcar sintáctica para crear y devolver un objeto
que se puede pasar en invocaciones a métodos o funciones que esperan argumentos secuenciados (de los que terminan con elípsis), o usarse directamente en cualquier lugar donde se pueda usar un
.
Esto a fin de cuentas puede ser más poderoso que tener métodos como
y
en las colecciones, y además permite hacer implementaciones más eficientes, ya que los iteradores intermedios involucrados se van utilizando conforme se necesitan, en vez de tener que procesar completamente una colección antes de pasar a la siguiente fase.
Si usan Groovy o Scala, puede que ya estén familiarizados con algunas de estas operaciones. Por ejemplo, tomar una lista de palabras y devolverlas en reversa:
Funciones en Ceylon, segunda parte
En mi post anterior, hablé acerca de las funciones de orden superior, la manera en que se pasan referencias a métodos, cómo se invocan, etc. Pues bien, ha habido bastante progreso en Ceylon, en varias áreas, y una de las que considero importantes es precisamente el manejo de funciones; algunas de las cosas que mencioné en ese post han cambiado, mientras que ha surgido funcionalidad nueva que no estaba disponible previamente. Así que veamos los cambios:
Callables
Primero que nada, ya no tenemos la restricción de que un
no podía ser invocado; ahora ya se puede, por lo que esto ya es válido:
La otra forma sigue siendo igual de válida:
Argumentos por nombre
En Ceylon hay dos formas de hacer una invocación: usando argumentos posicionales (que es la manera en que todo mundo está acostumbrado a hacerlo) o usando argumentos nombrados (que no todos los lenguajes tienen y los que lo tienen, usan distintas sintaxis).
Ceylon M2
El segundo release de Ceylon, M2 aka "Minitel", ya está disponible.
Algunos de los cambios más importantes desde M1 que salió en diciembre, están:
- Interoperabilidad con Java - ya se puede invocar código Java desde Ceylon, con algunas restricciones pero en general ya está funcionando.
- Referencias a funciones y métodos - con esto hay bastante avance en lo que respecta a funciones de orden superior; ya se pueden pasar referencias a métodos y/o funciones como parámetros a otros métodos/funciones y también puede haber métodos/funciones que devuelvan Callables. Asimismo, se pueden definir métodos o funciones simplemente asignándoles una referencia a otro método o función que tenga la misma firma.
- Performance - se optimizaron las operaciones aritméticas con Integer y Float, así como algunas operaciones que requieren boxing/unboxing (principalmente para interoperar con Java)
- SDK más completo - El SDK ya incluye varias interfaces y clases para colecciones: Collection, Array, List, Map, Set, FixedSized, etc.
Funciones de orden superior en Ceylon
Ceylon tiene una característica que en lo personal me parece muy atractiva, algo que en otros lenguajes anuncian con gran fanfarria pero en Ceylon no se ha hecho tanto barullo. Es algo que creo que ayudará mucho para el diseño de APIs en el futuro cercano. Se trata de las funciones de orden superior.
Visto de manera simple, las funciones de orden superior son funciones que reciben otras funciones como parámetros, o bien que devuelven funciones como valor de retorno. El concepto realmente no es complejo; el truco en lenguajes de tipado estático está en que la sintaxis no sea compleja (en lenguajes dinámicos es muy sencillo pasar una referencia si no se tiene que indicar el tipo de retorno de la función, ni su número ni tipo de argumentos).
Una cosa muy necesaria para poder manejar funciones de orden superior en un lenguaje de tipado estático, es tener un tipo que las represente. En el caso de Ceylon, tenemos la clase
. Podemos usar este tipo para guardar la referencia a un método de un objeto por ejemplo. Suponiendo que tuviéramos una clase
con un método
que reciba un entero y devuelva un string, entonces podemos hacer esto:
Ojo, no es lo mismo
(lo cual es una invocación al método) que
, que es simplemente obtener la referencia a ese método; a partir de entonces se puede manejar como una función.