Agustín Ventura
Ingeniería de Software
Docker es una tecnología de contenedores relativamente reciente (de 2013) que si bien ha puesto sobre el terreno de juego el concepto de contenedores (aunque estos son tan antiguos como del 2005 que fue cuando salieron con Solaris…). Un contenedor viene a ser una máquina virtual ligera, en realidad es una aplicación (se ejecuta en espacio de usuario, usa el kernel del sistema operativo, etc…) en la que se puede instalar un sistema operativo y unas aplicaciones (una imagen) y por tanto se comportará como una máquina virtual a efectos prácticos. La ventaja de esta aproximación es que mientras una máquina virtual tiene unos recursos fijos que toma del sistema anfitrión, Docker no, con lo que es más eficiente y ligero. La verdad es que todo el mundo habla de Docker, pero todavía no me he encontrado a nadie que lo use en producción. No obstante, este sistema es muy cómodo para montar entornos de desarrollo. Lo primero, como siempre, es instalar Docker. La página de [instalación] (https://docs.docker.com/engine/installation/linux/ubuntu/) no refiere aún información para Ubuntu 17.04, a ver que me voy encontrando. El primer paso de la instalación es instalar una serie de paquetes que para mi sorpresa (no) ya tengo instalados. A continuación, y resumiendo las detalladísimas instrucciones de instalación (esto es buena documentación y lo demás son tonterías), los pasos para la instalación son los siguientes:
Con Spring Boot es relativamente sencillo generar un backend para una aplicación por complejo que sea su dominio, precisamente lo bueno de Spring Boot es que permite realizar rápidamente todo el trabajo de infraestructura para centrarse por una parte en el código del dominio y por otra… en la UI. En los últimos años hemos pasado de un paradigma de desarrollo en servidor a uno nuevo cliente/servidor (otra vez). El servidor suele ser una API [REST ] (https://en.wikipedia.org/wiki/Representational_state_transfer) mientras que los clientes son típicamente aplicaciones Android, iOS y Web (lo cual incluye otros servicios REST y con eso emergen los microservicios…). En materia de clientes web, el ganador en toda la historia ha sido JavaScript y básicamente, dentro de JavaScript hay dos grandes frameworks:
Una de las funcionalidades básicas de Hibernate es abstraer la base de datos, pero sin embargo en tiempo de desarrollo resulta bastante útil controlar las consultas que va generando el motor así como sus parámetros. Desde las primeras versiones Hibernate tiene una propiedad, show_sql que muestra estas consultas por consola. Esto tiene dos desventajas, la primera que usa la consola y la segunda que para habilitarlo y deshabilitarlo se depende de un archivo de configuración específico (normalmente el propio de Hibernate o incluso una clase Java si se esta utilizando la configuración Java de Spring). Además este parámetro tan sólo muestra las consultas y no los parámetros de las mismas. La solución idónea pasa por utilizar el sistema de logging estándar que se utilice en la aplicación, así se puede mostrar en consola o registrar en un archivo o cualquier otro tipo de solución y además su activación y desactivación se hace en el sitio lógico, el archivo de configuración de logs de la aplicación. Otra ventaja es que, además, con su configuración oportuna se pueden logar también los parámetros de las consultas (algo muy útil para contrastar con nuestro cliente SQL favorito). Para poder mostrar estos logs hay dos loggers propios de Hibernate que configurar:
Unos apuntes rápidos sobre la nueva API de fecha y hora en Java 8. Primero, clases fundamentales:
LocalDate: La fecha en el contexto local. En una zona horaria determinada. LocalTime: La hora en el contexto local. LocalDateTime: La composición de ambas. Aquí lo fundamental es que corresponden al contexto local del observador, es decir esa hora es válida para Sevilla pero no para Canarias. La hora y la fecha (por extensión) si la necesito completa se representa mediante una fecha/hora y un offset con respecto a UTC. Por ejemplo, ahora mismo en Sevilla estoy en UTC +02:00 y en Canarias en UTC +01:00. Para representar eso tengo:
Bueno, pues ya queda la parte final, lanzarlo. Creo un método main en Wp2JBake, el primer argumento será el archivo de origen y el segundo el directorio de destino. Como de toda la gestión de errores se encarga el programa en sí, lo único que tengo que hacer es capturar la posible IllegalArgumentException y listo:
public static void main (String... args) { if (args.length!=2) { System.out.println("Wp2JBake needs two arguments to work: First the input file and second the destination folder"); } else { try { Wp2JBake exporter = new Wp2JBake(args[0], args[1]); Set<File> exportResult = exporter.generateJBakeMarkdown(); if (!exportResult.isEmpty()) { System.out.println("Export successful in " + args[1]); } } catch (IllegalArgumentException | IllegalStateException e) { System.out.println("Error exporting: " + e.getMessage()); e.printStackTrace(); } } } Ahora queda lo de siempre, generar el jar en Maven con todas sus dependencias. Añado al pom.xml la configuración del assembly-plugin para que genere el Manifest ya que sin él, el jar no sería ejecutable y además le digo que empaquete las dependencias junto con el jar: