jueves, 27 de noviembre de 2008

HOWTO: Importar un certificado servidor de Apache en un almacén JKS

[Offtopic: Esta entrada no habla sobre rendimiento]

Si tenemos un servidor Apache configurado para atender por SSL con su certificado servidor y su clave privada, y queremos utilizar el mismo certificado servidor en una aplicación Java, ¿cómo hacerlo?

Usos: por ejemplo si queremos eliminar Apache como proxy inverso y que nuestro motor de servlets (Glassfish, Tomcat o lo que sea) sea el frontal web directamente, o si queremos utilizar el mismo certificado que tenemos en el Apache para otros propósitos como por ejemplo en un servidor FTPS hecho en Java (como Apache Mina) o cualquier otro servicio paralelo.

Para ello lo más sencillo es utilizar un PKCS#12 pivote, que luego podremos eliminar.

Comandos:

$ openssl pkcs12 -export -in <certificado.cert> -inkey <claveprivada.key> -out <pkcs12.p12>
$ keytool -importkeystore -srckeystore <pkcs12.p12> -srcstoretype PKCS12 -destkeystore <almacen.jks> -deststoretype JKS

Obviamente, reemplazar <certificado.cert>, <claveprivada.key>, <pkcs12.p12> y <almacen.jks> por los nombres adecuados (ficheros origen utilizados por nuestro Apache, y JKS destino que se utilizará por nuestra aplicación Java).

Nota: la opción -importkeystore sólo es válida a partir de Java 6. En JDKs antiguos se utiliza "-import -pkcs12" (creo, pero tendría que tirar de archivo...)

domingo, 23 de noviembre de 2008

Compatibilidad entre versiones de Hotspot y versiones del JDK

Este es mi descubrimiento más curioso de todos en los últimos meses. Lo que en realidad me resulta curioso es no haberlo sabido/intuido hasta ahora. Es bueno estar siempre aprendiendo cosas nuevas, y es bueno también bajarse los humos uno mismo de vez en cuando...

Tradicionalmente muchos suelen confundir JDK y JVM. Pero son dos cosas distintas, una cosa es la versión de las bibliotecas Java, versión de bytecode y compilación javac (JDK) y otra muy distinta es la máquina virtual que ejecuta las aplicaciones Java. Esto lo he tenido claro siempre, lo que no sabía es que Hotspot tiene compatibilidad hacia atrás con versiones anteriores del JDK...

Con JRockit, esta diferenciación siempre ha estado muy clara, tanto por los usuarios como sobre todo por el equipo de JRockit/Bea/Oracle/quien_les_compre_a_continuación. Ellos distribuyen una versión de su VM "empaquetada" junto con una versión del JDK. De hecho, la versión JRockit 27.5 es compatible con JDK 1.4, JDK 1.5 y Java 6. Misma VM, diferente JDK en el paquete.

Pero estas semanas he estado haciendo pruebas y hablando con los ingenieros de Sun, resulta que Hotspot también es independiente del JDK y compatible hacia atrás con todos ellos (desde JDK 1.7 hasta JDK 1.5). En concreto he conseguido hacer funcionar con éxito y sin problemas aplicaciones sobre JDK 1.5 con Hotspot 14-b05 (distibuido en JDK 7 early access), y también el 6u6p con el mismo Hotspot 14 en lugar de el 13, que es el que venía por defecto...

¿Cómo se hace? Sencillo. Basta con identificar la bilioteca jvm de nuestro JRE y reemplazarla por la deseada. Algunos ejemplos:

  • En Windows, es el fichero jvm.dll que se encuentra tanto en <jre>\bin\server como en <jre>\bin\client (ojo, por supuesto que en realidad son distintas versiones, Hotspot cliente y Hotspot servidor)
  • En Linux x64, es el fichero libjvm.so que se encuentra en <jre>/lib/amd64/server

Del mismo modo, si no recuerdo mal, podemos poner la biblioteca jvm de JRockit en un directorio de instalación del JRE de Sun y viceversa. Es decir, la VM (Hotspot, JRockit, etc) es simplemente el libjvm.so si no me equivoco!

Lo que desde ya te puedo asegurar es que modificar la combinación JDK-JVM no está soportada por Sun. Así que, como suele decirse en estos casos... "Do it at your own risk!". Esto es lo que me dicen desde el equipo de Hotspot extraoficialmente cuando he preguntado por ello:

"Yes, for practical purposes, the latest HotSpot VMs should be compatible with JDKs back to 1.5, and we in engineering try hard to make that possible.

Sun, as a company, doesn't guarantee complete backward compatibility because of the huge testing matrix that would re required to verify each HotSpot release with every prior JDK. (We support more many more platforms than JRockit.)

So a customer can try out an new VM with an old JDK, but don't run your enterprise on it, and don't ask Sun to support it. ;-)"

