[ Blog ]
[ Wiki ]
[ Slideshare ]
[ Twitter ]

Bloggers recientes

Cesar Capillas Mensajes: 110
Estrellas: 7
Fecha: 18/05/13
Gustavo Fernandez Mensajes: 44
Estrellas: 7
Fecha: 10/05/13
Patricia Yagüe Mensajes: 2
Estrellas: 0
Fecha: 2/04/12

Archivo

Tags

noBlogo - El blog de zylk.net

Entradas con etiqueta <em>java</em>.

Carga avanzada de properties desde java con control de cache y de encoding

En el último mes en varios proyectos hemos tenido que solventar varios problemas relacionados con la carga de properties de idioma o configuracion desde java, las distintas problemáticas era

  1. Cargar un ResourceBundle desde un path de filesystem y no desde el classloader
  2. Cargar properties codificados en UTF8 sin que estos hayan sido pasados por el native2ascii
  3. Gestionar el ciclo de vida de los properties para que estén cacheados pero que se recarguen cada x-tiempo

Buscando alternativas para resolver estos problemas encontré un artículo relacionado con el tema, que ahora no encuentro, en el que se explicaba que en la jdk 1.6 se puede crear un controlador "custom" para la carga de los ResourceBundels, para ello basta con extender la siguiente clase java

ResourceBundle.Control

desde la que precisamente se pueden controlar los tres temas comentados.

A continuación se muestra una implementación de ejemplo que carga los ficheros de filesystem y gestiona el tiempo que cada properties permanece en la cache. También en este link se puede ver el código de carga para el tema del UTF8
 


Espero que este breve ejemplo os sirva, basta con cambiar las carga habitual del properties de

ResourceBundle.getBundle(name, new Locale("es", "ES"));

a

ResourceBundle.getBundle(name, new Locale("es", "ES"), new ZylkControl());


La ejecución de este ejemplo demuestra que

  1. Los ficheros se cargan directamente de filesystem
  2. Solo se accede a la lectura del fichero si el time-to-live así lo indica

Dejo también el código fuente de la clase de ejemplo linkada en el post

ubuntu 10.04 LTS y algunos problemas con los applets

Lunes por la mañana y no se que ha pasado pero en el firefox de mi ubuntu, y en el de todos los de la empresa (usamos la 10.04 LTS), los applets han dejado de funciona. No he encontrado mucha información al respecto por internet pero he lincado a mano la librería y parece que todo vuelve a funcionar correctamente. Lo dejo aqui escrito por si puede servir a alguien más.

ln -s /usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so   $HOME/.mozilla/plugins/libnpjp2.so

Algo tiene que ver con el plugin de java (sun-java6-plugin) porque usando el icedTea los applets funciona, el problema es que el icedTea usa una implementación de java que no es la de sun y en algunos temas de firma no funciona todo lo bien que me gustaría...

Seguiré investigando un poco más sobre el tema durante la semana, pero justo hoy necesitaba que los applets funcionaran para poder seguir con un proyecto, así que temporalmente me voy a quedar con la solución del link manual...

Usando hadoop para intercambio masivo de ficheros en un contexto de big data

Durante los últimos tres meses en zylk hemos estado desarrollando, conjuntamente con personal de EJIE (Oscar Guadilla en la definición de la arquitectura y gestión del proyecto, Carlos Gonzalez de Zarate y Roberto Tajada en la parte de platea integración y Juan Uralde en la parte de xlnets) , una aplicación horizontal para el intercambio temporal de ficheros. La problemática que se quería resolver era la siguiente:

  1. Disponer de un sistema para que las distintas aplicaciones, situadas en los distintos entornos (extra, intra, inter etc..), pudieran intercambiar ficheros.
  2. Disponer de un sistema de trazas/auditoria, consultable en tiempo real capaz de almacenar la información de millones de transacciones.
  3. Disponer de un sistema de eventos que permitiera la comunicación asíncrona entre las distintas aplicaciones (en lo que a intercambio de ficheros hace referencia)
  4. Disponer de una librería de cliente, para navegadores, que mejorara la experiencia de usuario a la hora de gestionar ficheros en aplicaciones web.
  5. Disponer de un API java que sirviera tanto para jdk 1.4, como para jdk 1.5+
  6. Disponer de un API batch.
  7. Disponer de un API WebService

