Bitsmi Blog

OCP11 - Understanding Modules

04-04-2021 - Antonio Archilla


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.

more…

OCP11 - Local Variable Type Inference

21-03-2021 - Xavier Salvador

Working with Local Variable Type Inference

After Java 10 we can use the keyword var instead of the type for local variables (like the primitive or the reference type) under certain conditions within a code block.

public void whatTypeAmI {
    var name = "Hello";
    var size = 7;
}

The formal name of this feature is local variable type inference but we have to consider two main parts for this feature.

more…

OCP11 - Assertions

13-03-2021 - Antonio Archilla

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.

more…

Error al sincronizar repositorio Git con certificado SSL auto-firmado

26-12-2020 - Antonio Archilla

Descripción del error

El cliente local de Git produce un error de comunicación con el servidor remoto cuando este último tiene un certificado SSL auto-firmado, avisando que la comunicación no es segura.

Error de sincronización en TortoiseGit

Solución

Es posible indicar a Git que confíe en origen remoto y permita trabajar con el repositorio. Esto se debe hacer sólo si se conoce el repositorio remoto y se confía en él.

more…

Monitorización de sistemas mediante Grafana - 1. Instalación

30-08-2020 - Antonio Archilla

El monitorizado de sistemas y aplicaciones proporciona un importante mecanismo para el análisis del funcionamiento de estos, permitiendo anticipar situaciones futuras o alertando de problemas que de otra manera quedarían ocultos o difícilmente identificables.

Grafana es una solución que permite el monitorizado completo de sistemas y aplicaciones mediante la recolección de métricas y logs desde multitud de fuentes de datos.

El stack de Grafana cubre todas las fases desde la recolección del dato hasta su visualización gracias a los diferentes componentes que la componen:

  • Prometheus: Encargado de la recolección de métricas. Utiliza un modelo Pull de recolección por el cual es el propio Prometheus quien requiere los datos al sistema monitorizado, que debe disponer de un endpoint al cual se pueda conectar. El stack dispone del componente Node-Exporter que proporciona acceso a multitud de métricas al instalarlo en el sistema objeto (CPU, uso de memoria, disco, red…). Es apropiado para la recolección de datos en intervalos de tiempo programados, aunque también proporciona mecanismos para su uso en ejecuciones batch u one-shot.
  • Graphite: Encargado de la recolección de métricas. A diferencia de Prometheus, funciona mediante un modelo Push, por lo que es el propio sistema objeto de la monitorización el encargado de enviar los datos a Graphite a través de un endpoint que este provee.
  • Loki: Encargado de la recolección de trazas de log. Como Graphite utiliza un modelo Push para publicar los datos en Loki pero afortunadamente en este caso el componente Promtail facilita la tarea encargándose de extraer las trazas de log y dándoles el formato apropiado para su publicación.
  • Grafana: Permite la visualización y explotación de métricas y trazas de log accesibles mediante la conexión a diversas fuentes de datos, entre las que se incluyen los mencionados Prometheus, Graphite y Loki, pero que también incluyen plug-ins para la conexión a servicios en la nube como AWS CloudWatch, Azure Monitor, Google Cloud Monitoring, bases de datos relacionales (MySQL, PostgreSQL, MSSSQL…), NoSQL (ElasticSearch, OpenTSBD…) o sistemas de recolección de trazas de log (Jaeger, Zipkin…).

Este es el inicio de una serie de artículos donde se propondrá la construcción de un sistema centralizado de monitorizado de sistemas y aplicaciones con capacidad de análisis de métricas y trazas de log.

more…

Uso de toolchains Maven

22-07-2020 - Antonio Archilla

Un toolchain en Maven es un mecanismo que permite a los plugins que se ejecutan durante las diferentes fases de construcción de un artefacto acceder a un conjunto de herramientas predefinido de forma general. De esta forma se evita que cada uno de ellos deba definir la composición y ubicación de este conjunto de herramientas y se homogeniza para que en todos los casos sea la misma. Habitualmente este mecanismo se utiliza para proporcionar la especificación de la jdk que será utilizada en el proceso de construcción en los casos que se deba utilizar una implementación diferente a utilizada para ejecutar el propio Maven, pero existe la posibilidad de construir toolchains personalizadas. El uso de las diferentes tipologías de toolchains debe estar soportado por los plugins utilizados. Afortunadamente, plugins básicos como maven-compiler-plugin, maven-javadoc-plugin, maven-surefire-plugin, entre otros, están diseñados para dar soporte a toolchains de tipo jdk, lo que permite definir procesos de construcción para diferentes implementaciones de jdk sin problema.

