Todas las entradas de: Antonio Archilla

NoClassDefFoundError en la inicialización de una clase Java

Los bloques de código estático en el lenguaje de programación Java són un mecanismo de inicialización de los recursos estáticos de una clase
que se ejecuta en el momento en que se interactua con dicha clase por primera vez. Un fallo producido dentro de dichos bloques estáticos puede provocar
errores inesperados en la ejecución del programa. En este post se habla de una de la posibles consecuencias de un error de este tipo y de cómo puede
ser identificado.

Seguir leyendo NoClassDefFoundError en la inicialización de una clase Java

Aplanado de estructuras de ficheros con PowerShell

En este post se muestra una implementación de copia plana de los contenidos de un árbol de directorios determinado mediante un script de PowerShell. Dicho de otra manera, el resultado de la ejecución de este script copiará en un mismo directorio destino todos los ficheros contenidos en un directorio origen y todos sus subdirectorios.

Seguir leyendo Aplanado de estructuras de ficheros con PowerShell

OCP7 11 – Hilos (05) – Variables atómicas y bloqueos de sincronización

En este artículo se exponen los mecanismos básicos que proporciona la plataforma estándar de Java para el acceso y actualización de variables de forma concurrente.
Se tratarán los siguientes conceptos:
  • Uso de variables atómicas
  • Acceso a variables mediante bloqueos de sincronización

Seguir leyendo OCP7 11 – Hilos (05) – Variables atómicas y bloqueos de sincronización

Autenticación en Bitbucket mediante SSH

Esta mini guia expone los pasos a seguir para configurar el acceso en Bitbucket mediante SSH, de forma que no sea necesaria la especificación de las credenciales cada vez que se realice una acción sobre un repositorio hospedado en dicho servicio. Incluye la configuración necesaria para los 2 tipos de repositorio soportados por Bitbucket (Git y Mercurial).

Es importante mencionar que la guia está enfocada a entornos Windows aunque los pasos son bastante similares en entornos Linux cambiando las instrucciones de consola por las del entorno de que toque.

Seguir leyendo Autenticación en Bitbucket mediante SSH

OCP7 11 – Hilos (02) – Control de Errores Inesperados

La clase Thread cuenta con un mecanismo de control de errores para casos en que se produzca un final inesperado a la ejecución de éste. A través del método setUncaughtExceptionHandler de la clase Thread es posible recoger la causa de esta finalización anómala dentro del hilo principal de la aplicación y actuar en consecuencia.

A continuación se añade un ejemplo que ilustra su funcionamiento:

// Resto del código
Thread t = new Thread(new Runnable()) {

 @Override
 public void run() {
  // Código del thread que provoca
  // una finalización anómala en su
  // ejecución
 }
});
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
  
 @Override
 public void uncaughtException(Thread t, Throwable e) {
  // Tratamiento del error producido en el Thread.
  // Por ejemplo, se puede registrar un error o emprender
  // una acción alternativa
 }
});

// Inicialización de la ejecución del Thread.
// Gracias al Listenr del thread no es necesario supervisar la finalización
// del thread para tratar el error pudiendo seguir la ejecución del programa
// principal
t.start(); 

// Resto del códigox

 

OCP7 08 – Aserciones

La aserción es un mecanismo que permite comprobar suposiciones en el código que ayudan a confirmar el buen funcionamiento del mismo y que este está libre de errores. En el siguiente post se muestra su funcionamiento básico y las situaciones en las que es apropiado su uso y en las que no.
Una expresión de tipo aserción se identifica por la palabra clave assert. Su sintaxis es la siguiente:
assert <expresión> [:]
Dónde:
  • expresión: Expresión booleana que indicará si la suposición se cumple o no. En caso de que no se cumpla, se lanzará un error de tipo AssertionError
  • valor: Opcional. Si se indica un valor en la expresión, este será adjuntado en el error AssertionError producido.

Seguir leyendo OCP7 08 – Aserciones

Spring Boot – Configuración del contenedor subyacente

