Todas las entradas de: Antonio Archilla

Multi-Release JARs

En los últimos años Java ha estado evolucionando muy rápido con el nuevo ciclo de distribución en el que se liberan 2 nuevas versiones por año.

Con la nueva versión 17 Long Time Support (LTS) de la JDK y la versión 18 a la vuelta de la esquina, muchos desarrollos aún están asimilando la anterior versión LTS, la JDK 11.

Se hace patente el hecho que los desarrollos de aplicaciones Java no pueden seguir el ritmo en el que van apareciendo las nuevas características del lenguaje y por eso muchas de ellas tardan en ser de uso general. Una de las consecuencias de este hecho es que los desarrolladores de librerías y frameworks están forzados a esperar hasta que la base de aplicaciones a los que dan soporte se adapta para seguir siendo compatibles con ellas.

Desde la aparición de Java 9 han aparecido mecanismos para paliar este hecho, posibilitando la construcción de artefactos compatibles con múltiples versiones de JDK: Uno de ellos son los Multi-Release JARs (MRJAR), que hace posible integrar en un mismo componente (fichero JAR) diversas versiones de código compatibles con múltiples versiones de JDK.

En este artículo se explica el funcionamiento de los MRJAR así como su integración en un proyecto construido mediante Maven.

Seguir leyendo Multi-Release JARs

OCP11 – Localization & Internationalization

Internationalization is the process by which an application is designed to adapt to multiple regions and languages using the mechanisms provided by the platform, Java Platform in this case. This includes placing text strings in properties files for every supported language, ensure that a proper formatting is used when data is displayed (E.G. numbers and dates), etc. This process is also known as I18N

A localized application is compatible with multiple language and country/region configurations (locales). The localization process is also known as L12N.

Seguir leyendo OCP11 – Localization & Internationalization

Montar unidades de disco externas de forma permanente en Linux

En el siguiente artículo se explica la configuración necesaria en Linux para montar unidades de disco externas automáticamente al iniciar el sistema. Aunque la explicación y ejemplos se han hecho específicamente para sistemas Ubuntu, los mismos pasos también son aplicables a otros sistemas Linux.

El proceso se puede dividir en los siguientes pasos:

  1. Identificar el dispositivo de disco externo en el sistema.
  2. (Opcional) Configurar un grupo que permita restringir el acceso al contenido de las unidades externas.
  3. Modificar la configuración en fstab para añadir las unidades de disco externas a los dispositivos a montar durante el arranque del sistema.

Adicionalmente, se explica cómo habilitar un disco montado como volumen en contenedores Docker cuando se utilizan usuarios con acceso restringido a las ubicaciones de disco.

Seguir leyendo Montar unidades de disco externas de forma permanente en Linux

OCP11 – Migration to a Modular Application

Following the introductory post of Java Platform Module System , also known as JPMS, this post exposes different strategies to migrate applications developed in Java as they can make use of it. This covers the cases where original application is based on a non compatible Java version (< Java 9) or it is compatible (>=Java9) but it was not originally implemented, since the use of this mechanism is fully optional.

Migration strategies

The first step to perform in the migration of an application to the module system is to determine which modules / JAR files are present in an application and what dependencies exists between them. A very useful way to do so is through a hierarchical diagram where these dependencies are represented in a layered way.

This will help giving an overview of the application’s components and which one of them and in which order they can be migrated, identifying those which won’t be able to adapt temporarily or definitively.

The latter case can be given for example in third parties libraries that have stopped offering support and that will hardly become modules. This overview will help determine the migration strategy that will be carried out.

Next, 2 migration mechanisms are exposed that respond to different initial situations.

Seguir leyendo OCP11 – Migration to a Modular Application

Usando Let’s Encrypt y Certbot para generar certificados TLS para nginx

Let’s Encrypt es una autoridad de certificación que proporciona certificados TLS de forma gratuita a todo host que lo necesite para securizar las comunicaciones con éste. Si además se utiliza un sistema NOIP como DuckDNS como servidor DNS, se consigue sin costes adicionales tener un servidor publicado en la red aunque no se disponga de IP fija.