:-)

martes, 18 de noviembre de 2008

Schedule de siguientes updates de Java 6. Versiones de Hotspot y compatibilidad entre ellas

Como veis, estoy dosificando (demasiado) la información que he obtenido de mi interacción con el equipo de ingenieros de Hotspot en Sun, que ha sido muy interesante y emocionante al mismo tiempo.

Como diría un amigo mío, a mi edad y aún sigo emoocionándome con chorradas... :-)

Y creo que ahora estoy dando una primicia.

Ni que decir tiene que esta información es absolutamente extraoficial (aunque probablemente el calendaro previsto sea público a colaboradores, seguro que está por https://jdk6.dev.java.net/ pero no he tenido tiempo de chequearlo) y que el calendario final puede variar por muy distintos motivos. Tampoco aseguro que la información sea verídica, es la que me han pasado desde dentro, eso sí que lo aseguro...

Calendario previsto de siguientes updates de Java 6:

  • Java 6 update 10 (6u10 / 1.6.0_10): recién liberado el 15 de octubre, con la nueva microarquitectura
  • Java 6 update 11 (6u11 / 1.6.0_11): reservado para posibles actualizaciones de seguridad, puede que no se produzca si no es necesario
  • Java 6 update 12 (6u12 / 1.6.0_12): planificado para Febrero o Marzo de 2009
  • Java 6 update 13 (6u13 / 1.6.0_13): reservado para posibles actualizaciones de seguridad, puede que no se produzca si no es necesario
  • Java 6 update 14 (6u14 / 1.6.0_14): Planificado para Mayo o Junio de 2009

Correspondencia entre versiones de Hotspot y distribuciones de Java 6:

  • Hotspot 10: incluido desde Java 6u04 (con diferentes builds y fixes en sucesivos updates u05, u06 y u07).
  • Hotspot 11: ya incluido en Java 6u10.
  • Hotspot 12: ¿? creo que nunca se liberará, por mis noticias es una vía muerta.
  • Hotspot 13: fue incluido en Java 6u6p ("performance release") a modo de anticipo de futuras mejoras de rendimiento, pero tiene algunos bugs reconocidos como el que indiqué en el anterior post. Dudo que lo incluyan en 6u12, seguramente dará paso a Hotspot 14 directamente...
  • Hotspot 14: su build 05 está actualmente incluido en Java 7 (desde algun snapshot relativamente reciente, no recuerdo cuál) y está previsto su lanzamiento para entornos productivos con Java 6 Update 14 (6u14). Es posible que se libere en 6u12 si consiguen solucionar ciertos problemas de estabilidad que actualmente tienen, aunque lo más probable es que no sea así y tengamos esperar a mayo-junio pues...

O lo que es lo mismo, salvo que haya fixes de seguridad, tengo bastante claro que dejaré mis entornos de producción estables con 6u07 hasta junio (quizás actualice a 6u10 en enero). Y entonces migrar en los entornos de Pruebas y comenzar la certificación... o sea, que preveo que actualizaré Producción después de verano, dando el salto desde Java 6u7 a 6u14...

:-)

lunes, 17 de noviembre de 2008

"What volatile means in Java" exposed by Jeremy Manson

Para quienes no sepan de él, Jeremy Manson es una de las eminencias y referencias en el mundo de la concurrencia Java y en el modelo de memoria Java, de hecho, fue uno de los papás del "nuevo" modelo de memoria Java allá por 2004-2005. Curra en Google, lo cual dice algo sobre su nivel, y hay a quien se le hace el culo pepsicola con estas cosas... (por eso lo menciono :-) Y es un tipo excepcionalmente abierto y amable aun cuando sabe que no tienes razón en lo que le expones, podéis buscar mis interacciones con él en su blog :-)

Jeremy ya lo expuso bastante bien en sus anteriores posts (que yo referencié aquí), y en realidad este no da excesiva información adicional. Pero está bastante bien explicado y con algún gráfico que se agradece...

Así que no me enrollaré mucho más. Ahí van los enlaces a sus tres posts acerca de las variables volátiles en el modelo de memoria Java:

Y esta es una gran PPT sobre el modelo de memoria en Java, escrito por el propio Manson et al.:

P.D: He actualizado también el post de julio sobre double-checked-locking con esta información...

miércoles, 12 de noviembre de 2008

Uso de Apache como proxy inverso de Glassfish V2

Aunque en muchos escenarios sería más que discutible... una práctica bastante habitual es tener un proxy inverso que sirva el contenido estático, haga balanceo y algunas reglas de seguridad delante de nuestro Glassfish.

