domingo, 18 de diciembre de 2011

2011: 50 años en el espacio, 30 "peceando"


640K ought to be enough for anybody.
- Bill Gates, 1981 (*)

Una cosa es segura: en tecnología no se deberían realizar aseveraciones del tipo "nunca jamás" porque más tarde o más temprano, el tozudo paso del tiempo te acabará poniendo en el ridículo más espantoso.

Hace 30 años, se lanzó el IBM PC, predecesor de los actuales ordenadores personales que hay en la mayoría de las casas y oficinas. Curioso nombre el que le pusieron, ya que difícilmente se podría llamar "personal" a algo científico que podía costar hasta casi $20.000, aunque mira tú, ironías del destino, sus equipos sucesores si han acabado siendo "personales".

Con respecto a los temas de tecnología que vertebran este blog, de este año destacaría otro suceso trascendental aparte de la curiosa efeméride anterior: un fallecimiento. Este año nos dejó una de las personas que más relevancia tiene en prácticamente toda la tecnología que uso diariamente en mi profesión y de la que deriva la esencia de casi todo lo que usamos: Dennis MacAlistair Ritchie, más conocido como Dennis Ritchie, o simplemente dmr (muchas veces escrito así, "dmr", en minúsculas, con un tremendo respeto, y con la solemnidad con la que uno escribe la más valiosa contraseña). El azar ha querido que el año de su muerte sea también el 40 aniversario de la publicación del primer manual de UNIX "UNIX Programmer’s Manual" que él escribió conjuntamente con Ken Thomson.

Poco puedo añadir yo a lo muchísimo publicado sobre quién fue dmr. La mayor parte de los que visitáis el blog con asiduidad, conocéis su enorme y extensísima contribución al mundo. Tan enorme, como igual de decepcionante la poca repercusión que la noticia ha tenido en la prensa no especializada, que sin embargo ha dado extensa cobertura a otro lamentable fallecimiento contemporáneo, de un personaje más público y notorio, más cool, aunque su legado no pueda ser comparable en absoluto ni por transcendencia ni por importancia. El tiempo pondrá a cada uno en su sitio.

La significación en el mundo de la tecnología de dmr es comparable a la de Marie Curie a la física nuclear o la de Ramón y Cajal a la neurología... y aún así, hay una diferencia extrema: mientras éstos "descubrieron", dmr creó. dmr puso las dos semillas de los llamados entonces Sistemas Abiertos con la creación de UNIX y C. De la misma forma que no podríamos hablar del ADN sin la adenina, guanina, y citosina, tampoco podríamos hablar de Windows, Linux, Mac OS X, Java, Ruby, PHP, o .NET sin C, ya que C ha sido y sigue siendo la base de la creación tecnológica a partir de la cual se han construido tecnologías más complejas.

Por otro lado, Internet (correo electrónico, facebook, Google, twitter, etc), Android, Mac OS X, iPhone y su iOS, Linux... todos tienen en común su procedencia y su esencia, su corazón: el UNIX que creó dmr. Actualmente, desde los Sistemas Operativos de los más grandes e importantes Data Centers y de los equipos financieros del mundo, hasta los smartphones más pequeños siguen usando algún tipo de UNIX o una derivación de éste. Sobre UNIX y C está construido el mundo tecnológico que conocemos. Este es el enorme legado de dmr.

Transborador y Estación Espacial Internacional juntas
Fuente: NASA
En otro orden de cosas, de interés también de este blog, damos repaso al año en lo que a temas de astronomía se refiere: 30 años después del primer vuelo orbital de un transbordador espacial (el Columbia), este año se ha puesto fin al programa de transbordadores espaciales, es decir, al programa STS. La sobrecogedora foto a la izquierda, es muy especial. Por lo general se toman fotografías de la Estación Espacial Internacional (ISS) desde el transbordador, o viceversa, pero no es frecuente que una tercera nave esté acercándose mientras las dos anteriores están unidas. Esta imponente imagen, tomada desde una nave Soyuz TMA-20, donde se aprecia el enorme tamaño de la Estación Espacial Internacional, es una preciosa foto que no se podrá volver a tomar nunca más.

Coincide este hecho con la celebración del 50 aniversario del primer vuelo espacial, realizado por Yuri Alexéievich Gagarin, ciudadano soviético, a bordo de la nave Vostok 1. En honor a su viaje y su transcendencia, la ONU decidió declarar el 12 de Abril como "Dia del Espacio". Esa misma noche se celebra la "noche de Yuri". Curiosamente, el día del primer vuelo de un transbordador orbital (Columbia) fue también el 12 de Abril.

Carl Sagan
También el 20 de diciembre de este año se cumplen 15 años sin el divulgador científico más grande de todos los tiempos. El "astrónomo del pueblo" que ilusionó a todas las mentes inquietas a través de una narración elocuente, precisa, seductora y poética en "Cosmos: un viaje personal": Carl Sagan.

Termino con un comienzo esperanzador, una emocionante nueva misión con el robot de exploración espacial más sofisticado lanzado hasta ahora: el Curiosity. Os dejo con una animación de su viaje, su espectacular aterrizaje y operaciones de superficie (ponedlo a pantalla completa en HD porque merece la pena).

¡ Feliz nuevo año 2012 !




(*) La frase ha sido atribuida frecuentemente a Bill Gates, aunque él ha negado decir tal cosa y existe discusión al respecto ya que no parecen existir evidencias firmes.


Referencias y más información:

miércoles, 14 de diciembre de 2011

Copiar y pegar en applets Java

Una de las páginas a las que suelo acceder a menudo es ésta. Se trata de una sencilla página contenedora de un applet para probar expresiones regulares en Java realizada por David Matuszek.

Esta página contiene una de ésas maravillosas utilidades tipo que acaban siendo atemporales (yo diría que hace más de 7 años que lo uso): sencilla, directa, concisa y eficaz. La verdad es que para probar una expresión regular antes de incorporarla en el código no se necesita más de eso... ni menos tampoco, ya que esto permite ahorrar mucho tiempo de depuración. Una pequeña joya muy recomendable.


De un tiempo a esta parte, me di cuenta que ya no podía copiar las expresiones realizadas ni pegar texto de ejemplo. Esto me resultaba tremendamente molesto, pero siempre que usaba la página tenía tanta prisa por resolver el problema que me llevaba a ella que no me permitía detenerme un momento para averiguar la razón del incómodo cambio.