Una de las principales características del framework Spring Boot es permite la ejecución de aplicaciones web sin necesidad de usar servidores de aplicaciones externos donde desplegarlas. Esto lo consigue mediante el uso de un contenedor incrustado en la misma aplicación (Tomcat, Jetty Undertow). Aunque el framework configura por defecto este contenedor con valores válidos en muchos de los casos, a veces las peculiaridades de las aplicaciones hacen que se tengan que modificar ciertos parámetros de la configuración, como por ejemplo el soporte para HTTPS o el tamaño máximo peticiones de las peticiones, por poner algunos ejemplos. En este post se explicará la manera de personalizar estos valores.

Seguir leyendo Spring Boot – Configuración del contenedor subyacente

SQL – Encapsulado de sentencias complejas

En muchas ocasiones el acceso a un conjunto de datos almacenado en base de datos requiere de una consulta especialmente compleja. En los casos en que se debe permitir acceso a sistemas externos a estos datos, la solución ideal pasa por implementar una capa de negocio intermedia entre la aplicación consumidora de la información y la base de datos, sea mediante servicios web, un data-grid u otra componente que permita abstraer la complejidad de la obtención de los datos para facilitarla al sistema externo.
Hay casos en que esto no es posible y por requerimientos de arquitectura en el sistema, las aplicaciones externas deben acceder directamente a la base de datos para obtener la información. En estos supuestos, es buena idea implementar una interfaz para la obtención de los datos, una API que permita crear una caja negra sobre la implementación real de la obtención de los datos. Con ello se consigue:
  • Las modificación de las estructuras subyacentes de la base de datos no afectan a la integración con el sistema externo al mantenerse la interfaz de obtención de datos.
  • Permite mantener el control de cómo se obtienen los datos, lo que minimiza la posibilidad de errores al estar centralizada en una única implementación.
  • Ante la aparición de errores, se minimiza el tiempo necesario para la corrección, ya que estaría localizada en un único punto: La implementación de la interfaz.
En este post se propone un posible mecanismo para construir estas interfaces de acceso aplicado a bases de datos Oracle.

Seguir leyendo SQL – Encapsulado de sentencias complejas

SQL – Expresiones de Tablas Comunes (CTE)

Las Expresiones de Tabla Común, en inglés Common Table Expressions (CTE), se pueden definir cómo la especificación de un conjunto de resultados temporales que se obtienen a través de una subconsulta determinada. El ámbito de aplicación de este conjunto de datos queda restringido a una ejecución concreta de la instrucción SQL en la que se encuentra definida (SELECT, INSERT, UPDATE o DELETE), momento a partir del cual, dichos resultados son eliminados del contexto de ejecución. Dicho de una manera un tanto simplista y haciendo un símil con conceptos aplicables a la programación imperativa, sería cómo la definición de una subrutina local, en el sentido que permite definir un «código», en este caso una consulta que devuelve un conjunto de resultados determinados, asignarlo a un identificador determinado y usarlo cómo referencia dentro de otras partes de la consulta principal.

Algunas de las ventajas que proporciona su utilización son:

  • Permite evitar la reevaluación de una subconsulta que se ejecute múltiples veces dentro de la consulta principal
  • Simplifica la escritura y legibilidad de consultas complejas en las que se realicen definiciones de tablas derivadas (definidas dentro de la clausula FROM cómo una subconsulta) en uno o múltiples niveles
  • Permite substituir la definición de vistas globales cuando sólo están restringidas a una sola consulta, ayudando a no «ensuciar» el espacio global de nombres con definiciones innecesarias
  • Permite realizar operaciones de agrupación o condicionales sobre datos derivados de operaciones escalares o no deterministas. En este caso se podrá definir el cálculo de las operaciones requeridas dentro de la consulta CTE y posteriormente realizar las agrupaciones necesarias en la consulta principal o en otra CTE como si de valores de una tabla corriente se tratara

Seguir leyendo SQL – Expresiones de Tablas Comunes (CTE)