Cambios en en el stack de Amneris (Tiempo de Balances 1)

El stack de Amneris ha sufrido grandes cambios en los últimos meses. Tenemos 3 nuevas incorporaciones, 2 jubilaciones, y un retiro por invalidez :)

En primer lugar damos la bienvenida oficial a Tapestry5 que si bien ya hacia tiempo que estaba dando vueltas por los alrededores, no había sido debidamente presentado. La adopción de Tapestry5 deja a Tapestry4 relegado al mantenimiento de aplicaciones legacy.

De la misma manera que Tapestry4, se retira con honores Trails 1.x, que ya ha cumplido su ciclo, para dejar paso al todavía en desarrollo Trails 2 basado en Tapestry5. Trails 2 está todavía muy lejos de ofrecer todas las prestaciones que ofrece se hermano menor, pero no tiene sentido seguir invirtiendo tiempo en Trails 1 cuando el framework principal en el que se basa está ya completamente obsoleto. Esto conlleva también el esfuerzo de ir migrando de a poco todos nuestros otros frameworks y librerías que se basaban en Trails.

La incorporación de Tapestry5 al stack desplaza también a Spring como framework de IoC por defecto del stack. Spring (a mi parecer) a dejado de innovar en el espacio de la IoC y en estos momentos hay ofertas muchísimo más interesantes como Guice y Tapestry5 IoC. La cantidad de código basado en Spring IoC que tenemos es tal que reemplazarlo no será tarea fácil, pero de ahora en adelante Spring no será la primer alternativa a la hora de implementar IoC en nuestras aplicaciones. Trails2 será completamente independiente de Spring. Completamente compatible SI, pero independiente al fin.

Ya he mencionado la incorporación de Tapestry5 y Trails2 pero el gran fichaje de la temporada es Magnolia CMS. Trails nos estaba quedando un poco chico para según que cosas y necesitábamos incorporar una solución robusta que nos garantizara estabilidad pero con flexibilidad. Magnolia se usa detrás de los sitios de InfoQ y JBoss.org, así que si puede con la carga de esos dos sitios, podrá manejar nuestra carga sin ningún inconveniente. Otra gran característica de Magnolia es la implementación de Java Content Repository (JCR - JSR-170) que nos da una gran tranquilidad respecto de que nuestros datos son almacenados siguiendo un estándar abierto para la gestión de contenido.

Bienvenidos Magnolia, Tapestry5 y Trails 2!

Gmail & Magnolia & JavaMail [FIXED]

(continuación de Gmail & Magnolia & JavaMail)

Finalmente lo entendí! y resulta que los simpáticos muchachos de SUN tenían razón. Hay que leer hasta entender.

Lo que estaba haciendo mal era agregar un SSLSocketFactory cuando la comunicación era TLS.
Claro, ahora es fácil decirlo: "si es TLS obviamente no necesita socket SSL!", pero costó sangre darse cuenta.

La configuración finalmente queda así:


if (Boolean.valueOf((String) this.mailParameters.get(SMTP_SSL)).booleanValue()) { // port 465
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
}

if (Boolean.valueOf((String) this.mailParameters.get(SMTP_TLS)).booleanValue()) { // port 587
props.put("mail.smtp.starttls.enable", "true");
}


Gracias a Teresa Miyar el parche ya está integrado en el trunk de Magnolia. :)

.

Gmail & Magnolia & JavaMail

Estaba trabajando en agregar soporte para Gmail en Magnolia (MAGNOLIA-2420), dándome la cabeza contra la pared con errores de JavaMail cuando me encontré con este grato aviso en la documentación
Note also that THERE IS NOT SUFFICIENT DOCUMENTATION HERE TO USE THESE FEATURES!!! You will need to read the appropriate RFCs mentioned above to understand what these features do and how to use them. Don't just start setting properties and then complain to us when it doesn't work like you expect it to work. READ THE RFCs FIRST!!!
(Las negritas también son originales: http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html)

Que simpáticos los muchachos de SUN!!!

Para conectar JavaMail con Gmail la misma FAQ oficial de JavaMail propone usar unos parámetros de configuración "smtps" (notar la S final) que no aparecen en ningún otro lugar de la documentación y que, como siempre, a mi no me funcionan. Buscando por la red he encontrado varias referencias a la configuración con "smtps", pero ninguna oficial. http://www.google.com/search?q=%22mail.transport.protocol%22++site%3Ajava.sun.com

Dado que la documentación no me ayudaba decidí seguir sus consejos y esto es lo que encontré:

La documentación de Gmail indica que Gmail soporta 2 puertos para la conexión SMTP: el 465 y el 587, e indica también que debe usarse el comando STARTTLS.

El comando STARTTLS debería iniciar una comunicación encriptada sobre el submission port 587 siguiendo el protocolo TLS según el RFC 2476: Message Submission. Pero por alguna razón (que todavía no he descubierto) JavaMail da un mensaje de error al intentar usar este puerto. Después de probar varias configuraciones decidí probar el otro puerto, que si que funcionó al primer intento.
El puerto 465 es "menos" estándar (incluso hay otro servicio, el URD - “URL Rendesvous Directory for SSM” registrado por Cisco en el mismo puerto) y utiliza el protocolo SSL. El puerto 465 se menciona en el apendice A de la especificación: The SSL Protocol Version 3.0 “Simple Mail Transfer Protocol with SSL” de 1996.

La diferencia entre SSL y TLS es muy sutil y es simplemente la versión. SSL hace referencia a SSL 3.0 y TLS hace referencia a TLS 1.0 que es igual a SSL 3.1
Repito:

TLS 1.0 == SSL 3.1

Aunque el protocolo permanece sustancialmente igual existen pequeñas diferencias entre SSL 3.0 y TLS 1.0.

Al final la configuración del JavaMail para Gmail quedó algo así:

Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");

props.put("mail.debug", "true");

Session session = Session.getInstance(props);

(Java 1.6 valida automáticamente los certificados de Gmail así que no hay necesidad de agregarlos a mano a la truststore)

Aunque encontré una solución a mi problema, y el código ya está funcionando me quedé muy intrigado de porqué no funciona con el puerto 587 y porqué en la red hay tantas referencias a la configuración "smtps" pero la única referencia oficial está en la FAQ, así que, aunque sea para sacarme la duda, seguiré investigando.

.