Bueno, pues resulta que desde el lanzamiento de Java Plug-in 1.6.0_24 en Febrero 2011, copiar y pegar desde o hacia el portapapeles del sistema se consideró un agujero de seguridad y, por tanto, se desactivó. Puedes copiar entre applets, pero no entre applet y portapapeles del sistema.

La solución estaría en modificar el fichero java.policy del directorio lib/security del plugin, aunque lo más probable es que este cambio sea sobreescrito de nuevo en la siguiente actualización de la JRE. Así que lo mejor es crear un archivo de usuario java.policy personalizado:
  1. Localiza tu fichero Java Security Policy. Se llama java.policy y debería estar bajo el directoro lib/security de tu instalación Java JRE. En Linux está en /usr/lib/jvm/java-6-sun-1.6.0.26/jre/lib/security/java.policy.
  2. Copialo a tu home y renómbralo a .java.policy (fíjate que debe comenzar con un punto).
  3. Edita el fichero y añade la línea que se indica debajo de los comentarios:
  4. // "standard" properties that can be read by anyone
    permission java.awt.AWTPermission "accessClipboard";
    
  5. Reinicia el navegador

Referencias y más información:

sábado, 12 de noviembre de 2011

Los niveles de aislamiento en PostgreSQL (no son 4)



"No. No lo intentes. Hazlo, o no lo hagas, pero no lo intentes."

Cuando ví el Episodio IV de la Guerra de las Galaxias ("El Imperio Contraataca"), aún era un niño impresionable, y me llamó la atención la reprenda que hizo Yoda a Luke y que cito aquí. Era uno de ésos consejos marciales que se enuncian solemnes como un consejo vital.

Con el tiempo te das cuenta que como consejo está bien, y puede ser incluso un buen objetivo... pero en ciertas facetas de la vida no es válido. Por ejemplo, en el mundo científico y en nuestro mundo profesional el consejo es justamente el contrario: inténtalo, pruébalo y compruébalo. Y sólo cuando lo hayas hecho y consigas un resultado repetible, ponlo en práctica, esto es, súbelo a producción.

Gracias a no seguir el consejo de Yoda fui consciente de una (grave) carencia de PostgreSQL con respecto a los niveles de aislamiento. Como ya hice una introducción al aislamiento en otro artículo, no voy a extenderme más en el tema y voy al grano. El caso que me ocupaba es que tenía que hacer una importación transaccional de datos masiva en un sistema en OLTP de producción en el que se están modificando constantemente datos relacionados con los que voy a importar. El resultado de la importación es que la transacción gigante bloquea datos e impide que se efectúen modificaciones en datos relacionados paralizando en la práctica buena parte de las operaciones de producción produciéndose un efecto "bola de nieve" al sumarse cada vez más transacciones en cola a la transacción gigante pendiente. Sin embargo, para lo único que quiero la transacción es para tener atomicidad en la operación, es decir, para que no se quede a medias en caso de algún problema, pero no me importa que se puedan producir eventualmente casos de dirty read, que no afectarían a los usuarios del sistema de producción en su trabajo. Vale, no hay problema. La transacción de inserción la podemos realizar con el nivel de aislamiento más bajo (READ_UNCOMMITED) y problema solucionado. ¿No? No obstante, no hagamos caso a Yoda, y probémoslo en pre-producción. Resultado: exactamente el mismo que si no hubiera especificado nada del nivel de aislamiento.

¿Qué ha pasado?

En la documentación de SET TRANSACTION, en efecto compruebo que PostgreSQL admite los cuatro niveles de aislamiento como la mayoría de las bases de datos (de hecho, la sentencia no dio error)... pero sólo sintácticamente: no están todos implementados. Si contiúas leyendo te das cuenta que no son 4, sino 2 los niveles implementados:
"The SQL standard defines two additional levels, READ UNCOMMITTED and REPEATABLE READ. In PostgreSQL READ UNCOMMITTED is treated as READ COMMITTED, while REPEATABLE READ is treated as SERIALIZABLE."
Lo que viene a decir: "¿Pensabas que eran cuatro, no? Pues no. Son dos". De hecho, ahora (con la versión 9.1) ya son 3. Pero sigue sin estar soportada la lectura sucia (dirty read). En la documentación sobre aislamiento también es bastante claro:
"In PostgreSQL, you can request any of the four standard transaction isolation levels. But internally, there are only two distinct isolation levels, which correspond to the levels Read Committed and Serializable. When you select the level Read Uncommitted you really get Read Committed, and when you select Repeatable Read you really get Serializable, so the actual isolation level might be stricter than what you select."

Un verdadero jarro de agua a mis pretensiones, ya que no puedo conseguir atomicidad sin bloqueo (aunque sea realizando lecturas de transacciones no confirmadas) en PostgreSQL, al menos con la versión actual 9.1.


