Bitsmi Blog

OCP7 11 – Hilos (06) – Colecciones con protección de Thread

30-12-2018 - Xavier Salvador

En general las colecciones de java.util no tienen protección de thread. Para poder utilizar colecciones en modo de protección de thread se debe utilizar uno de los siguientes mecanismos:

  • Utilizar bloques de código sincronizado para todos los accesos a una colección si se realizan escrituras.
  • Crear un envoltorio sincronizado mediante métodos de biblioteca como java.util.Collections.synchronizedList(List<T>). Es importante destacar que el hecho de que una Collection se cree con protección thread no hace que sus elementos dispongan de la misma protección de thread.
  • Utilizar colecciones dentro de java.util.concurrent.

more…

Autenticación en Bitbucket mediante SSH

04-11-2018 - Antonio Archilla

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.

more…

Anidar listas de objetos de negocio en un modelo Json mediante Swagger

02-07-2018 - Xavier Salvador

Implementación

Para poder anidar distintos objetos de negocio dentro del Swagger, el primer paso consiste en añadir éstos en la sección definitions del Swagger.

Aquí deben declararse todos los que se van a utilizar para crear la lista de objetos de tipo Element según el ejemplo que se ha desarrollado.

Una vez añadidas las definiciones se añade al Swagger el siguiente código:

ElementList:  
    type: array
    description: Elements List.
    items:
      $ref: '#/definitions/Element'

Type indica a Swagger que el elemento contenido es de tipo array. Description describe la lista de elementos de la lista.

items:
    $ref: '#/definitions/Element'      

Con esta sintaxis se indica a Swagger que cada elemento de la lista ElementList se corresponde con una definición de objeto de negocio cuya definición també aparecerá cuando Swagger muestre el modelo general.

Se pueden anidar varios niveles en la creación de un objeto complejo. En el caso de ejemplo que se describe en el apartado siguiente se puede visualizar tres niveles: ElementList -> Element que contiene a su vez listas del tipo Acces e Invoice.

more…

Error Handshake Failure al establecer una conexión SSL

25-05-2018 - Antonio Archilla

Descripción de error

Se produce un error de tipo Handshake Failure (detalle del tipo de error en este enlace) cuando se intenta establecer una conexión con un servidor externo a través del protocolo SSL.

more…

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

17-02-2018 - Antonio Archilla

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.

more…

OCP7 08 – Aserciones

07-02-2018 - Antonio Archilla

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 <expression> [: <message>]

Where:

  • expression: 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
  • message: Opcional. Si se indica un valor en la expresión, este será adjuntado en el error AssertionError producido.

more…

OCP7 11 – Hilos (03) – Mecanismos básicos en la plataforma Java

27-01-2018 - Xavier Salvador

En este artículo se exponen los mecanismos básicos que proporciona la plataforma estándar de Java para la implementación de tareas concurrentes detallada para su versión 7.

Se tratarán los siguientes conceptos:

  • Implementación de tareas mediante hilos de ejecución
  • Gestión del ciclo de vida de los hilos de ejecución mediante API

more…

OCP7 08 – Excepciones (II)

27-01-2018 - Xavier Salvador

Extensión de los tipos de excepción estándar

En la medida de lo posible se deberá hacer uso de la jerarquía de excepciones provistas por la JDK. En caso de querer crear nuevos tipos, se deberán tener en cuenta los siguientes puntos:

  • Extender de RuntimeException o una de sus subclases en caso de definir un tipo de error no recuperable (Excepción no comprobada).
  • Extender de Exception o una de sus subclases (a excepción de RuntimeException) en caso de definir un tipo de error recuperable (Excepción comprobada) que debe ser explícitamente declarado y capturado.
  • No extender directamente de la clase Throwable, ya que la mayoría de tratamientos de errores mediante bloques try/catch se hace como mínimo a nivel de Exception. En estos casos, las excepciones derivadas directamente de Throwable no serían capturadas por estos bloques lo que podría provocar efectos no previstos.