Como digo es algo muy discutible en el 75% de los casos, la mayor parte de al gente lo hace como "buena práctica" y punto, pero no siempre hace falta y a cambio se complica un poquito más el sistema... Si se hace sólo por rendimiento, a día de hoy no tiene sentido porque Grizzly (el motor http de Glassfish) es muy óptimo y lo que se gana por un lado se pierde en las comunicaciones entre el proxy inverso y la aplicación final. Pero si se hace por seguridad (suele ser la excusa pero en la mayor parte de los escenarios no aporta nada, sobre todo si se ejecuta en la misma máquina que el Glassfish, je, je), o por balanceo de cargas o por caches, etc, etc. Entonces me callo. Sí que hace falta. Y es muy buena idea que sea Apache el servidor web escogido.

En cualquier caso. ¿Cómo hacer que un Apache 2 / 2.2 sea el frontal HTTP para nuestro Glassfish?

Espero que en V3 den soporte bien dado, para Glassfish V2 hay que hacerlo con mod_jk en el lado Apache y copiando unos jars de Tomcat 5.5 en el lado Glassfish. Sí lo habéis leído bien...

En todos estos enlaces están las instrucciones:

Pero, oh sorpresa, resulta que en los últimos meses las cosas han cambiado. Tomcat 6 no trae ningún tomcat_apj.jar (sino que lo han integrado en tomcat_coyote.jar) y la implementación en las versiones más recientes de Tomcat 5.5 no es compatible con Glassfish V2. ¿Te sale esta excepción al hacer una request?:


java.lang.NoSuchFieldError: USE_CUSTOM_STATUS_MSG_IN_HEADER
at org.apache.jk.common.JkInputStream.appendHead JkInputStream.java:283)
at org.apache.jk.core.MsgContext.action(MsgContext.java:267)
at org.apache.coyote.Response.action(Response.java:221)
at org.apache.coyote.Response.sendHeaders(Response.java:416)
at org.apache.coyote.tomcat5.OutputBuffer.doFlush(OutputBuffer.java:355)
at org.apache.coyote.tomcat5.OutputBuffer.close(OutputBuffer.java:321)
at org.apache.coyote.tomcat5.CoyoteResponse.finishResponse(CoyoteResponse.java:578)
at org.apache.coyote.tomcat5.CoyoteAdapter.afterService(CoyoteAdapter.java:318)


Si esta es la excepción, esta es tu solución: coge el tomcat_apj.jar de Tomcat 5.5.23 y no de ninguna posterior (actualmente van por la 5.5.27 en la rama 5.5). Y funciona perfectamente.

Al César lo que es del César, a mi me ha salvado la vida esta entrada: http://www.albeesonline.com/blog/2008/10/10/javalangnosuchfielderror-use_custom_status_msg_in_header/

Todo una guarrada, ¿verdad? Lo cierto es que dice poco del equipo de diseño de Glassfish, es como si no hubieran pensado en implantaciones "para el mundo real"... ¿?

sábado, 8 de noviembre de 2008

Identificación de bugs en la versión 6u6p y workaround

Como indiqué en el post 6u6-p: Pues en Linux x64 peta!!!!!!!, en mis entornos servidor tuve problemas en la versión 6u6p. Tras enviar el feedback a Sun, los ingenieros del Hotspot se pusieron en contacto conmigo e hicimos múltiples pruebas.

El trato ha sido maravilloso, y estoy encantado de haber podido ayudar a identificar el problema, aunque he de decir que ya lo tenían resuelto, je je.

Tras varias semanas, por fin hemos llegado a la conclusión de que se trataba de un problema con el análisis de escape (ver para más información sobre Escape Analysis, ver los posts Allocation, deallocation and escape analysis for Java y ¿Funcionan las optimizaciones sobre el modelo de threading? ), que ya estaba identificado en el bug 6726999 y que han resuelto en la versión 14 de Hotspot, cuyo build 05 por cierto se distribuye con los Early Access del JDK 7 y que está previsto que se incorpore en Java 6 en un update aproximadamente en mayo-junio. Habrá que esperar pues...

He aprendido varias cosas de las interioridades de Hotspot y de versiones, pero tengo otros posts preparados para eso... De momento sólo diré que con el nuevo 6u10 por fin se distribuye Hotspot 11, pero el desarrollo del mismo ya va por la versión 14... Como podréis imaginaros, la evolución a nivel de Hotspot está siendo espectacular aunque tenemos que esperar para ver cada versión en la calle...

Me han pasado también varias versiones del libjvm.so, en concreto versiones "fastdebug" que tracean información de ejecución y compilación, y tiene además toneladas de asserts. Por ejemplo, algunos parámetros de lanzamiento interesantes para las VM fastdebug:
  • -XX:+LogCompilation: para escribir en un fichero hotspot.log y en el especificado arriba información acerca de la compilación binaria en tiempo real
  • -XX:SuppressErrorAt= (por ejemplo -XX:SuppressErrorAt=/xmlstream.cpp:119) para que no se ejecute un cierto assert