El proyecto se dividió en dos partes.

  • Una primera en la que se hicieron las pruebas pertinentes para seleccionar las tecnologías y los patrones necesarios para el desarrollo. (Tres semanas de trabajo)
  • Una segunda en la que se realizó la implementación de la solución y se depuraron todos los aspectos que no se habían tenido en cuenta en la fase de análisis/pruebas (Nueve semanas de trabajo)

A continuación se muestra un gráfico de los distintos componentes que conforman las solución.

Y los distintos métodos que se pensaba crear y exponer en cada canal. Como eje principal de la solución se optó por usar hdfs (hadoop distributed file system1).
La idea original era crear una API java recubriendo el API original de hadoop para exponer los siguientes métodos:

  • move
  • info
  • copy
  • list
  • put
  • get

La primera pega que nos encontramos fue que el API de HADOOP solo se puede ejecutar con java 1.5+ lo que nos obligó a crear un nuevo canal de comunicación para exponer el API java 1.4. Para ello expusimos los métodos por medio de un API REST y creamos un cliente compatible con java 1.4 para dichos métodos.  Tanto el API para java 1.4 como el de 1.5 se instancian usando una factoría abstracta que permite cambiar del API 1.4 al API 1.5 con tan solo cambiar las implementaciones ya que creemos que en un futuro próximo todas las aplicaciones correrán con java 1.5+
A continuación mostramos un diagrama de como se han creado las implementaciones y las interfaces relacionadas con el proyecto.

 

Una vez tuvimos el core creado y consensuado nos centramos en el resto de las partes, a saber

  • Sistema de trazas.
  • Eventos (platea integración).
  • API WS.
  • Widget para upload.


A continuación presentamos un gráfico que resume todos los canales de comunicación entre los distintos APIs y componentes.

 

Donde se pude ver que al core se le han añadido las funcionalidades de trazas, metadatos y seguridad basada en xlnets.

Para el sistema de trazas se han utilizado colas JMS con un MDB que publica los mensajes en una base de datos noSQL como mongo-db. Se optó por esta solución porque después de hacer pruebas de rendimiento se conseguían un rendimiento entre 5-10 veces superior que en tablas relacionales. Hay que decir de todas formas que en este caso el concepto de noSQL encajaba a la perfección con el problema que se quería solventar al igual que los conceptos de listas finitas, orden natural inverso etc..

Para la parte de metadatos se ha optado por almacenar los mismos serializados en json en el propio hadoop, por un tema de auto-consistencia del filesystem. Aunque creemos que a esta parte habría que darle todavía una vuelta más e ir a un modelo de tablón basado en HBASE, por ejemplo. Si se hiciera esto se estudiaría también la posibilidad de cambiar el sistema de trazas a HBASE también.

Para el componente de upload se ha usado SWFUPLOAD, ya que se intentó usar los blobs de javascript que permiten no usar flash, pero internet-explorer en su versión 8 no los implementa todavía. Hay que destacar que para poder usar SWFUPLOAD en un entorno seguro que use las cookies para mantener la sesión hay que sortear unos pequeños problemas de flash con las cookies … pero eso es otra historia.

Para la parte de seguridad, simplemente se han usado las librerías de xlnets.

Para la parte de eventos se uso platea integración.

Otra de las partes que se usó, fue el map-and-reduce para el expurgo de ficheros, para lo que hadoop evidentemente nos sirvió.


Creo que esto es más o menos todo, la verdad es que la solución final es bastante potente y creemos que puede evolucionar satisfactoriamente y cubrir las necesidades para las que se ha diseñado.

normalizando nombres en java

Un problema típico en los programas que gestionan uploads/downloads de ficheros es el nombre del fichero que los usuarios dan a los ficheros. Es decir, existe la no muy buena costumbre, entre los usuarios de windows y mac principalmente, de usar nombres de ficheros con tíldes espacios en blanco etc... que suele originar problemas a la hora de almacenarlos en los filesystems ya que la codificación en bytes de algunos caracteres en los distintos encodings no es la misma. Es decir no se codifica de la misma manera en UTF-8 que en ISO-8859-1. Por tanto suele ser una buena práctica normalizar esos nombres sustituyendo las tildes por sus equivalente sin tilde y las ñ por n. Además también es una buena idea evitar los espacios en blanco para que las urls no tengan la pinta de %20% etc... En java para realizar esa tarea se puede hacer uso de una expresión regular y de un Normalizador de texto. El código es el siguiente:

  private static String normalizador(String str)
  {
    return Normalizer.normalize(str, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "").replaceAll(" ", "+");
   }