Tratamiento y propagación de excepciones

Se puede encontrar más información aquí.

Propagación entre métodos

Cuándo se gestionan las excepciones, hay ocasiones que se desea relanzar una excepción que está siendo gestionada. Un programador novicio cree que el código siguiente puede hacer esto:

public class EjemploExceptionRethrow {
    public static void demoRethrow()throws IOException {
    try {
         
        // Se fuerza el lanzamiento de una IOException cómo ejemplo,
        // Normalmente la excepción es disparada por la ejecución de código.
        throw new IOException(Error);
    }
    catch(Exception exception) {
         
     /* Se trata la excepción y se relanza */
     throw exception;
    }
   }
 
    public static void main(String[] args) {
        try {
            demoRethrow();
        } catch (IOException exception) {
            System.err.println(exception.getMessage());
        }
    }
}

El código anterior no compilará correctamente en caso de hacerse con versiones de Java anteriores a 7 ya que el método demoRethrow explicitamente especifica en su firma que la excepción lanzada es de tipo IOException, mientras que el bloque catch declara la excepción capturada y relanzada de tipo Exception. En este caso el compilador no es capaz de inferir el tipo real de la excepción. En caso de la compilación del código se realice sobre la versión 7 o posterior, el código anterior será válido y compilará correctamente. En este caso, el compilador sí es capaz de inferir el tipo final al que pertenece de la excepción relanzada analizando las excepciones lanzadas dentro del bloque try.

El siguiente ejemplo muestra otro modo de gestionar la excepción y propagarla.

public class EjemploAntiguoExceptionRethrow {
    public static demoRethrow() {
    try {
     throw new IOException("Error");
    }
    catch(IOException exception) {
     /*
       * Se trata la excepción y se relanza
       */
     throw new RuntimeException(exception);
    }
   }
 
    public static void main(String[] args) {
        try {
            demoRethrow();
        } catch (RuntimeException exception) {
            System.err.println(exception.getCause().getMessage());
        }
    }
}

El problema con el código anterior es que realmente no está relanzando la excepción original. La está encapsulando con otra excepción, lo que implica que el código del catch del main necesita gestionar la excepción con la que se ha encapsulado el catch original.

Captura de excepciones mediante bloque try/catch/finally

Java 7 permite capturar múltiples excepciones en un mismo bloque catch. Este mecanismo es llamado multicatch.

try {
 
    // Ejecución que puede generar uno de los errores catch
 
} catch(SQLException e) {
    System.out.println(e);
} catch(IOException e) {
    System.out.println(e);
} catch(Exception e) {
    System.out.println(e);
}

A partir de Java 7 se puede implementar el multicatch.

try {
    // Ejecución que puede generar uno de los errores catch
} catch(SQLException | IOException e) {
    System.out.println(e);
} catch(Exception e) {
    System.out.println(e);
}

A destacar la utilización del carácter pipe | para separar los nombres de las clases. El carácter pipe | entre los nombres de las excepciones es el mecanismo cómo se declaran las múltiples excepciones a ser capturadas por el mismo catch.

Para un mayor detalle en el siguiente enlace se puede encontrar más información sobre la implementación del multicatch.

Bloque try with resources

Implementación de la interfaz Closeable. Para evitar que recursos como ficheros, comunicaciones con la BBDD u otros servicios queden en un estado indeterminado tras un error, Java cuenta con mecanismos para evitar este tipo de situaciones, uno de los cuáles es el try-with-resources, Similar al try pero con las siguientes diferencias:

  • Diferencia de que entre paréntesis se declaran aquellos recursos que se desean proteger.
  • Un recurso siempre debe ser cerrado después de que termine el programa.
  • Un recurso es cualquier objeto que implemente la clase java.lang.AutoCloseable.

Los recursos de este bloque de código deben implementar la interfaz java.io.Closeable (que hereda de AutoCloseable – se recomienda mejor utilizar este objeto). Utilizando este bloque de código el programador no tiene que preocuparse de cerrar los recursos utilizados dentro del try-with-resources.