Referencias y más información:

    jueves, 27 de octubre de 2011

    Generar certificados autofirmados con OpenSSL


    Software is like sex: It’s better when it’s free.
    Linus Torvalds.


    Tengo la suerte de trabajar en un lugar rodeado de extraordinarios profesionales como compañeros. El artículo que traigo aquí hoy es un resumen de un correo electrónico de uno de ellos que, con su permiso (y sugerencia) he convertido humildemente en otro post más para este blog. Gracias, Josete. Es un placer y un honor trabajar contigo.



    Mini How-To: Generar certificados autofirmados con OpenSSL para Apache HTTP Server

    -por José Morales Mora.

    PASO 1. Generar Clave RSA

    Ejecutar:

    openssl genrsa -des3 -out server.key 1024

    Genera una clave CA para realizar la firma del certificado. Nos pide la clave privada para este certificado. Podemos especificar el tamaño de la clave ( 1024, 2048)

    PASO 2. Generar CSR ( Petición de Firma de Certificado)

    Ejecutar:

    openssl req -new -key server.key -out server.csr

    Realiza una petición para la firma con clave privada especificado. Al realizarlo nos pide datos:

    Country Name (2 letter code) []:
    State or Province Name (full name) []:
    Locality Name (eg, city) []:
    Organization Name (eg, company) []:
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server's hostname) []: 
    Email Address []:
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
     
    
    IMPORTANTE: El "Common Name" debe corresponder con la URL que queremos Securizar. Si la URL a poner por SSL es www.paco.es, este campo debe contener exactamente eso.


    PASO 3. Eliminar Clave Privada DES3

    Ejecutar:

    cp server.key server.key.org
    openssl rsa -in server.key.org -out server.key
    

    Esto es necesario porque en estos casos que tenemos un certificado firmado con clave primaria, Apache HTTP Server pide en cada arranque esa clave para utilizar el certificado. La solución es eliminar la encriptación DES3 para la clave.


    PASO 4 . Generar Certificado Autofirmado.

    Ejecutar:

    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

    Con este paso obtenemos el CRT autofirmado preparado para ser utilizado en apache.

    PASO 5. Configurar Apache

    Para utilizar estos certificados en apache, lo que tenemos que hacer es añadir al Virtual Host que queramos:

    SSLEngine on
    SSLCertificateFile /usr/local/apache/conf/ssl.crt/server.crt
    SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/server.key
    



    Referencias y más información:

    domingo, 9 de octubre de 2011

    Combinando XPath con JAXB


    El primer 90% del código ocupa el 90% del tiempo de desarrollo. El 10% restante del código ocupa el otro 90% de tiempo de desarrollo.


    Usar JAXB es tremendamente cómodo si tenemos que procesar datos XML bien definidos y cuya estructura sea bastante estable en el tiempo: nos evitamos toda la fontanería de análisis, verificación y marshalling / unmarshalling. Por otro lado, nos resuelve de un plumazo convertir los datos XML a objetos DTO/VO de datos en nuestra aplicación ya que nos permitirá pasarlos directamente a Servicios de negocio o a vista (si usamos un MVC), en lugar de crearlos y mantenerlos manualmente cada vez que se modifican las especificaciones.

    Pero no todo son ventajas. A la hora de acceder a un dato de un elemento, tratar con objetos puede suponer un verdadero engorro de iteraciones anidadas o tener que usar predicados para las colecciones de elementos, cuando con XPath podemos realizar un acceso rápido y directo al elemento a través de sencillas expresiones.

    Por ejemplo, supongamos que tenemos el siguiente XML:
      
        
          1
          
            
              ...
              06002
            
          
        
        
          2
          
            
              ...
              28034
            
          
        
        
          3
          
            
              ...
              06002
            
          
        
      
    
    Si necesitamos acceder a todos los elementos/objetos empleado cuyo elemento cp sea 06002, usando objetos generados por JAXB deberíamos iterar por la colección empleados, así:

    List<Empleado> empleados06 = new ArrayList<Empleado>();
    for ( Empleado empleado : empleados.getEmpleadoList() ) {
      for ( direccion : empleado.getDirecciones().getDireccionList() ) {
        if ( direccion.getCp().equals("06002") ) {
          empleados06.add(empleado);
        }
      }
    }
    

    con XPath es mucho más simple: podemos obtener una lista usando la expresión

    //empleado[cp='06002']

    Cuanto más niveles jerárquicos tenga nuestro árbol de información (más grados de anidación), más compleja se hace la recuperación de datos usando JAXB. Sin embargo, con XPath es tan simple como evaluar una expresión.

    Hasta que descubrí JXPath, tenía que elegir entre XPath (y pagar la "penalización" de realizar el marshalling/unmarshalling manualmente) o JAXB (y pagar la penalización de la selección de elementos con código manual).

    JXPath

    JXPath es otro genial componente de Apache Commons: una librería que evalúa expresiones (basadas en) XPath contra jerarquías de objetos Java, permitiendo hacer complejas consultas e iteraciones sobre estructuras y conjuntos de simples objetos POJO.

    Es decir, te permite usar XPath sobre objetos. Y no sólo sobre objetos serializados vía JAXB, sino cualquier POJO o colección de éstos. Si XPath es al XML lo que el SQL a las bases de datos, JXPath es el equivalente a los objetos Java. Es la solución perfecta para simplificar código que debe evaluar y filtrar conjuntos de objetos o, por ejemplo, cuando debemos seleccionar datos en objetos en tiempo de ejecución, en los que es sencillo construir una expresión XPath dinámica. El artículo "Java Object Querying Using JXPath", muestra una serie de ejemplos muy ilustrativos.

    Referencias y más información:

    martes, 13 de septiembre de 2011

    Sincronización de llamadas a Webservices y EJB

    A la vista de suficientes ojos, todos los errores resultan evidentes.
    Ley de Linus, formulada por Linus Torvalds, (1997).

    Los servidores de aplicaciones y la arquitectura J2EE fue diseñada desde el principio con el multithreading en mente. La idea de escalabilidad y procesamiento paralelo de forma segura ha sido en una constante en su desarrollo y evolución para que los desarrolladores pudiéramos construir aplicaciones seguras sin preocuparnos de asuntos como la gestión de memoria o la sincronización de objetos.

    Sin embargo, para las aplicaciones "de la vida real" nos encontramos con que algunas veces tenemos que "serializar" (en el sentido de alinear poniendo en serie, encolar manteniendo un orden y como contraposición al procesamiento paralelo) llamadas o procesamientos concretos... Algo para lo que J2EE no fue pensado desde el principio. Así, en el diseño y construcción de aplicaciones empresariales se suelen dar una serie de necesidades relacionadas entre si que, hasta hace poco, no han tenido solución directa manejada en el estándar JEE:
    • Serialización o sincronización de procesamiento de peticiones de un webservice. Es decir, poder hacer un WebService como si fuese un Servlet SingleThreadModel (ya obsoleto, por cierto). En definitiva: garantizar que no se atiende otra petición mientras se está atendiendo ya una, evitando la simultaneidad y por tanto evitando también duplicidad de procesamientos realizada por un cliente demasiado impaciente.
    • Serialización o proceso ordenado de los mensajes de una cola JMS o, lo que es lo mismo, mantenimiento del orden de llegada en el procesamiento de los mensajes. Esto, que podría parecer obvio, no lo es tanto, ya que para un MDB (Message Driven Bean), el contenedor crea un pool de objetos que trabajan en paralelo de forma que si se sacan 2 o 4 mensajes simultáneamente, puede ser que un mensaje más reciente se tarde menos en procesar que un mensaje anterior.
    • Instanciación de un singleton, patrón en principio no permitido por la especificación J2EE (hasta la reciente EJB 3.1, de la que hablaré más adelante). El patrón singleton es tremendamente necesario para asegurar la instanciación única de motores o manejadores de objetos (conexiones, datos, cachés, clientes, etc) que deben estar perfectamente sincronizados.
    El que no haya tenido que solucionar este problema podrá pensar que nada más fácil como especificar al servidor que instancie un pool de tamaño 1 para el EJB/MDB que queramos y, voilà, problema solucionado. La idea es buena. Si aseguramos una y sólo una exclusiva y única instancia de nuestro EJB, podemos resolver las tres necesidades de un sólo plumazo: podríamos publicar dicho EJB como un Webservice, tener un sólo MDB o tener nuestro Singleton.... Por ejemplo, en el caso de Glassfish, podríamos indicarlo en el correspondiente fichero sun-ejb-jar.xml, de la siguiente forma:

    
        
            
                DataProviderService
                
                    1
                    1
                    1
                    0
                
            
        
    
    


    Pero lamentablemente no es así: no funciona. Al menos en Weblogic, Glassfish y JBoss. Dudo que eso sea posible en ninguno. La razón es sencilla: el contenedor no está diseñado para eso, sino justamente para lo contrario, con lo que conseguiremos un nivel altísimo de reciclado de instancias, pero no conseguiremos mantener la misma instancia de forma permanente sin que la recicle el servidor. Tampoco haciendo variaciones con esos parámetros. Tras un número suficiente de pruebas comprobaremos que el servidor recicla y mantiene, aunque sea durante pocos instantes, varias instancias del mismo EJB.

    Las soluciones

    En principio hay tres soluciones válidas.

    Si estás usando JEE 5 o inferior, es decir, un contenedor EJB 3.0 o inferior, tienes dos soluciones a tu alcance que básicamente pasan por mantener la sincronización fuera del servidor de aplicaciones: crear un JMX MBean o sincronizar por tu cuenta. Si estás usando JEE 6, estás de enhorabuena. Aquí están mis propuestas.

    Usar un MBean de JMX
    Un MBean es, en definitiva, un singleton accesible vía JMX. No es un objeto manejado por el contenedor de EJB ni un estándar JEE, pero es una solución más elegante que realizar un Singleton por código ya que podemos controlar su ciclo de vida e incluso acceder a su estado de manera remota. Eso si, como decía, la sincronización de los objetos que use (colas JMS, etc) corre por nuestra cuenta. El problema del WebService lo podemos reducir a un problema de JMS, ya que podríamos publicar los mensajes en una cola y extraerlos uno a uno haciendo que nuestro MBean sea un cliente JMS.

    Usar un recurso sincronizable
    Un mismo EJB puede ejecutarse en diferentes JVM's. El ciclo de vida de los objetos y su concurrencia es cosa del contenedor. Por tanto, declarar un método de un EJB como "synchronized" es una violación de la especificación y no debería ser una opción. Por tanto, nuestros EJB's deberán usar un objeto manejado que pueda ser sincronizado: bien un Singleton propio (si nos basta con sincronizar para una única JVM), bien usando la transacciones serializables de base de datos (si necesitamos sincronizar entre varias JVM's o queremos hacerlo más escalable).

    Crear un Singleton Session Bean
    Si puedes usar un contenedor JEE 6 compatible, puedes implementar un Singleton Session Bean. Ésta es por fin la solución adecuada dentro del estándar JEE: un singleton manejado con atributos para controlar la sincronización. Con este método se solucionan de un plumazo todas las cuestiones de sincronización o singletons de una forma segura y manejada por parte del contenedor EJB.



    Referencias y más información:

    jueves, 28 de julio de 2011

    Cambiar la URL de conexión y establecer timeout a un Web Service JAX-WS

    En el artículo anterior explicaba cómo realizar un cliente de Web Service JAX-WS con maven. Las herramientas de JAX-WS generan la url de conexión (endpoint) a partir de la url definida en el WSDL. Sin embargo, desplegar nuestro cliente en un entorno de producción final requerirá que realicemos una programación un poco más afinada y parametrizada permitiendo cambiar la url de conexión (típicamente hacia el servicio de producción final) y establecer timeouts.

    Establecer los timeouts es extremadamente recomendable para prevenir que nuestra aplicación se quede "pegada" al servicio y eventualmente pueda bloquearse toda nuestra aplicación al quedarnos sin threads libres, ya que los tiempos máximos de espera suelen estar indefinidos por defecto.

    Para especificar todo esto no es necesario regenerar el cliente. La práctica habitual es parametrizar los valores de URL, timeout de conexión y timeout de lectura (request timeout) usando algún fichero de configuración o similar, recuperarlos y especificarlos en nuestro proxy cliente.

    A continuación dejo un snippet de código típico de ejemplo:


    import javax.xml.ws.BindingProvider;
    import com.sun.xml.ws.client.BindingProviderProperties;
    ...
    int requestTimeout = 5000;
    int connectTimeout = 500;
    String nuevaUrl = "http://www.cestel.es/jdialer/dataProvider";
    
    Jdialer jdialer = new Jdialer();
    BindingProvider bp = (BindingProvider) jdialer.getDataproviderPort();
    bp.getRequestContext().put(BindingProviderProperties.REQUEST_TIMEOUT,
    		requestTimeout);
    bp.getRequestContext().put(BindingProviderProperties.CONNECT_TIMEOUT,
    		connectTimeout);
    bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
    				nuevaUrl);

    domingo, 19 de junio de 2011

    JAX-WS Web Services con Maven


    Como decía en "Generación de código JAXB con Maven", una de las ventajas que aporta maven es la capacidad de automatizar tareas repetitivas y reproducibles del proyecto de desarrollo en el propio gestor del ciclo de vida del mismo independizándolo de la herramienta de desarrollo.

    Por ejemplo, si necesitamos acceder a un Web Service tenemos que generar los artefactos cliente que permitan "consumirlo" (Service Endpoint Interface -SEI-, clases valor de dependencias, etc...) y cada vez que cambie en algo el servicio tendremos que regenerar nuestros artefactos. Si esta tarea se realiza con un IDE, siempre necesitaremos el mismo IDE para actualizarla y (probablemente) pasar por algún tedioso wizard. Con maven, basta tener nuestros fuentes y el fichero pom.xml para que nuestro proyecto se construya en un momento sin instalar ni configurar nada.

    El plugin jaxws-maven-plugin provee los adaptadores para las herramientas wsgen y wsimport de JAXWS a través de los goals jaxws:wsgen y jaxws:wsimport para crear web services y clientes de éstos respectivamente.

    Para crear un web service, bastará con indicar el SEI en la sección execution del plugin y las opciones que queramos (en este caso, generar el fichero WSDL. Por ejemplo:
    
        org.codehaus.mojo
        jaxws-maven-plugin
        1.10
            
                
                    1
                    
                        wsgen
                    
                    
                         cestel.jdialer.provider.DataProviderService
                         true
                    
                
            
        
    Si queremos crear un cliente para un determinado servicio especificaremos, como habitualmente, el fichero de definición WSDL, el paquete donde queremos que se generen los artefactos y el directorio donde se generarán los ficheros fuente. Por ejemplo:
    
        org.codehaus.mojo
        jaxws-maven-plugin
        1.10
            
                
                    1
                    
                        wsimport
                    
                    
                        
                            ${project.build.directory}/jaxws/wsgen/wsdl/Jdialer.wsdl
                        
                        gesif.sgi.jdialer.dataprovider
                        ${basedir}/src/main/java
                    
                
            
        


    Referencias y más información:

    jueves, 19 de mayo de 2011

    Cerrar una sesión de telnet ordenadamente

    telnet towel.blinkenlights.nl
    Antes de que el ssh se extendiera como la forma de inicio de sesión remota a servidores UNIX y Linux, era frecuente realizar sesiones de telnet para acceso a una consola del servidor. Actualmente, el uso del telnet se limita prácticamente a realizar sesiones 5250 o 3270 hacia AS/400 o Mainframes o se reduce a realizar meras pruebas de conectividad TCP básicas cuando no tenemos el hping a mano y un tcptraceroute nos resulta teclear demasiado.

    Siempre que realizamos un telnet solemos ver un mensaje "Escape character is '^]'." como el siguiente:

    zarza@szarza:~$ telnet ftp.es.debian.org 80
    Trying 82.194.78.250...
    Connected to ftp.es.debian.org.
    Escape character is '^]'.
    ^]
    telnet> quit
    Connection closed.
    szarza@szarza:~$

    Hasta ahora, nunca había sabido cancelar las conexiones de telnet que se quedaban pegadas, así que acababa matando la sesión cerrando el proceso padre del telnet (konsole, xterm, cmd.exe, etc) porque no me había preocupado de saber cómo obtener y enviar la famosa secuencia "^]". Sin embargo, es bastante sencillo: se trata de la combinación CTRL+ALT GR+], lo cual es lógico: "^" significa CTRL y el carácter ] se obtiene pulsando la tecla "Alt Gr"+]. Una vez en el prompt del telnet, podemos poner "quit" para salir.

    Por otro lado, este artículo me ha servido para comprobar que sigue estando disponible la película Star Wars Episode IV en ASCII vía telnet haciendo "telnet towel.blinkenlights.nl" gracias a Simon Jansen.

    sábado, 7 de mayo de 2011

    Solar System Scope: el sistema solar a tu alcance

    Lo maravilloso de aprender algo, es que nadie puede arrebatárnoslo.
    -- B. B, King.

    Hace casi dos años, escribí un artículo sobre Sideralis, un planetario para móviles gratuito muy práctico. Desde entonces hasta ahora los móviles han cambiado mucho y han aparecido productos software espectaculares para astronomía en todas las plataformas. Por ejemplo, he tenido la ocasión de ver GoSkyWatch funcionando en un iPhone 4 y es realmente impresionante.

    Pero lo que hoy traigo aquí es igualmente impresionante, y no hace falta ni tener un iPhone ni siquiera instalarse nada, tan sólo un navegador y curiosidad.
    Solar System Scope es un simulador interactivo 3D del sistema solar online realmente espectacular. A diferencia de otros simuladores 2D estáticos (como el de la NASA) o dinámicos (como el de Gunn Interactive), éste permite movernos a través del sistema solar con total libertad de navegación e incluso de representación, ya que nos permite cambiar la escala del sistema (tanto en distancia como en tamaño de los objetos).


    No sólo es un buen simulador del sistema solar: es el mejor que he visto. Sus posibilidades de interacción lo hacen tan entretenido, que te puedes pasar un buen rato jugando con múltiples ángulos de observación (desde cada planeta haciendo doble clic) y observando las posiciones y movimientos a través de una representación desproporcionada para que nos quepan todos los planetas en pantalla.

    Como elemento didáctico para los niños, es verdaderamente genial, porque se puede jugar con la escala para enseñarles (al poner el sistema en escala real) las enormes distancias del sistema, cómo Urano gira tumbado con sus anillos prácticamente en vertical con respecto al plano orbital, mostrar las fases de la luna y por qué vemos siempre su misma cara, que no sólo Saturno tiene anillos o el extraño amanecer de Venus por el Oeste.




    Aunque aún le faltan funcionalidades por terminar (como la localización de estrellas o planetas), puedes comprobar que tiene una interfaz muy sencilla que te hará pasar un rato ameno y entretenido aprendiendo o visualizando aquello que aprendimos hace años. Prúebalo y me cuentas.


    Referencias y más información:

    domingo, 17 de abril de 2011

    PowerDesigner free alternatives... or something close (for PostgreSQL minimum)

    Herramientas de modelado de datos gratuitas (para PostgreSQL)


    Las herramientas de modelado de datos son muy útiles a la hora de realizar un diseño de datos nuevo o acercarnos a la comprensión y estudio de un modelo existente (en aquellas con características de ingeniería inversa). La capacidad de realizar un diseño de modelo visualizándolo de forma gráfica, a través de los Diagramas E-R, o de obtener un diagrama y documentación de una base de datos existente aumenta enormemente la eficiencia de nuestro trabajo reduciendo drásticamente el tiempo necesario con respecto a una realización manual de dichas tareas de diseño, análisis y estudio.

    La mejor y más completa herramienta de modelado que conozco es PowerDesigner©. No es objeto de este artículo describir la enorme cantidad de características que tiene, ni lo perfectamente resuelto que están en ella las tareas de modelado e ingeniería directa e inversa, pero te aseguro que es casi perfecta, contemplando todo el ciclo de modelado (lógico y físico, con multitud de bases de datos) de datos, además de otras tareas de modelado como el de objetos (con generación de código), esquemas xml, etc...

    PowerDesigner tiene, empero, un (grave) inconveniente: sólo está disponible para Windows, y en Sybase/SAP no se han preocupado (al contrario que otras compañías, como por ejemplo Spotify) de que pueda ejecutarse con Wine perfectamente.

    Vale. Así que tenemos Linux (por ejemplo) y no podemos ejecutar PowerDesigner pero necesitamos una herramienta que nos ayude en nuestro trabajo. ¿Qué alternativas hay?. He buscado en internet "herramientas de modelado de datos", "data modelling tools", "PowerDesigner alternatives"... con resultados decepcionantes: apenas listas de herramientas poco comentadas o algún comentario en foros... Así que me puse manos a la obra a buscar por mi cuenta y compartirlo con la comunidad.

    Lo primero que hay que tener en cuenta es que no existe ninguna herramienta gratuita alternativa comparable a PowerDesigner, ni por calidad ni cantidad de características. Pero existen herramientas bastante decentes (para ser gratuitas) que nos pueden servir para la mayor parte de nuestras necesidades. De hecho, hay una lista publicada con una cantidad enorme de herramientas diferentes de modelado que me llevaría muchos días probar. Así que, como en otras ocasiones, fijé una serie de características y condicionantes necesarios para mi, con lo que el número de herramientas candidatas se redujo considerablemente. Mi lista de características y condiciones ha sido la siguiente:
    • Debe estar disponible para Linux, como mínimo.
    • Debe tener características de modelado de datos (no basta con una herramienta de diagramas o que sea sólo para UML)
    • Debe tener características de ingeniería directa e inversa.
    • Debe soportar (para la ingeniería directa e inversa) como mínimo, PostgreSQL. Adicionalmente se valorará otras bases de datos como MySQL, Oracle, SQL Server, DB2, Derby, etc...
    • Debe tener características de documentación: generar diagramas E-R, y documentación de la base de datos.
    • Por supuesto, debe ser gratuita y, preferentemente, libre.
    A continuación, os detallo las herramientas analizadas

    Open System Architect 4.0.0

    Es Open Source. Frecuencia de actualización: desconocida.
    De todas las herramientas, analizadas es la que más se parece (dicho esto con todas las cautelas y salvando mucho, mucho las diferencias) a PowerDesigner, y es la que más características y posibilidades incorpora. Por ejemplo, es la única de las analizadas que integra el modelado lógico. Tiene la mejor organización de proyectos y menús y es rápida. Me han gustado muchos aspectos que aparentemente la podrían convertir en la más completa...sin embargo, también es la que más me ha decepcionado en el resultado final. El acceso a las bases de datos es vía ODBC (es la única de las analizadas que no está hecha en Java), lo cual me ha resultado un poco arcaico y engorroso de configurar, aunque al final ese no ha sido el inconveniente, sino la falta de acabados finales que hacían perder la lucidez de las funcionalidades:
    • Diagramas
      • los diagramas generados son feos (si bien este inconveniente es generalizado en todas las herramientas analizadas)
      • faltan opciones de presentación gráficas, de reordenado y de diseño de las tablas y sus relaciones
    • Ingeniería inversa:
      • La importación de tablas no es cómoda y no se sabe muy bien de qué esquemas estás importando. No puedes agregar tablas referenciadas relacionadas (hijas) o que la relacionen (padres) automáticamente.
    • Documentación:
      • No encontré las características de documentación mínimas que buscaba.
    En definitiva, debería ser la mejor... pero al final no me ha gustado. Es como si te montas en un Mercedes, que hace ruido, no tiene aire acondicionado y la dirección y el cambio son muy duros. No me ha resultado cómoda y no la voy a usar. Estaré atento a futuras versiones si es que se producen.


    SQL Power Architect 1.0.6


    Aunque es un producto comercial, la versión community es Open Source y gratuíta.Frecuencia de actualización: alta.

    La versión community gratuita es suficiente para un trabajo de modelado básico. Soporta ingeniería directa e  inversa de forma cómoda (se pueden agregar fácilmente las tablas hijas) con bastantes opciones gráficas de presentación. Es rápido, amigable y con él se puede generar una documentación mínima decente. De todos los analizados es el que menos opciones de modelado y documentación tiene, aunque cumple su cometido muy dignamente.


    SQuirreL SQL 3.2.1

    Open Source. Alta actualización. Esta herramienta es en realidad un cliente SQL multi-bases-de-datos (bastante bueno, la verdad) con capacidades de modelado e ingeniería directa e inversa.

    SQuirrel no destaca por sus capacidades gráficas de diagramas E-R. La organización de las tablas en una importación vía ingeniería inversa deja bastante que desear (como se puede observar) aunque salvando el detalle de tener que organizar y posicionar las tablas a mano, tenemos suficientes opciones para añadir tablas referenciadas o elegir la presentación de las tablas. Sin embargo, como he comentado, SQuirrel es un cliente multipropósito y multibase bastante completo, con muchos plugins y potentes editores de datos, SQL, DML y esquemas. Este es probablemente el más completo multi-propósito de todos los analizados.


    Druid III (3.11)

    Open Source. Frecuencia actualización: Alta

    Druid es fundamentalmente una herramienta pensada para crear bases de datos de forma gráfica y documentarlas. Su capacidad de documentación de bases de datos supera a todas las del análisis: es capaz de generar documentación tipo javadoc de una base de datos con los diagramas E-R y sus tablas de forma detallada, como se puede comprobar en la siguiente ilustración.

    La interfaz es un poco "extraña" (por llamarla de alguna manera) y muy poco intuitiva (probablemente la peor interfaz de todas). Sin embargo, si quieres documentar una base de datos, ésta es tu heramienta. Permite documentar una base de datos existente vía ingeniería inversa, realizando diagramas temáticos y realizando documentación adicional, de forma muy sencilla, añadiendo tablas relacionadas, y presentando la información que deseemos. En todo caso, a pesar de que le faltan opciones gráficas de zooming y layout y de tener una interfaz difícil, para documentar una base de datos vía ingeniería inversa, es la que más me ha gustado.


    Resumen:

    • Todos tienen carencias en la presentación de los diagramas E-R: faltan opciones de "layout" y los diagramas son poco vistosos.
    • Todos son multiplataforma (todos salvo Open Systems Architect están hechos en Java).
    • Todas las herramientas son válidas. Y deberías probarlas todas. Ahora bien, cada una tiene un punto fuerte
      • Documentación: Druid
      • Algo para empezar, sencillo: SQL Power Architect.
      • Cliente completo, todo en uno: SQuirrel
      • OSA no me ha gustado, a pesar de ser la única que incorpora modelado lógico de forma explícita.
    Todo esto, como siempre, es cuestión de gustos y de necesidades concretas. Así que, como en otras ocasiones, recomiendo probar y sacar conclusiones... y si las compartes conmigo comentando, te lo agradezco.

    ¿Conoces alguna otra herramienta que cumpla las condiciones iniciales?


    Referencias y más información:

    lunes, 21 de marzo de 2011

    java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String

    Ver lo que tenemos delante de nuestras narices requiere una lucha constante.
    -- George Orwell (1903-1950) Escritor británico.

    Un error en tiempo de ejecución como éste: java.lang.ClassCastException: [LFQN_ClassName; cannot be cast to FQN_ClassName, puede dejarte con cara de perplejidad durante algunos minutos. A mi me pasó. Y reconozco cierta vergüenza al admitir que fueron unos cuantos largos minutos en los que no daba crédito. Estaba tan concentrado en que el casting era correcto que no podía entender cómo la JVM me decía que no podía adaptar un tipo de dato a otro exactamente igual... Al cabo de unos minutos me di cuenta que la clave está en el corchete ("["). No se trata del mismo tipo: la máquina virtual me está diciendo que no puede convertir un array de ese tipo a ese mismo tipo (directo).

    En efecto, el capítulo 4.3 de la especificación de la máquina virtual referente al fichero class, lo explica bien claro: estamos intentando convertir una instancia de String[] a String. En fin, es de estas veces que tienes la solución delante pero no la estás buscando: estás en otra cosa.... Hay que confiar más en los mensajes de error.

    Por cierto que no veo sustituto de ésta url en el dominio oracle.com... así que puede que no esté disponible a partir del 1 de junio. Así es, amigos, uno de los primeros dominios que se registraron y más antiguos, dejará de existir (desaparecerá, en palabras de Oracle).


    Referencias y más información:

    miércoles, 9 de marzo de 2011

    Balteus cumple 10 años (en binario)

    (Ilustración: Fran Barquero)
    - "¿Le gusta nuestro búho?" -Rachael
    - "¿Es artificial?" - Rick Deckard
    - "Naturalmente." - Rachael
    --Blade Runner.


    El pasado domingo 6 de Marzo, este blog cumplió su segundo año de vida. Y he aprovechado la ocasión para hacerle un sutil cambio en el diseño, en la línea del anterior: sobrio y sencillo. Espero que os guste.

    Este año me han ocurrido algunas situaciones anecdóticas y relevantes para mi, teniendo en cuenta que soy un escritor de un blog muy especializado y con pocos lectores asiduos. La primera me ocurrió con mi post "La galaxia en un campo de fútbol", en el que comenté el libro de Juan Fernández Macarrón y el propio Juan me dejó un afectuoso comentario (también me pasó en el artículo sobre Logback: también el autor comentó en mi web).  La segunda es que enlazaron mi artículo sobre el control del nivel de aislamiento transaccional con JPA en "The Aquarium", el blog de referencia sobre Java EE y Glassfish. Fue una grata sorpresa, la verdad.

    Por otro lado, este año he sido menos prolífico que el primero, y no por falta de temas, sino por falta de tiempo. También he encontrado que los lectores habituales son "silenciosos" y no tienen tiempo y/o ganas de comentar mis artículos (en fin, sois así, ¿qué le vamos a hacer?).

    También he contado con un regalo-ilustración realizado especialmente para la ocasión. Gracias, Fran, por la ilustración. Me ha hecho mucha ilusión.

    A mis lectores frecuentes: gracias por seguir por ahí... y dejad algún comentario, por favor!. Me gusta saber que hay alguien ahí leyendo.

    P.D.: Si veis algo que ha quedado "raro" con el cambio de diseño, por favor, decídmelo.

    lunes, 28 de febrero de 2011

    Documentación de código con Doxygen y Maven


    Voluminous documentation is part of the problem, not part of the solution.
    -- Tom DeMarco, software development consultant
    Documentation is like sex: when it is good, it is very, very good; and when it is bad, it is better than nothing.
    -- Dick Brandon

    La documentación de proyectos software siempre ha sido un tema controvertido. Aspectos como la estructura, enfoque, perspectiva, y metodología han generado decenas de tratados y "estándares" (como sinónimo de modelo, patrón o referencia) tan voluminosos como imprácticos e irrealistas. Sin embargo, ya comenté en "La falacia de la Ingeniería del Software" mi poca confianza en la aplicación realista de muchas metodologías y estándares que comparten entre sí la escasez de referencias reales profesionales.

    Mi experiencia a la hora de documentar un proyecto para la cesión de  administración y mantenimiento a terceros me ha enseñado que la documentación sólo sirve si:
    • está contínuamente actualizada y sincronizada con lo que documenta (el adverbio continuamente aquí, es clave)
    • la documentación y lo documentado están mutuamente accesibles
    • tiene estructura y formato ágil para la consulta
    Por supuesto, creo que los aforismos "cuanta más documentación mejor" o "toda documentación que se haga es poca" son del todo erróneos. El objetivo es la calidad, y creo honestamente que la cantidad participa de forma inversamente proporcional en una ecuación de calidad.

    En lo que a documentación de código se refiere, los objetivos anteriores se obtienen con creces con sistemas de generación de documentación automatica:
    • La documentación está junto a lo documentado favoreciendo la contínua actualización
    • Están mutuamente accesibles
    • La estructura es la idónea para facilitar el acceso a la documentación precisa fácilmente ya que suelen generar HTML
    En este aspecto, la mejor herramienta que he probado hasta ahora es, sin duda y con diferencia, Doxygen.

    Doxygen es un generador de documentación gratuito para  C++, C, Java, Objective-C, Python, IDL, Fortran, VHDL, PHP, C# y D. Su licencia es GPL y sus resultados son comparables (e incluso mejores en algunos aspectos) a documentadores comerciales.

    Los desarrolladores de Java, que ya conocen Javadoc, cuya generación está perfectamente integrada con Maven, se preguntarán para qué diablos necesitarían otro documentador. Como se comenta en la segunda cita introductoria de este artículo, Javadoc está bien: es mejor que nada. Pero comparar Doxygen con Javadoc es equivalente a comparar maven con "make".

    Las características más destacables, frente a Javadoc, desde mi punto de vista:
    • Genera automáticamente diagramas de clase y colaboración. Opcionalmente, diagramas de dependencia, llamada, etc... 
    • Permite incluir el código fuente resaltado en la propia documentación
    • Formatos: HTML,CHM, PDF, XML, etc..
    Doxygen es una utilidad basada en línea de comando, como Javadoc, con más 100 opciones configurables que permiten ajustar la documentación final. Aunque la mayoría de las opciones interesantes ya están configuradas por defecto, Doxygen cuenta con un frontal gŕafico (doxywizard) muy util para gestionar las opciones y los ficheros de configuración. Se instala fácilmente ("sudo apt-get install doxgen-gui", en *ubuntu) existiendo distribuciones en código fuente y binarios para Mac OS y Windows... y, he aquí lo mejor: existe un plugin para maven.

    Usando Doxygen con Maven
    De la misma forma que podemos automatizar la generación de documentación javadoc en nuestras construcciones con maven, podemos hacerlo con Doxygen. Para ello, tan sólo debemos seguir los siguientes pasos:
    1. Instalar Doxygen y hacerlo disponible en el path (para *ubuntu esto es automático con la instalación)
    2. Añadir el plugin a nuestro pom.xml. A continuación muestro las opciones de configuración que yo suelo usar
    
        ...
        
            
                
                    com.soebes.maven.plugins.dmg
                    doxygen-maven-plugin
                    1.0.1
                
            
        
        ....
        
            
                
                    com.soebes.maven.plugins.dmg
                    doxygen-maven-plugin
                    1.0.1
                    
                        false
                        es.cestel.szarza.balteus
                        1.0
                        spanish
                        true
                        true
                        true
                        true
                        src/main
                        true
                    
                
            
        
        ....
    
    
    Recomiendo probar con las opciones de generación de diagramas. Especialmente los diagramas de colaboración pueden ser muy útiles para ciertos módulos de proyecto.


    Referencias y más información:


    lunes, 31 de enero de 2011

    StatementTimeout / QueryTimeout con PostgreSQL

    Si no esperas lo inesperado no lo reconocerás cuando llegue.
    - Heráclito de Efeso (540 AC-470 AC) Filósofo griego

    Como comentaba en "las 8 falacias de los sistemas distribuídos", en los entornos de producción debemos tener en cuenta que pueden suceder hechos que no se producen en nuestros entornos de desarrollo, integración o preproducción... y ciertamente ocurren. En estos entornos son necesarios procesos y tareas concurrentes inherentes a su propia naturaleza y ambiente de "explotación" (tareas de mantenimiento tanto programados -backups-, como no programados -recuperaciones de datos-, arranque eventual de otras -nuevas- aplicaciones, procesos de datawarehousing, etc).

    Uno de estos sucesos típicos suele ser el inexplicable y aleatorio bloqueo de una sesión o de toda una aplicación entera. Tras el correspondiente susto y examen exhaustivo, detectamos la causa en una consulta de base de datos que, eventualmente, tarda demasiado. En algunas ocasiones las causas son muy poco evidentes y muy difíciles de detectar, ya que sólo se producen por la coincidencia de determinados eventos (periódicos o no), e incluso en un determinado orden.

    ¿Y por qué tarda tanto una consulta que en nuestro entorno de preproducción se lleva apenas unas pocas decenas de milisegundos? Pues típicamente porque ocurre un bloqueo en la base de datos debido a una transacción de larga duración. Si las cosas se complican, puede existir incluso un deadlock (bloqueo mutuo) que deje nuestro sistema completamente bloqueado y produzca un efecto dominó en otras aplicaciones dependientes de la misma base de datos.

    Obviamente, la solución pasa por detectar la casuística concreta y evitarla, pero mientras buscamos la causa o la solución, necesitamos mantener nuestro sistema funcionando con normalidad. Para protegernos a este tipo de eventualidades, se debe establecer un valor de timeout en nuestras consultas y transacciones a bases de datos que impida que una consulta se quede indefinidamente esperando el resultado y, por tanto, todas las sesiones de la aplicación que llegan a ese punto. En los entornos JEE, donde se configuran pools de conexiones a bases de datos que permiten un uso eficiente de recursos y conexiones de bases de datos, la ausencia de estos timeouts en esas condiciones pueden suponer el agotamiento de las conexiones del pool, debido a que no se liberan las conexiones y, por tanto, la imposibilidad de que nuevas sesiones de la aplicación puedan funcionar.

    Configuración de Statement Timeout en Glassfish
    En la mayoría de los servidores de aplicaciones y contenedores web JEE, existe una forma de indicar este parámetro para cada uno de nuestros pools, permitiendo especificar distintos parámetros en función de las características de las aplicaciones o de la duración de las transacciones. En el caso de Glassfish, por ejemplo, es a través del atributo StatementTimeout del pool (que internamente realiza las llamadas a setQueryTimeout() del driver.


    Usando PostgreSQL, este atributo sin embargo nos ha dado una desagradable sorpresa:

    Caused by: org.postgresql.util.PSQLException: Method org.postgresql.jdbc4.Jdbc4PreparedStatement.setQueryTimeout(int) is not yet implemented.
            at org.postgresql.Driver.notImplemented(Driver.java:753)
            at org.postgresql.jdbc2.AbstractJdbc2Statement.setQueryTimeout(AbstractJdbc2Statement.java:635)
            at com.sun.gjc.spi.base.ConnectionHolder.prepareStatement(ConnectionHolder.java:477)
            at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.prepareStatement(DatabaseAccessor.java:1162)
            at oracle.toplink.essentials.internal.databaseaccess.DatabaseCall.prepareStatement(DatabaseCall.java:612)
            at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:485)

    Pues si, aunque parezca increíble, el driver jdbc de Postgresql no implementa aún setQueryTimeout(), al menos hasta la versión disponible en el momento de escribir este artículo (versión Version 9.0-801 de 2010-09-20).

    Establecimiento de propiedades de la conexión en el pool de conexiones de Glassfish
    La solución es establecer el parámetro de conexión SocketTimeout, que especifica en segundos el tiempo máximo que se espera respuestas del servidor antes de cerrar la conexión. Este parámetro tiene el mismo efecto que el atributo StatementTimeout / QueryTimeout que comentaba anteriormente.


    Para nuestros scripts PL/pgSQL, podemos establecer directamente el parámetro statement_timeout al inicio:

    SET statement_timeout TO 5000; -- para 5 segundos
    
     <...resto del PL>
    
    RESET statement_timeout; -- reset
    

    En general, establecer un valor de timeout en operaciones síncronas es una buena práctica para evitar sorpresas desagradables.

    Related Posts Plugin for WordPress, Blogger...
    cookieassistant.com