Que dado un string como "camión con Ñ" devuelve camion+con+n. Este método es preferible al tipico replaceAll("é","e").replaceAll("á","a") etc.. ya que además de servir para otros idiomas evita la problematica de que en el código fuente é está codificada en un encódigo concreto que puede hace que el replaceAll no haga nada.

Dejo el link de un artículo interesante relacionado con el tema, http://www.rgagnon.com/javadetails/java-0456.html

Monitorizando Liferay Portal con Nagios

Un aspecto fundamental en el mantenimiento y prevención de desastres en un sistema es la monitorización de los diferentes servicios que proporciona. Un herramienta muy popular es este campo dentro del mundo opensource es Nagios debido a la gran comunidad de usuarios y plugins existentes. Uno de ellos es check_jmx, que permite la monitorización de variables de un servidor de aplicaciones java, activando la consola jmx.

En primer lugar es necesario configurar el acceso via jmx en el servidor de aplicaciones a monitorizar, y reiniciarlo. Basicamente hay que localizar el punto del script de arranque de Jboss o Tomcat donde especificamos las opciones de java $JAVA_OPTS de modo:

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote=true"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.port=9999"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.authenticate=true"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.password.file=/opt/liferay/jmxremote.password"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.access.file=/opt/liferay/jmxremote.access"

También es necesario editar los archivos jmxremote.access:

admin readwrite
zylk readonly

y jmxremote.password:

admin secret1
zylk secret2

Podemos probar que el jmx está listo con jconsole, una vez reiniciado el servidor de aplicaciones:


Luego nos descargamos el plugin para Nagios, y configuramos los comandos y servicios correspondientes. Por cierto, es un script de shell que invoca a un jar, luego para ejecutarlo en el servidor de monitorización es necesario instalar java.

La configuración del comando (commands.cfg) en Nagios:

define command {
  command_name check_alfresco_HeapMemoryUsage_Used
  command_line    /usr/local/nagios/plugins/check_jmx -U service:jmx:rmi:///jndi/rmi://’$HOSTADDRESS$’:'$ARG1$’/jmxrmi -O java.lang:type=Memory -A HeapMemoryUsage -K used -username ‘$ARG2$’ -password ‘$ARG3$’ -w ‘$ARG4$’ -c ‘$ARG5$’
}

y la del servicio (services.cfg):

define service {
  host_name               baco
  service_description  heap memory used
  check_command     check_jmx_HeapMemoryUsage_Used!9999!zylk!secret1!750000000!800000000
  use                           generic-service
}

En el caso específico que nos ocupa, monitorizamos la memoria heap de un contenedor de servlets Tomcat con un gestor de portales Liferay, aunque podría ser cualquier aplicación java, como Alfresco ECM o Nuxeo. En el blog de Toni de la Fuente, hay un detallado artículo de monitorización de Alfresco a través de varios métodos, entre los que incluye Nagios.

Como complemento a este artículo en la parte que se refiere a Nagios, es posible graficar la evolución temporal de las variables java en PNP4Nagios mediante performance data. Para ello necesitamos modificar un poco el script el check_jmx, añadiéndole los datos de rendimiento, de modo que tendremos en Nagios gráficas diarias, semanales, mensuales tipo Cacti (rrdtool) en nuestro Nagios.

El cambio en la parte final del script es el siguiente:

DIR=`dirname $0`
JMX=`$JAVA_CMD -jar $DIR/check_jmx.jar "$@"`
JMXVAL=$?
VAL=`echo $JMX | awk '{print $5}'`
echo $JMX "|$6=$VAL;;;"
exit $JMXVAL

Y este sería el resultado para la memoria heap de java del servidor Liferay:

Y esto es todo.

Mostrando 5 resultados.