En este artículo se explicarán los pasos necesarios para definir una toolchain en la instalación local de Maven y de como utilizarla en la construcción de un artefacto.

more…

Inclusión de recursos zip como dependencias Maven

11-07-2020 - Antonio Archilla

Maven es una herramienta altamente utilizada en el ecosistema Java para gestionar los módulos y librerías que componen una aplicación, ya sea directamente a través del própio Maven o de otras herramientas, como Gradle, SBT, Ivy, etc., que utilizan los repositorios de este para obtener dichos recursos. A parte de artefactos de tipo jar, war o definiciones pom, Maven también permite gestionar empaquetados de tipo zip en los repositorios. Esto permite gestionar dependencias a recursos estáticos comunes en varios proyectos Maven sin necesidad de duplicarlos en cada uno de ellos, facilitando así su mantenimiento y actualización. En este artículo se muestra de forma genérica como incluir recursos comunes en un proyecto Maven a través de una dependencia y un caso concreto de como aprovechar esto para gestionar paquetes npm de forma local sin tener que hacer uso de un repositorio npm remotoé

more…

Sdkman - The Software Development Kit Manager

02-07-2020 - Xavier Salvador

SDKMAN! es una herramienta para manejar versiones paralelas de múltiples Kits de Desarrollo de Software en la mayoría de los sistemas basados en Unix. En este post, aunque originalmente está pensando para sistemas Unix veremos su utilización mediante Java en su version 11 en entornos Windows, concretamente con Windows 10.

Proporciona una conveniente Interfaz de Línea de Comando (CLI) y API para instalar, cambiar, eliminar y listar candidatos.

Anteriormente conocido como GVM el Groovy enVironment Manager, fue inspirado por las muy útiles herramientas RVM y rbenv, utilizadas en general por la comunidad Ruby.

Para poder ser utilizando en entornos Windows es neceasario realizar una refacorización del código fuente del script bash original.

Existe una sección (install) en la propia página web dónde se indican los pasos a seguir para su instalación y utilización en entornos Windows.

Para mostrar su uso en Windows 10 se utiliza el Shell de Git Bash mediante el uso de este script get_sdkman_io (ya preparado para funcionar en entornos Windows).

more…

Migrar un repositorio de código Mercurial a Git

23-06-2020 - Antonio Archilla

En el siguiente artículo se expone el proceso de migración de un repositorio de código gestionado por Mercurial SCM a Git SCM. El proceso se puede llevar a cabo en entornos Linux / Unix o Windows utilizando la consola de comandos Git Bash y adicionalmente herramientas gráficas como Tortoise Hg y Tortoise Git para verificar los resultados.

more…

Incidencias de class loader

13-06-2020 - Antonio Archilla

En el lenguaje de programación Java, para identificar una clase especifica se tienen en cuenta principalmente 2 cosas: El nombre del package en el que se encuentra y el propio nombre de la clase. Mediante estos 2 valores, el sistema de class loaders de la máquina virtual identifica y carga la diferentes clases según sean necesarias durante la ejecución de una aplicación. Este mecanismo tiene un problema bastante conocido cuando más de una clase con el mismo nombre y package se encuentran contenidas en ficheros jar o directorios diferentes. Este fenómeno es una de las variantes del denominado Jar Hell que en este caso concreto consiste en que no todas las clases pertenecientes al mismo package que son cargadas por el sistema de class loaders proceden de la misma ubicación (directorio de clases o fichero jar), lo que puede ocasionar incompatibilidades o errores inesperados si estas no pertenecen a la misma versión de código.

La especificación de Java define un mecanismo denominado package sealing que puede aplicarse opcionalmente para garantizar que todas las clases pertenecientes a un mismo package son cargadas desde el mismo fichero jar. En caso de que la máquina virtual en un momento determinado intente cargar una clase de un package definido como sellado y esta pertenezca a un fichero jar distinto al del resto de clases del mismo package ya cargadas, se producirá un error advirtiendo de ello. Desafortunadamente, no todas las librerías hacen uso de este mecanismo, por lo que a veces es complicado ver si esta puede ser la causa de un error determinado.

En este artículo se exponen diferentes casuísticas derivadas de este fenómeno y de como identificar la causa de un error de este tipo para poder solucionarlo.

more…

results matching ""

    No results matching ""