Las únicas contrapartidas que tiene son que el host ha de ser accesible desde internet, lo que deja fuera a hosts dentro de intranets, y que la duración del certificado generado es de 3 meses, lo que implica una renovación constante.

Afortunadamente, el proceso de generación y renovación de los certificados se puede automatizar completamente mediante la herramienta Certbot que tiene soporte para multitud de sistemas operativos y plataformas cloud.

En este post se describe el proceso de generación de certificados para un servidor HTTP nginx ubicado en un sistema Ubuntu 20.04 con IP dinámica gestionada por el servicio DuckDNS.

Seguir leyendo Usando Let’s Encrypt y Certbot para generar certificados TLS para nginx

Construcción de imágenes de Docker multiplataforma con Buildx

Docker proporciona soporte para crear y ejecutar contenedores en una multitud de arquitecturas diferentes, incluyendo x86, ARM, PPC o Mips entre otras. Dado que no siempre es posible crear las imágenes correspondientes de arquitectura equivalente por cuestiones de disponibilidad, comodidad o rendimiento, la alternativa de poder crearlas desde un mismo entorno crea interesantes escenarios, como la posibilidad de tener un servicio de integración continua encargado de la creación de todas las variaciones para las diferentes arquitecturas cubiertas por una aplicación.

En este artículo se expone la configuración de la herramienta buildx de Docker para la creación imágenes de múltiples arquitecturas en un mismo entorno. En el ejemplo incluido se crearán 2 imágenes para las arquitecturas AMD64 y ARM64 en un entorno basado en Ubuntu Linux AMD64.

Seguir leyendo Construcción de imágenes de Docker multiplataforma con Buildx

Restaurar un pendrive bootable en Windows

Habitualmente se utilizan pendrives como soporte para la instalación de sistemas operativos mediante la creación de un pendrive bootable. El problema es que después de hacer esto este queda en un estado que no permite su uso para el almacenamiento de datos porque el proceso de conversión a bootable ha creado múltiples particiones y sistemas como Windows no son capaces de reconocerlo correctamente.

En este post se describe el proceso de restauración de un pendrive bootable a su estado original en Windows.

Seguir leyendo Restaurar un pendrive bootable en Windows

OCP11 – Understanding Modules

Java Platform Module System or JPMS was introduced in Java 9 as a form of encapsulation package.

A module is a group of one or more packages and a module-info.java file that contain its metadata.

In other words it consists in a ‘package of packages‘.

Benefits of using modules:

While using modules in a Java 9+ application is optional, there are a series of benefits from using them:

  • Better access control: Creates a fifth level of class access control that restricts packages to be available to outer code. Packages that are not explicitly exposed through module-info will be not available on modules external code. This is useful for encapsulation that allows to have truly internal packages.

  • Clear dependency management: Application’s dependencies will be specified in module-info.java file. This allows us to clearly identify which are the required modules/libraries.

  • Custom java builds: JPMS allow developers to specify what modules are needed. This makes it possible to create smaller runtime images discarding JRE modules that the application doesn’t need (AWT, JNI, ImageIO…).

  • Performances improvements: Having an static list of required modules and dependencies at start-up allows JVM to reduce load time and memory footprint because it allows the JVM which classes must be loaded from the beginning.

  • Unique package enforcement: A package is allowed to be supplied by only one module. JPMS prevents JAR hell scenarios such as having multiple library versions in the classpath.

The main counterpart is not all libraries have module support and, while it is possible it also makes more difficult to switch to a modular code that depends on this kind of libraries. For example, libraries that make an extensive use of reflection will need an extra configuration step because JPMS cannot identify and load classes at runtime.

Seguir leyendo OCP11 – Understanding Modules

OCP11 – Assertions

Assertion is a mechanism that allows you to check assumptions in the code that help you to confirm the proper functioning of the code and that it is free of errors. The following post shows its basic operations and the situations in which its use is appropriate and in which it is not.

An assertion expression is identified by the assert keyword. Its syntax is as follows:

assert <expression> [: <message>]

Where:

  • expression: Boolean expression that indicates whether the assumption is satisfied or not. In case it is not fulfilled, an AssertionError type error will be thrown.
  • message: Optional. If a message is specified in the expression, it will be attached to the produced AssertionError.

Seguir leyendo OCP11 – Assertions