Archivos del sitio
Nosotros caminamos junto a hombres gigantes
Hace 335 años Issac Newton utilizo la locución A hombros de gigantes en referencia a los grandes científicos que le habían precedido como Galileo, Kepler, Copérnico, Aristóteles : …si he podido ver más allá es estando parado sobre hombros de gigantes. Y no hay ninguna duda de que el avance de la Ciencia moderna se apoya en los científicos que les precedieron. En nuestro caso la Informática es demasiado joven para tener una verdadera historia y a pesar de eso ya tenemos mucho que agradecer a los gigantes sobre los que nos apoyamos.En nuestro trabajo, si además apostamos por el Software Libre tenemos que ser conscientes de que no solo nos apoyamos sobre hombros de gigantes sino que gracias al Software libre “Nosotros caminamos junto a hombres gigantes“…Sin buscar demasiado, todo nuestro entorno de desarrollo o cualquiera de nuestros proyectos le debe más al software libre de lo que nosotros jamas podamos retornar. A modo de ejemplo, dejo un pequeño listado de algunas de las librerías que aparecen en los proyectos que hacemos en Viavansi, si uno hace cuentas, es fácil sentirse abrumado por la cantidad de código del que hacemos uso, y de lo mucho que tenemos que agradecer.
- iText ( Bruno Lowagie), commons-lang (Daniel Rall, Stephen Colebourne,…), hibernate-annotations (Emmanuel Bernard,…), commons-beanutils (Robert Burrell Donkin, Craig McClanahan,…) , xalan (David Bertoni, John Gentilin, … ), commons-httpclient (Michael Becke, Jeff Dever, …), httpunit (Christian W. Hargraves, Kay Johansen, …), commons-fileupload ( Martin Cooper, John McNally,…), cglib (Juozas Baliuka , …), struts ( Craig R. McClanahan, Ted Husted, … ), dom4j (Curt Arnold, David White, … ), nekohtml( Andy Clark,… ), xml-security:xmlsec ( Derek Morr, Pete Hendry, …), jboss-javassist ( Shigeru Chiba,… ), xerces(Arnaud Le Hors, Tozawa Akihiko, …), hibernate-entitymanager ( Gavin King, …), commons-io (Serge Knystautas, …), net.openid:core (Jason Alexander, …), com.sun.facelets:jsf-facelets (Jacob Hookom, …), myfaces ( Ted Husted, …), bouncycastle (Tito Pena, …), …(1000s…)
Soy consciente de que me he dejado cientos de proyectos y miles de personas fuera de este listado, pero …Mil gracias a todos!
Viafirma.org 1.2.5
Ya tenemos nueva versión de Viafirma (Nuestra plataforma de Firma y Autenticación Digital), la lista completa de cambios es:
- Migración del stack WebSerice utilizado, antes Xfire, ahora JAX-WS 2.1.
- Nuevo método para el envío de emails firmados digitalmente.
- Cache de CRLs para minimizar el número de accesos a CRLs externas.
- Soporte de firma en servidor (indicando el alias y el password) y custodia de documentos firmados offline.
- Actualizada la versión de la librería OpenId para el soporte completo de OpenId 1.1 y OpenId 2.0 (draft)
- Mejorada la documentación de instalación y creada aplicación pre-empaquetada .war .
- Añadido digito de control al identificador de firma.
- Validación y recuperación de documentos custodiados mediante el identificador del documento.
- Uso de friend-url para el acceso a documentos custodiados, ej:http://viafirma.viavansi.com/viafirma/v/Y1MW-9LE3-JE81-2087-8160-3774.
- Mejorado el renderizado del QR-CODE, añadida información hash del documento y mejoradas en el formato de la etiqueta.
- Mejorado el renderizado del justificante pdf, para formatos no A4.
- Parametro para control de acceso al Servicio Web , ALLOWED=”ip,ip2″ indica que ips tienen permiso para acceder al servicio web.
- Soporte de certificados almacenados en “Acceso a Llaves” de Mac OSX (Con esto ya tenemos soporte completo de Mac OS X).
- Solución de bugs en el css para IE6 e IE7.
- Solución de bug en el envio de mimetype al navegador.
- Añadido método al api cliente, que permite retornar una imagen png con el código de barras y QR code del documento custodiado.
- Se ha añadido a la demo de la plataforma la posibilidad de firmar un documento de ejemplo, sin necesidad de subir uno ya existente.
- Mejorado el parseador de Oids, para extraer correctamente los datos del certificado.
Consejos para desarrolladores de OpenCms
Hace unas semanas mientras impartía formación de OpenCms estuve hablando con un técnico de otra empresa y me comentó los problemas que estaban teniendo al manejar un proyecto en OpenCms 6. Al cabo de unos minutos nos dimos cuenta de que los problemas que tenía no se debían a OpenCms (más bien, yo me di cuenta y él dijo:¡Por fin alguien que me entiende!), sino al diseño del portal que le habían entregado.
Llegados a este punto le estuve comentando los siguientes consejos que nosotros seguimos en Viavansi:
1.- No usar microsites cuando no sea apropiado:
Un microsite es un tipo de carpeta (”carpeta extendida”) que viene en el módulo TemplateOne.
Básicamente se utiliza para dar una funcionalidad distinta a una parte del portal. Si vamos a crear un portal desde cero no debe estar contenido en un microsite, sino en una carpeta normal. Si vamos a actualizar a futuras versiones de OpenCms ni siquiera debemos usarlo, es más, en la instalación por defecto de OpenCms 7.0.4 no aparece (se recomienda no instalar el módulo TemplateOne y usar el nuevo TemplateTwo).
2.- Si programas para OpenCms 6 o superior es mejor que olvides la forma de trabajar que tenías en OpenCms 5.
3.- Crea una estructura correcta:
Es muy importante crear un portal sólido, con una estructura lógica. Las plantillas deben estar en una carpeta en nuestro módulo y la parte navegable debe estar en /sites/ o /sites/default/ (dependiendo de como configures el fichero opencms-system.xml). Olvidate de cosas del estilo http://misitio.com/com.misitio/resources?noticia=/sites/actualidad/noticia_0005.html.
Si tu estructura es correcta puedes ver la noticia escribiendo http://misitio.com/actualidad/noticia_0005.html.
(Doy fe de haber visto cosas como esa en más de una ocasión).
4.- No añadas las jsp a las fuentes de las búsquedas:
La búsqueda por defecto muestra una descripción de cada elemento en los resultados. Si añadis las jsp y os ponen como búsqueda “include” las descripciones pueden mostrar cosas como cms.loginWebUser(usuario,contraseña), etc.
5.- Cuidado con las distintas versiones de OpenCms:
Hay que conocer cómo se comporta cada versión de OpenCms (qué bugs o qué cosas se implementaron según qué versión).
OpenCms 6.x hasta OpenCms 6.2.2 valida antes de cerrar los campos de los XSD, esto fue corregido en la 6.2.3.
OpenCms 7.0 hasta OpenCms 7.0.3 no mapea de campos a atributos, OpenCms 7.0.4 sí.
Para conocer estos detalles no hay nada mejor que leerse las notas de cada versión.
6.- Corrige los errores conocidos:
Hay errores del desarrollador que son fácilmente reconocibles en OpenCms, por ejemplo si el menú flotante aparece n veces repetido significa que al modificar el fichero opencms-modules.xml has repetido n veces un id de recurso.
7.- Copias de seguridad: Las copias de seguridad no se deben hacer sólo de la base de datos:
Si no tenemos los archivos de configuración (en especial el opencms-modules.xml) es muy dificil que restauremos el sistema.
8.- No tocar el código fuente de OpenCms:
La mejor forma de poder actualizar a futuras versiones es que el código fuente de OpenCms no se haya modificado. Si hacemos un portal y no hemos respetado este punto lo más seguro es que tarde o temprano nos arrepintamos.
9.- OpenCms tiene una línea de aprendizaje fácil (comparada con otras tecnologías, por supuesto), pero es muy difícil llegar a dominarlo. Hay que echarle muchas horas, hacer muchas pruebas, etc.
10.- Comunidad:
No estais sólos con OpenCms. Existe una comunidad muy grande de desarrolladores que os pueden echar una mano. Los principales recursos de OpenCms son:
* Página de OpenCms.
* Lista de correos oficial (en inglés).
* Foro de OpenCms (en inglés).
* OpenCms Hispano (en español).
* Grupo en facebook.(en inglés). Buscar por OpenCms, claro.
* OpenCms wiki (en inglés).
Carta al señor Armonia
Pocos de nuestros lectores sabrán que dentro de VIAVANSI tenemos a un blogger ex-semi-profesional… Juan G. Hurtado, aka Armonia.
Juan tenía Armonia, un blog muy técnico muy dedicado a la Web y sobre todo a la capa de cliente (estándares), con una cantidad terrible de visitas. Le hizo bastante conocido en la blogosfera 2.0 hispana, le hacían entrevistas, salía en revistas internacionales… Su blog fue su CV y su reclamo para entrar en VIAVANSI. Ahora es el señor Semántico, nuestro crack de capa de cliente y uno de los secretos de que a nuestros clientes les guste la interfaz de nuestras aplicaciones. Sin embargo, por desgracia, un buen día se hartó y dejó de escribir.
Por eso, como opinan otros muchos internautas, señor armonía: ¡vuelva a escribir! *
*Y si escribes en xnoccio, pues mejor :-)
Java: Implementación de una caché con Referencias Débiles
Últimamente me ha surgido una necesidad que hasta ahora no se me había presentado.
Os comento de qué se trata:
Estaba desarrollando una aplicación web (jsf, seam, etc.), en unos de las páginas se generaba un listado en el que se muestra datos sobre una serie de documentos.
Existe la posibilidad de descargar estos documentos, que no son más que archivos pdfs, a través de una aplicación cliente que a su vez se despliega con Java Web Start con JNLP en la misma aplicación web.
El problema es el siguiente:
El usuario X a través de la aplicación ve el listado, pero el JNLP no comparte la misma sesión que el navegador, luego no podemos acceder a dicho listado, ya que se trata de un objeto visible en el conexto Sesión.
Una primera solución consistiría en pasar los distintos identificadores de los documentos listados al JNLP a través de parámetros en la URL. Pero existe el problema de que el listado sea demasiado largo y la URL resultante sea demasiado larga, problema con caracteres no aptos para una URL, etc. Podemos jugárnosla, optar por esta “solución” y rezar para que nunca se produzca esa situación… no mola, sigamos pensando y busquemos otra solución.
Posteriormente podemos pensar en identificar el listado y mantener los elementos relacionados en una caché. Caché que no se alojará a nivel de Sesión, sino en el conexto de la Aplicación (ServletContext), para que esté visible desde todas las sesiones (usuario web y usuario jnlp).
Pero, ¿cómo implementamos esta caché?
Usemos un simple HashMap:
El primer usuario entra, hace un listado, se introduce en la caché el listado.
El mismo usuario genera otro listado, se introduce en la caché.
Entra otro usuario, lo mismo, un nuevo elemento a la caché.
Trás introducir cinco mil elementos en la caché vemos que la aplicación ya no puede más y dice ‘¡¡ hasta aquí hemos llegado !!’.
¿Qué ha pasado? Pues que la caché ha almacenado muchísimos listados y se ha ‘comido’ muchísima memoria.
¿Cómo podríamos solucionarlo? Establezcamos un tamaño máximo de cacheo, lo que nos llevará a proponer una determinada política de reemplazo (aleatoria, LRU, LFU, FIfo). Demasiadas cosas para pensar, y teniendo en cuenta las leyes de Murphy ‘Si algo puede fallar, fallará’, así que mejor sigo investigando otra forma de implementar la caché.
Y ¿se podría implementar la caché de tal forma que el recolector de basura de Java vaya borrando sus elementos cuando se esté consumiento demasiada memoria? Esto nos lleva al concepto de “Referencia débil”.
Recordemos los tipos de referencias en Java: Fuertes, débiles, blandas y fantasma. En la práctica las débiles y las blandas son tratadas igual por la Máquina Virtual Java (no sigo explicando esto porque no es el objetivo de este post).
Cuando el recolector de basura se ejecuta y va recorriendo los distintos objetos, si estos objetos son apuntados por referencias débiles se eliminan, tal y como suena, esto no ocurre con las referencias fuertes.
¿Cómo podemos aprovechar esto en nuestra caché? Pues a través de la clase WeakHashMap (véase java.util.WeakHashMap). Esta clase implementa java.util.Map, pero las keys se almacenan como objetos con referencias débiles. Con esto se dejará la responsabilidad de vaciar la caché al recolector de basura.
Pues nada más, con esto hemos conseguido implementar una caché visible desde las distintas sesiones en una aplicación y gestionada por el Recolector de Basura.
A continuación os pongo un pequeño código de ejemplo para que podais ver la diferencia de funcionamiento entre un HashMap y un WeakHashMap.
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class Prueba {
public static void main(String[] args) {
Map map = new HashMap();
Map weakMap = new WeakHashMap();
imprime("map", map);
imprime("weakMap", weakMap);
for (int i = 0; i < 50; i++) {
System.out.println("=======================n=======================");
System.out.println("Insertando: " + i);
System.out.println("Insertando: " + i + "_key");
map.put("" + i, "" + i);
map.put("" + i + "_key", "" + i);
weakMap.put("" + i, "" + i);
weakMap.put("" + i + "_key", "" + i);
imprime("map", map);
imprime("weakMap", weakMap);
if (map.keySet().size() != weakMap.keySet().size()) {
System.out.println("DISTINTO TAMAÑO !!!");
}
System.out.println("Eliminando: " + i);
map.remove("" + i);
weakMap.remove("" + i);
imprime("map", map);
imprime("weakMap", weakMap);
}
}
private static void imprime(String texto, Map map) {
System.out.println("n-----------" + texto + "-----------");
System.out.println("Size: " + map.keySet().size());
System.out.println("Map:" + map);
System.out.println("------------------------------n");
}
}
Por cierto, quien quiera seguir investigando las referencias débiles puede probar con la clase java.lang.ref.WeakReference.
Saludos.
Spring vs Seam (La guerra ha empezado)
Como primer contrincante tenemos Spring, un framework muy extendido, al que le empezaban a pesar las arrugas, y que tras su última actualización ha vuelto a rejuvenecer.
Como segundo contrincante tenemos Seam, un framework joven, y con una nueva filosofía.
He de reconocer que cada vez me gusta mas Spring, cada vez se parece más a Jboss Seam :p. Os dejo algunos ejemplos en los que el nuevo Spring ha seguido el camino marcado por Seam, abandonando los “desagradables” xmls de mapeo declarativo, para ofrecer la misma funcionalidad con anotaciones.
Gestión de transacciones con Spring:
@Transactional(readOnly = false)
void postComment(long articleId, Comment comment);
Gestión de transacciones con Seam:
@Transactional
void postComment(long articleId, Comment comment);
Publicación de Manager JSF Beans con Spring 2.5:
@Controller(”PersonaController”)
@Scope(”session”)
public class PersonaController{
..
}
Publicación de Manager JSF Beans con Seam:
@Name("personaController")
@Scope(SESSION)
public class PersonaController{
..
}
La verdad es que revisando una a una las nuevas anotaciones y funcionalidades que proporciona Spring, solo me queda alegrarme por el parecido. Estoy seguro que con esta competencia ganamos todos, por ahora estoy del lado de Seam ya que su enfoque resulta menos forzado y mucho mas alineado con los futuros Web Beans, pero quien sabe lo que nos depara el futuro.
Los que quieran profundizar en las diferencias, pueden ver Framework Deachmatch: Spring vs Seam[pps].
También se han publicado una serie de artículos muy interesantes sobre como integrar Spring con Seam.
Leaving Firefox: me voy a la Opera
Los usuarios somos así: nos sorprendemos rápido, nos enamoramos, pero no puedes fallarnos: tenemos tendencia a ser infieles.
Querido navegador del zorrito: nos conocimos hace muchos años. Ni siquiera eras un zorrito. Te conocí como Phoenix, y te tomé como referencia como Firebird. Empecé contigo con versiones 0.x, y me entusiasmé cuando lanzaste tu 1.0 desde la Preview Release. Tenías unas pestañas que nadie más tenía, y podía añadirte plugins que me hacían la vida más fácil. Las Developer Tools cambiaron mi vida de desarrollador, bloqueabas los pop-ups, recordabas mis contraseñas cuando querías… ¡respetabas los estándares, no como ese capullo de IE! Eras software libre. Molabas mucho. Te recomendé a todo el mundo, sentía que jugaba con los buenos en la lucha contra el poder.
Fuiste evolucionando, llegaste a la versión 1.6, ahí me desencanté un poco, pero no era culpa tuya. Las relaciones largas a veces causan hastío. Yo no te cambiaba por nada… Salió tu versión 2.0. Ahí empezó el desastre. Te cuelgas, te apagas, te cierras solo. Vas lento, más que el resto. Coges mucha memoria. Me obligas a adaptarte, a usar about:config. Los amigos del Mac se fueron un día de safari y nunca volvieron. Una y otra vez me ofrecías restaurar la sesión. A los usuarios nos gusta llevar el control, no que nos guíen. Le echaba la culpa al sistema operativo, a la red… no quería verlo. Pero hablando con otros usuarios, a todos nos pasaba lo mismo… ¿de verdad es cosa tuya? ¿Tanta confianza tenemos?
Hoy me he hartado y me he instalado Opera. Ha sido un flechazo a primera vista. Tiene un sistema de marcado rápido muy amigable, es rápido, se lleva mucho mejor que tú con Java y Flash, tiene el recargar cada N segundos, contigo necesitaba el plugin ReloadEvery… No te perderé de vista, te actualizaré, con la esperanza de que vuelvas. No te desinstalaré, todavía te respeto. Pero…
Los usuarios somos así: nos sorprendemos rápido, nos enamoramos, pero no puedes fallarnos: tenemos tendencia a ser infieles.
Tips: Problemas con el tiempo de “Leasing” en sistemas de cálculo distribuidos
Desde hace unos meses llevo trabajando en un proyecto que requiere una enorme capacidad de calculo para su correcto funcionamiento, por lo que he tenido que recurrir a un sistema de calculo en cluster basado en JavaSpace/Jini y ComputeFarm. Al principio el sistema funcionaba correctamente, pero a medida que he ido añadiendo cpus (1 mac, 1 portátil Linux, 1 portátil Windows Vista, 2 pcs con XP, 4 pcs antiguos con Linux y una PlayStation3) ha empezado a bloquearse y a dejar el cluster inutilizado. El problema surge al ser un cluster muy heterogéneo, lo que causa que mientras en algunas cpus el tiempo de calculo requerido por tarea sea solo de algunos segundos, en otras máquinas el tiempo de calculo requerido es muy elevado. En estas condiciones surge de forma “aleatoria” la siguiente excepción:
net.jini.core.transaction.UnknownTransactionException: unknown transaction at com.sun.jini.mahalo.TxnManagerImpl.join(TxnManagerImpl.java:759)... at com.sun.jini.mahalo.TxnManagerImpl_Stub.join(Unknown Source)... at com.sun.jini.mahalo.TxnMgrProxy.join(TxnMgrProxy.java:131)... at com.sun.jini.outrigger.SpaceProxy.write(SpaceProxy.java:298)
¿Y por que no reconoce la transacción Jini?
Cuando se produce una situación en la que le “toca” realizar una tarea muy costosa a una cpu lenta, se activa el timeout de la transacción y por lo tanto ya no hay una transacción a la que commitear el resultado del cálculo, y esto hace que las tareas no puedan ser liberadas, causando la caída del cluster. Una vez entendido el problema, la solución es muy sencilla:
- Si la implementación del worker es ComputeFarm 0.8, es suficiente con modificar la variable de sistema mediante: -Dorg.tiling.computefarm.impl.javaspaces.MaxTaskExecutionTime=1500000 ( para por ejemplo permitir tiempos de espera de 25 minutos)
- Si la implementación del worker es ComputeFarm 0.7, como es mi caso debido a dependencias con otras librerías, hay que recompilar el proyecto para configurar manualmente este parámetro, modificando el código fuente de org.tiling.computefarm.WorkerThread.
Una vez solucionado este punto, y aunque mi experiencia en este tipo de soluciones es muy reducida, tengo que admitir que el pack “JavaSpace/Jini/ComputeFarm” es una maravilla para la creación sencilla de sistemas de cálculo distribuidos.
Busca esto rápido
Encuentra lo que buscas de forma sencilla usando el buscador.
Categorías
Encuentra artículos a través de sus "tags"
Archivos mensuales
Encuentra artículos según el mes en el que fueron escritos.
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007