Una de las ventajas de Autocloseable consiste en poder llamar varias veces a su método close() obteniendo siempre el mismo resultado. Las excepciones generadas durante el proceso de cierre de un recurso son totalmente ignoradas.

Es importante indicar que el orden del cierre de recursos es el opuesto al orden de apertura de esos recursos: el primer recurso en abrirse es el último recurso en cerrarse.

Ejemplo para definir un nuevo objeto try-with-resources

package TryWithResources;
 
public class NewResource implements AutoCloseable{
     
    String closingMessage;
  
    public NewResource(String closingMessage) {
        this.closingMessage = closingMessage;
    }
  
    public void doSomeWork(String work) throws ExceptionA{
        System.out.println(work);
        throw new ExceptionA("Exception thrown while doing some work");
    } 
 
    @Override
    public void close() throws ExceptionB{
        System.out.println(closingMessage);
        throw new ExceptionB("Exception thrown while closing");
    }
  
    public void doSomeWork(NewResource res) throws ExceptionA{
        res.doSomeWork("Wow res getting res to do work");
    }
}

Ejemplo de su utilización en la ejecución de un programa

package TryWithResources;
 
public class TryWithRes {
 public static void main(String[] args) {
   
        try(NewResource res = new NewResource("Res1 closing")) {
            res.doSomeWork("Listening to podcast");
    
        } catch(Exception e) {
            System.out.println("Exception: "+e.getMessage()
    +" Thrown by: "+e.getClass().getSimpleName());
        }
    }
}

Ejemplo cuándo existen recursos anidados ambos derivando de AutoCloseable.

package TryWithResources;
 
public class TryWithResV2 {
 
    public static void main(String[] args) {
 
        try (NewResource res = new NewResource("Res1 closing");
                 NewResource res2 = new NewResource("Res2 closing")) {
 
         try (NewResource nestedRes = new NewResource("Nestedres closing")) {
                nestedRes.doSomeWork(res2);
         }
        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage() 
                + " Thrown by: " + e.getClass().getSimpleName());
        }
    }
}

Nótese el uso del carácter » ; » cómo separador en la declaración de los recursos dentro del bloque try-with-resources.

Tratamiento de excepciones no capturadas

En el procesado de hilos (Threads) puede producirse que su ejecución termine de forma abrupta debido a que se ha producido una excepción y ésta no ha sido capturada. Java dispone a partir de la versión 5 de la Interface UncaughtExceptionHandler perteneciente al paquete java.lang. Esta interface es invocada cuándo un hilo (Thread) termina abruptamente su ejecución debido a una excepción no capturada.

El siguiente código de ejemplo muestra la utilización de esta Interface.

public class MultiplexUncaughtExceptionHandler implements UncaughtExceptionHandler {
    private final UncaughtExceptionHandler[] handlers;
 
    public MultiplexUncaughtExceptionHandler(UncaughtExceptionHandler... handlers) {
        super();
        this.handlers = Arrays.copyOf(handlers, handlers.length);
    }
 
    public void uncaughtException(Thread t, Throwable e) {
        for (UncaughtExceptionHandler handler : handlers) {
            try {
                handler.uncaughtException(t, e);
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
    }
}

Se puede encontrar más información en este enlace oficial de Oracle.

more…

OCP7 13 – Localización

18-10-2017 - Xavier Salvador

Las especificaciones para el uso de recursos en formato de fichero de propiedades a través de la API ResourceBundle de Java definen unas reglas para la nomenclatura y ubicación de dichos ficheros que hay que seguir de forma que la JVM pueda localizar y recuperar los recursos definidos en ellos. No obstante, dicha API proporciona mecanismos que permiten personalizar este proceso. En este POST se explica cómo hacerlo.

more…

Spring Boot – Configuración del contenedor subyacente

14-05-2017 - Antonio Archilla

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 o 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.

more…

results matching ""

    No results matching ""