A lo que íbamos. Aparte de todo este rollo, el único workaround de momento, si se quiere funcionar con la 6u6p en producción es ejecutarlo con el parámetro de lanzamiento -XX:-DoEscapeAnalaysis. Yo no voy a hacerlo, prefiero seguir con Java 6u07 en producción pero con esa opción habilitada (porque ejecuto bastantes clases compiladas para JDK 1.4, aggg, y está lleno de StringBuffers, que se benefician bastante de los análisis de escape, aunque en Hotspot 10 estén hastante limitados de momento.

Además, dejo una perlita... en toda la interacción con el equipo de ingenieros de Hotspot, me han dado información extraoficial acerca de fechas previstas de liberación de las siguientes actualizaciones de Java 6 y sus correspondencias con versiones de Hotspot. Esto lo publicaré en el siguiente post...

:-)

lunes, 3 de noviembre de 2008

Lanzamiento de Java 6u10

[Actualizado el 6/11/2008: algunas correcciones y ampliación del resumen ejecutivo con mis conclusiones]

Sun liberó el pasado día 15 de octubre por fin Java 6 update 10 (6u10), que puede descargar como siempre de http://java.sun.com/javase/downloads/, tras mucho tiempo en beta y release candidate...

Nota: la noticia tiene ya 15 días, pero he preferido no escribir sobre ello hasta haberlo probado, claro :-)

Se trata de un hito importante (llevaban en beta bastante tiempo) porque supone una pequeña revolución tecnológica al menos para usos "de escritorio". De hecho, si os fijáis ha habido un salto entre el anterior update (6u07) y este (6u10), es debido a que se empezarons a librerar versiones beta más o menos a la vez que la 6u06, y dejaron margen a updates de seguridad por si se retrasaba más de lo esperado.

Pueden verse los detalles en:

Aquí mi resumen ejecutivo:

  • No se incluyen actualizaciones resoluciones de vulnerabilidades de seguridad. Por lo tanto la versión 6u7 está igual de actualizado que 6u10 en este aspecto.
  • Resolución de múltiples bugs, la mayoría afectando al uso de escritorio, entorno gráfico e instalación, pero algunos también son temas estrella en las versiones servidor, por ejemplo por fin han eliminado la limitación en el tamaño de heap por defecto a 1,4 GBytes en Windows x64 (se mantiene en Windows x32 por la limitación del espacio de direcciones a 2 gigas), además de corregir un memory leak con el modelo ParalellOlgGC de Garbage Collector (es el modelo paralelo que utilizo yo).
  • Se incorpora por fin la versión 11 de Hostpot, desde 6u4 se mantenía la versión Hotspot 10, con mejoras de rendimiento tanto para cliente como para servidor, además de resolución de bugs como los mencionados arriba
  • Nueva implementación del renderizado Direct3D para Windows, incluyendo (¡por fin!) aceleración hardware, aunque de momento sólo esté implementada para tarjetas ATI u nVidia).
  • Refactorización del JRE. El JRE ahora consta de un núcleo (kernel) mínimo y se instalan distintos bundles en función de las necesidades (ver documentación para más detalles).
  • Reingeniería del Plugin. Menudo revolcón le han dado, ya no es un pluggin "para apllets Java" sino que además integra las nuevas tecnologías JNLP y JavaFX. Importante: La gestión de applets tiene cambios significativos, incluyendo el tratamiento de applets no firmados, ver las release notes...
  • Y ¡por fin!, mejor control de versiones, elección de qué versión usar en caso de tener varias instaladas... y lo más importante de todo: la actualización puede funcionar en modo parche para no tener varios directorios con distintos updates del JDK instalado. Con lo molesto que era hasta hahora consolidar todo esto a mano. Por cierto que manda huevos que no lo hayan hecho hasta ahora.
Yo ya lo tengo instalado en mi PC, y funcionando con Netbeans y SQLDeveloper sin problema. Por cierto que he actualizado el post Tuning de NetBeans 6 (y NetBeans 6.1) para reflejar mi nueva configuración con aceleración gráfica por hardware, je je.

También lo hemos instalado ya en los entornos servidor de Desarrollo y Pruebas Integradas. Sin embargo, de momento no lo voy a instalar en los entornos de Preproducción y Producción hasta dejar pasar un tiempo y poder hacer pruebas de carga. En función de los calendarios que maneje de aquí a unos meses es posible que no tenga tiempo de certificarlo y, además, tengo noticias de primera mano "desde dentro" del equipo de Hotspot acerca del calendario de siguientes actualizaciones y versiones de Hotspot incluidas en ellas... pero eso es otra historia que escribiré en otro post ;-)