Mostrando entradas con la etiqueta jvm. Mostrar todas las entradas
Mostrando entradas con la etiqueta jvm. Mostrar todas las entradas

viernes, 22 de mayo de 2026

Lenguajes que han muerto y que no estabas enterado: el caso de Ceylon

Ceylon fue un lenguaje de programación que prometía algo que otros han intentado sin éxito: ser el verdadero sucesor de Java.

Tampoco lo logró.

Fue creado por Gavin King, el mismo creador de Hibernate, y "lanzado" el año 2011.

Digo lanzado, porque las versiones "lanzadas" nunca llegaban a ser estables. Pues cada versión lanzada (valga la redundancia) afectaban al lenguaje y que confundían al pobre ingenuo que se acercaba al lenguaje con el objetivo de aprendera a usarlo.

Lo que aprendías en una versión lo debías desaprender en la nueva... y así sucesivamente.

Actualmente el lenguaje se encuentra archivado por la Fundación Eclipse: https://projects.eclipse.org/projects/technology.ceylon

Ceylon posee (¿debería hablar en presente?) una sintaxis similar a la de Java y C#. Quienes venían de esos lenguajes podían adentrase al lenguaje sin tanto problema.

Características principales:

  • Orientado a objetos. 
  • Soporte a la meta programación. 
  • Imperativo. 
  • De tipado estático. 
  • Soporte la construcción modular. 
  • Multiplataforma.
  • Además de tener su propio IDE (plugin para Eclipse).

Un vistazo a Ceylon

El clásico "Hola, mundo" en Ceylon.

holamundo.ceylon

shared void run(){
    print("Hola, mundo en Ceylon");
}

No mencionaremos cómo compilarlo y ejecutarlo ya que, como mencionamos, cada versión del lenguaje cambiaba todo. Desde cómo comentar código hasta como construir el ejecutable.

Entrevista sobre Ceylon a Gavin King

El tema central de la entrevista fue sobre el nacimiento y propósito del lenguaje Ceylon.

Gavin King comentó que, tras años trabajando con Java, detectó limitaciones en su sistema de módulos y en la coherencia del lenguaje. Ceylon surge para ofrecer una sintaxis más moderna y un modelo de tipos más seguro.

Observemos esta tabla comparativa entre Ceylon y Java.

Comparativa Ceylon y Java

Aspecto Java Ceylon
Origen y creador Desarrollado por Sun Microsystems (1995), liderado por James Gosling. Creado por Gavin King en Red Hat (2011).
Objetivo principal Lenguaje de propósito general para aplicaciones empresariales, móviles y web. Modernizar el ecosistema Java con un lenguaje más coherente, modular y expresivo.
Paradigma Orientado a objetos con soporte funcional desde Java 8. Mixto: orientado a objetos y funcional, con fuerte énfasis en modularidad y claridad semántica.
Tipado Estático y fuerte, pero con inferencia limitada. Estático y fuerte, con inferencia de tipos avanzada y tipos unión/intersección.
Sistema de módulos Introducido en Java 9 (Jigsaw), pero complejo y poco intuitivo. Sistema de módulos nativo desde el inicio, simple y coherente.
Interoperabilidad Corre sobre la JVM y puede interactuar con otros lenguajes del ecosistema. Compila para JVM y JavaScript, permitiendo ejecución en servidor y navegador.
Sintaxis Verbosa y orientada a clases. Más concisa, con sintaxis moderna y expresiva.
Herramientas Ecosistema maduro (IDE, frameworks, librerías). IDE propio con compilador, gestor de módulos y documentación integrada.
Enfoque de diseño Prioriza compatibilidad y estabilidad. Prioriza legibilidad, coherencia y seguridad de tipos.
Casos de uso Aplicaciones empresariales, Android, sistemas financieros. Aplicaciones modulares, APIs, servicios distribuidos y código multiplataforma.

Ceylon representó su intento de modernizar el paradigma Java, ofreciendo una alternativa más elegante y coherente para proyectos grandes y distribuidos. Fue una lástima que no lo haya logrado.

Enlaces:

https://en.wikipedia.org/wiki/Ceylon_(programming_language)
https://swizec.com/blog/cool-thing-thursday-ceylon/
https://codemonkeyjunior.blogspot.com/2012/04/ceylon-funcionando-correctamente.html
https://projects.eclipse.org/projects/technology.ceylon
https://web.mit.edu/ceylon_v1.3.3/ceylon-1.3.3/doc/en/spec/html_single/#:~:text=Ceylon%20is%20a%20general%2Dpurpose,oriented%2C%20and%20higher%2Dorder.


domingo, 15 de febrero de 2026

Hablemos de GraalVM: una JVM políglota

GraalVM es una herramienta que nos ayuda a compilar y ejecutar aplicaciones poliglota con alto rendimiento. Emplear esta herramienta nos permite mejorar la velocidad de ejecución de un programa y reducir el consumo de memoria.

Soporta múltiples lenguajes de programación como: Java, Javascript, Python, Ruby, R, etc.

Se considera una opción "mejorada" de la JVM tradicional.

Con GraalVM tenemos el concepto de Native Images (imágenes nativas), lo que consiste en la creación de ejecutables nativos a partir de aplicaciones Java; permitiendo un arranque mucho más rápido y menor uso de memoria.

GraalVM y la JVM

Observemos la siguiente tabla comparativa entre GraalVM y la JVM.

Comparativa: GraalVM vs JVM HotSpot
Aspecto GraalVM JVM HotSpot
Arquitectura Diseño modular con compilador Graal y soporte poliglota. Optimizada para Java, con JIT clásico y soporte limitado a la JVM.
Lenguajes soportados Java, JavaScript, Python, Ruby, R, LLVM bitcode, entre otros. Principalmente Java y lenguajes basados en la JVM (Scala, Kotlin, Groovy).
Rendimiento Mejor optimización en tiempo de ejecución, menor consumo de memoria. Buen rendimiento para Java, pero menos eficiente en arranque y memoria.
Native Images Permite compilar aplicaciones a ejecutables nativos con arranque rápido. No soporta generación de binarios nativos directamente.
Tiempo de arranque Muy rápido gracias a Native Image, ideal para microservicios. Más lento, requiere inicialización completa de la JVM.
Casos de uso Microservicios, aplicaciones poliglota, optimización en la nube. Aplicaciones Java tradicionales, sistemas empresariales robustos.
Interoperabilidad Alta, permite mezclar lenguajes en una misma aplicación. Limitada a lenguajes JVM.

Para instalarlo deberás ir a este sitio: https://www.graalvm.org/downloads/

En tu sistema deberás crear la variable de JAVA_HOME y GRAALVM_HOME apuntando al directorio.

Abre una terminal y teclea:

$ java --version

Salida:

java 25.0.2 2026-01-20 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 25.0.2+10.1 (build 25.0.2+10-LTS-jvmci-b01)
Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 25.0.2+10.1 (build 25.0.2+10-LTS-jvmci-b01, mixed mode, sharing)

Ejemplo 1. El clásico programa de "Hola, mundo".

HolaMundo.java

public class HolaMundo{
   public static void main(String[] args){
      String mundo = new String("mundo!!");
      System.out.printf("Hola, %s\n",mundo);
   }
}

Compilamos:

$ javac HolaMundo.java

Ejecutamos:

$ java HolaMundo

Salida:

Hola, mundo!!

Ahora creemos una imagen nativa.

$ native-image HolaMundo

El proceso de creación de la imagen nativa puede tardar un tiempo considerable.

Si todo va bien, tendremos un ejecutable llamado holamundo.exe.

Podemos crear un batch con el siguiente contenido:

ejecutable.bat

@echo off
echo Start Time: %time%
holamundo.exe
echo End Time: %time%

Lo ejecutamos y observamos el tiempo que tarda en ejecutarse:

Start Time: 10:55:17.00
Hola, mundo!!
End Time: 10:55:17.04

Ahora modifiquemos el bat:

ejecutable.bat

@echo off
echo Start Time: %time%
java HolaMundo
echo End Time: %time%

Lo ejecutamos y observamos la salida:

Start Time: 10:58:58.59
Hola, mundo!!
End Time: 10:58:58.92

La ejecución del .exe apenas duró unos 4 milisegundos. Mientras que el .class tuvo una duración de 33 milisegundos.

GraalVM puede ser una herramienta de gran ayuda para desarrolladores backend, pues permite optimizar el funcionamiento de las APIs y mejorar el consumo de recursos de memoria. Continuaremos con este tema en próximas entregas.

Enlaces:

https://www.graalvm.org/
https://csantanapr.medium.com/book-review-supercharge-your-applications-with-graalvm-9f330ec38c07
https://github.com/graalvm/graalvm-ce-builds/releases/

jueves, 1 de enero de 2026

Un vistazo a JakartaEE

Los que vienen programando en Java algún tiempo sabrán que trabajar con este lenguaje tiene sus pros y contras. No todo ha sido fácil, pero tampoco algo imposible.

Crear aplicaciones web con Servlets y JSP con sus configuraciones tediosas le complicaban la vida a más de uno. Ni se diga con los odiosos EJB y el uso de servidores como JBoss, Glassfish, etc.

Después vino Spring Framework con su Spring Boot que facilitó la vida a los desarrolladores web. Pues está herramienta se encargaba de lo complicado y dejaba al programador enfocarse en una sola cosa: su código.

Jakarta EE es la evolución directa de Java EE, el Java empresarial que muchos sufrían en antaño. La documentación oficial nos dice:

  • Es conjunto de especificaciones que se utiliza para crear productos y frameworks Java para aplicaciones empresariales a gran escala. 
  • Impulsa sistemas como bancos, sitios de comercio electrónico y plataformas empresariales. 
  • Se basa en Java SE con API adicionales para desarrollo web, acceso a bases de datos, mensajería y seguridad.

Características principales:

  • Tecnologías web: Servlets, JSP, JSF.
  • Lógica de negocio: EJB (Enterprise JavaBeans).
  • Persistencia de datos: JPA Mensajería: JMS Seguridad y transacciones.

Jakarta EE se ejecuta en servidores de aplicaciones como WildFly, GlassFish y Payara, que gestionan la configuración, la escalabilidad y el ciclo de vida.

Jakarta EE Get Started

Para los que vienen de Spring Boot este sitio se les hará familiar:

https://start.jakarta.ee/

Pues es similar al sitio https://start.spring.io/, el cual nos ayuda a crear un proyecto listo para usar y que nos evita las odiosas y tediosas configuraciones.

La documentación oficial nos dice:

"Jakarta EE Get Started crea rápidamente una aplicación Jakarta EE lista para usar, eliminando las complicaciones habituales de configuración. En lugar de empezar con una carpeta vacía, obtienes un proyecto completo y funcional, listo para construir, como si empezaras con un set de LEGO preconstruido que puedes personalizar al instante. Incluye la configuración correcta de Maven, estructuras de directorios estándar y código de ejemplo que demuestra los conceptos clave de Jakarta EE".

En pocas palabras, Jakarta EE aprendió lo que no hizo Java EE.

Al entrar al sitio podemos ver un formulario similar al de Spring Boot Initializer:

Comencemos con un proyecto sencillo.

Descargamos el archivo ZIP y lo descomprimimos en algún directorio:

$ cd jakartaee-hello-world

Veamos el contenido del proyecto:

src\main\java\org\eclipse\jakarta\hello\Hello.java
src\main\java\org\eclipse\jakarta\hello\HelloApplication.java
src\main\java\org\eclipse\jakarta\hello\HelloWorldResource.java

Hello.java

package org.eclipse.jakarta.hello;

public class Hello {

    private String name;

    public Hello(String name) {
        this.name = name;
    }

    public String getHello(){
        return name;
    }
}

La cual es una clase o un bean.

HelloApplication.java

package org.eclipse.jakarta.hello;

import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.ApplicationPath;

@ApplicationPath("rest")
public class HelloApplication extends Application {
    
}

Similar a la aplicación tipo Spring Boot.

HelloWorldResource.java

package org.eclipse.jakarta.hello;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

@Path("hello")
public class HelloWorldResource {

    @GET
    @Produces({ MediaType.APPLICATION_JSON })
    public Hello hello(@QueryParam("name") String name) {
        if ((name == null) || name.trim().isEmpty()) {
            name = "world";
        }

        return new Hello(name);
    }
}

La cual es una clase similar a un Controller en Spring Boot.

En teoría, es una aplicación funcional. Comprobemos esto.

Compilamos el proyecto:

$ mvn clean install

Si todo va bien, nuestra aplicación estará compilada y se habrá creado el WAR en la carpeta generada llamada target.

Ahora será necesario descargar e instalar Glassfish:

https://glassfish.org/download

Una vez descargado y descomprimido en algún directorio en específico, debemos crear la variable de entorno para poder ejecutarlo:

C:\glassfish7\bin

Ahora iniciaremos el servidor Glassfish:

$ asadmin start-domain

Abriremos el navegador en la ruta: http://localhost:4848

Entraremos al administrador de Glassfish. Vamos a Application/Deploy. Seleccionamos nuestro WAR y damos ok. Ya podemos ejecutar la aplicación.

Abrimos el navegador en la ruta: http://localhost:8080/jakartaee-hello-world/rest/hello?name=Thomas_Muller

Salida:

¡Hemos creado nuestra primera aplicación con Jakarta EE!

Detenemos el servidor Glassfish:

$ asadmin stop-domain

Actualización:

Si no quieres instalar Glassfish, puedes ejecutar este comando:

$ mvnw clean package wildfly:run

Deberás descargar la última versión de Wildfly:

https://www.wildfly.org/downloads/

Descomprimir el ZIP y colocarlo en algún directorio (C:\wildfly).

Además de editar el pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.eclipse</groupId>
    <artifactId>jakartaee-hello-world</artifactId>
    <version>0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>jakartaee-hello-world</name>
    <description>
        Simple Jakarta EE 11 application running on WildFly.
    </description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
        <maven.compiler.release>21</maven.compiler.release>
        <jakartaee-api.version>11.0.0-RC1</jakartaee-api.version>
        <compiler-plugin.version>3.13.0</compiler-plugin.version>
        <war-plugin.version>3.4.0</war-plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-core-api</artifactId>
            <version>${jakartaee-api.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>jakartaee-hello-world</finalName>
        <plugins>
            
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>4.2.0.Final</version>
                <configuration>
                    <jbossHome>C:\wildfly</jbossHome>
                    <startupTimeout>180</startupTimeout>
                </configuration>
            </plugin>

            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
            </plugin>

           
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>${war-plugin.version}</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project> 

Ya podrás desplegarlo sin la necesidad de iniciar Glassfish.

Feliz año 2026

Este es el post número 400 del blog.😉

Enlaces:

https://jakarta.ee/
https://www.linkedin.com/pulse/java-explained-servlets-jsp-jakarta-ee-rohit-bhosale-r2gzf/?trackingId=XgJjdE8PQombg7SZoMmx9Q%3D%3D
https://jakarta.ee/learn/starter-guides/a-comprehensive-beginners-guide-to-the-get-started/

sábado, 27 de diciembre de 2025

Ballerina: una comparativa con Rust

Como mencionamos en la entrega anterior, Ballerina es un lenguaje de programación en crecimiento. No posee una comunidad tan grande como otros lenguajes (Java, C#, C/C++, Python, etc.), pero así empiezan todos. Ballerina junto otros lenguajes como Go y Rust han cobrado cierto interés en el mundo de la programación, servicios Cloud, servicios REST y hasta la I.A.

En esta ocasión haremos una comparativa con Rust, un lenguaje de programación que tiene inspiración en lenguajes como C y C++, tomando lo mejor de ellos y descartando lo que no es necesario y Ballerina, un lenguaje que ha cobrado importancia en el desarrollo en la nube. Ambos lenguajes han aprendido de los mejores e incluso han ido superándolos incluso en velocidad y rendimiento.

Ballerina y Rust son lenguajes muy distintos: Ballerina está orientado a integración y microservicios, mientras que Rust se centra en sistemas de alto rendimiento y seguridad de memoria.

Veamos una tabla comparativa:

Comparativa: Ballerina vs Rust
Aspecto Ballerina Rust
Paradigmas Multiparadigma con foco en integración, concurrencia y servicios distribuidos; código con visualización de flujos y llamadas. Multiparadigma (imperativo y funcional) orientado a sistemas, control de bajo nivel y seguridad de memoria.
Casos de uso Integración de APIs, microservicios, orquestación de endpoints, aplicaciones cloud-native y seguridad en comunicaciones. Sistemas operativos, motores de juegos, programación embebida, CLI y servicios de alto rendimiento.
Compilación y ejecución Compila con bal build; ejecuta con bal run archivo.bal. Soporte integrado para Docker/Kubernetes. Compila con rustc archivo.rs; ejecuta con ./archivo. En proyectos se usa Cargo (cargo build, cargo run).
Tipos de variables Tipado estático: int, float, boolean, string; estructurados: record, map, array, table. Tipado estático con inferencia: primitivos (i32, f64, bool, char) y avanzados (struct, enum, tuple).
Estructuras de control if, while, foreach, match; concurrencia con workers y fork/join. if, loop, while, for, match con patrones; concurrencia segura con async/await y ownership.
Estructuras de datos record (tipo estructurado), map, array, table. struct, enum, tuple, array, Vec<T>, HashMap<K,V>.
Concurrencia Modelo de trabajadores, transacciones y flujos de integración; primitivas para servicios distribuidos. Seguridad de datos en concurrencia mediante ownership, borrowing y tipos como Arc/Mutex.
Ecosistema Enfocado en integración (HTTP, gRPC, GraphQL, Kafka) con librerías estándar orientadas a servicios. Amplio ecosistema de crates para sistemas, redes, WebAssembly, embebidos y desarrollo multiplataforma.
Curva de aprendizaje Suave para integraciones y microservicios; diseño opinado para flujos de red. Pronunciada por el ownership y el borrow checker; recompensa con rendimiento y seguridad.

Puntos clave entre Ballerina y Rust

Ambos lenguajes tienen similitudes y diferencias, aquí los puntos claves:

  • Enfoque distinto: Ballerina es un lenguaje de integración; Rust es un lenguaje de sistemas. 
  • Compilación: Rust ofrece control de bajo nivel y optimización; Ballerina simplifica despliegues en entornos distribuidos. 
  • Datos y control: Rust tiene estructuras más ricas y flexibles; Ballerina prioriza simplicidad y seguridad en datos de red. 
  • Concurrencia: Ambos soportan concurrencia, pero Rust lo hace con un modelo de ownership y Ballerina con workers y diagramas visuales.

Ejemplo 1. Crear un sencillo "Hola, mundo" en Ballerina y Rust. Esto nos servirá para ver cómo se compila y ejecuta un programa en cada lenguaje.

Empecemos con Ballerina. Compilaremos y ejecutaremos un archivo llamado holamundo.bal:

import ballerina/io;

public function main(string... args) {
    io:println("\t Hola, mundo en Ballerina");
}

Compilamos y ejecutamos:

$ bal run holamundo.bal

El código se compilará y se ejecutará en la terminal, la salida será:

Compiling source
        holamundo.bal

Running executable

         Hola, mundo en Ballerina

Ahora con Rust, compilaremos y ejecutaremos el archivo holamundo.rs:

fn main() {
    println!("\t Hola mundo en Rust");
}

Compilamos:

$ rustc holamundo.rs

Se creará un ejecutable:

$ holamundo.exe

Salida:

         Hola mundo en Rust

¿Qué podemos notar?

  • Ambos lenguajes son compilados. 
  • Ballerina es más similar Java, es dependiente de la JVM y genera bytecodes
  • Rust es más similar a C/C++, genera ejecutables nativos (*exe). 
  • La extensión de un programa Ballerina es *bal.
  • La extensión de un programa Rust es *rs.

Tipos de datos en Ballerina y Rust

Como mencioanmos, ambos lenguajes son compilados. También comparten la característica de ser de tipado estático. Eso quiere decir que debes especificar el tipo de datos a usar. No como lenguajes como Python o Ruby donde "una variable es una variable".

Tipos de datos en Ballerina vs Rust
Categoría Ballerina Rust
Primitivos numéricos int, float, decimal i8, i16, i32, i64, u8, u16, u32, u64, f32, f64
Booleanos boolean bool
Texto y caracteres string char, String (tipo de colección)
Compuestos record, map, array, table struct, enum, tuple, array, Vec<T>, HashMap<K,V>
Especiales nil (valor nulo), error, any Option<T>, Result<T,E>, unit (())
Concurrencia Workers y canales integrados para paso de mensajes Tipos seguros para concurrencia: Arc, Mutex, RwLock

Ejemplo 2. Crear un programa en ambos lenguajes con el objetivo de ver los tipos de datos en cada lenguaje.

En Ballerina:

tipos.bal

import ballerina/io;

type Persona record {|
    string nombre;
    int edad;
|};

enum Estado {
    ACTIVO,
    INACTIVO
}

public function main() {
    int edad = 30;
    float altura = 1.75;
    boolean activo = true;
    string inicial = "C"; // no existe 'char'
    string nombre = "Thomas Muller.";

    int[] numeros = [1, 2, 3, 4];
    [int, float, string] tupla = [25, 1.80, "Ana"];

    Persona p = { nombre: "Luis", edad: 40 };
    Estado estado = ACTIVO;

    map<string> capitales = { "MX": "Ciudad de México", "US": "Washington" };

    int|error resultado = 10; // Result
    float? opcion = 3.14;     // Option

    
    int contador = 0;
    fork {
        worker w1 {
            int local = contador;
            local += 1;
            io:println("Worker 1 contador: " , local.toString());
        }
        worker w2 {
            int local = contador;
            local += 1;
            io:println("Worker 2 contador: " , local.toString());
        }
    }

	io:println("Nombre: " + nombre + ", Edad: " + edad.toString());
    string capitalMX = capitales["MX"] ?: "Desconocido";
    io:println("Capital de MX: " + capitalMX);
    io:println("Persona: " + p.toString());
    io:println("Contador final (simulado): " + contador.toString());
}

Compilamos y ejecutamos:

$ bal run tipos.bal

Salida:

Nombre: Thomas Muller., Edad: 30
Capital de MX: Ciudad de México
Persona: {"nombre":"Luis","edad":40}
Contador final (simulado): 0
Worker 2 contador: 1
Worker 1 contador: 1

En Rust:

tipos.rs

fn main() {
    
    let edad: i32 = 30;
    let altura: f64 = 1.75;
    let activo: bool = true;
    let inicial: char = 'C';
    let nombre: String = String::from("Thomas Muller.");

    
    let numeros: [i32; 4] = [1, 2, 3, 4];
    let tupla: (i32, f64, &str) = (25, 1.80, "Ana");

    struct Persona {
        nombre: String,
        edad: i32,
    }
    let p = Persona { nombre: String::from("Luis"), edad: 40 };

    enum Estado {
        Activo,
        Inactivo,
    }
    let estado = Estado::Activo;

    use std::collections::HashMap;
    let mut capitales = HashMap::new();
    capitales.insert("MX", "Ciudad de México");
    capitales.insert("US", "Washington");

    let resultado: Result<i32, &str> = Ok(10);
    let opcion: Option<f64> = Some(3.14);

   
    use std::sync::{Arc, Mutex};
    use std::thread;

    let contador = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..2 {
        let contador = Arc::clone(&contador);
        let handle = thread::spawn(move || {
            let mut num = contador.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for h in handles {
        h.join().unwrap();
    }

    println!("Nombre: {}, Edad: {}", nombre, edad);
    println!("Capital de MX: {}", capitales["MX"]);
    println!("Persona: {} ({})", p.nombre, p.edad);
    println!("Contador final: {}", *contador.lock().unwrap());
}

Compilamos:

$ rustc tipos.rs

Se creará un ejecutable:

$ tipos.exe

Salida:

Nombre: Thomas Muller., Edad: 30
Capital de MX: Ciudad de México
Persona: Luis (40)
Contador final: 2

Podríamos continuar con las comparaciones con estructuras de datos, acceso a archivos, acceso a base de datos y hasta servicios REST. Sin embargo, lo haremos en otra ocasión.

Conclusiones

Es importante hacer notar que:

  • Rust: curva de aprendizaje más pronunciada por su sistema de ownership y borrow checker
  • Ballerina: menos comunidad y ecosistema que Rust; puede ser limitante fuera del ámbito de integración.

Ambos lenguajes tienen un propósito, resuelven problemas distintos. No son competidores.

Enlaces:

https://rust-lang.org/
https://ballerina.io/
https://www.infoq.com/articles/ballerina-integration-tutorial-part-2/
https://www.infoq.com/articles/ballerina-microservices-language-part-1/



sábado, 20 de septiembre de 2025

Conociendo Akka

¿Qué es Akka?

Es una plataforma (o framework) inspirado por Erlang que busca el desarrollo simple de aplicaciones escalables y multihilo.

Permite crear servicios transaccionales, duraderos y en tiempo real que distribuyen lógica y datos de forma conjunta.

Se puede usar con Java o Scala distintivamente.

Donde la concurrencia no se basa en la memoria compartida entre varios hilos y los métodos de sincronización (como en Java) sino que está basado en el sistema Actor-Modelo para ello.

Donde un actor es un objeto con el que puedes interactuar enviándole mensajes: cada actor puede procesar mensajes y enviarle mensajes a otros actores. Además de que los actores pueden tener un estado interno pero la comunicación sólo ocurre pasando mensajes y nunca a través de estructuras compartidas.

Donde una máquina virtual JVM pueden correr millones de actores a la vez construyendo una jerarquía padre (supervisor)-hijo con los padres monitorizando el comportamietno de los hijos. Permitiendo una forma sencilla splitear nuestros actores entre varios nodos de un cluster.

Un sencillo ejemplo con Akka

Iniciaremos creando unproyecto con Maven:

$ mvn archetype:generate -DgroupId=com.codemonkey -DartifactId=akka-hello-world -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Nos ubicamos en el directorio creado:

$ cd akka-hello-world

Editamos el archivo pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.codemonkey</groupId>
    <artifactId>akka-hello-world</artifactId>
    <version>1.0</version>
    <dependencies>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-actor-typed_2.13</artifactId>
            <version>2.6.21</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.12.1</version>
                <configuration>
                    <source>21</source>
                    <target>21</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Construimos el proyecto:

$ mvn clean install -X

Observemos la clase principal.

HelloWorld.java

package com.codemoneky;

import akka.actor.typed.ActorSystem;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.AbstractBehavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;

public class HelloWorld extends AbstractBehavior<String> {

    public static Behavior<String> create() {
        return Behaviors.setup(HelloWorld::new);
    }

    private HelloWorld(ActorContext<String> context) {
        super(context);
    }

    @Override
    public Receive<String> createReceive() {
        return newReceiveBuilder()
                .onMessage(String.class, this::onMessage)
                .build();
    }

    private Behavior<String> onMessage(String message) {
        System.out.println("Mensaje recibido: " + message);
        return this;
    }

    public static void main(String[] args) {
        ActorSystem<String> system = ActorSystem.create(HelloWorld.create(), "HelloWorldSystem");
        system.tell("Hola Mundo");
        // Termina el sistema después de enviar el mensaje
        system.terminate();
    }
}

Esta clase mostrará un mensaje "Hola Mundo".

Compilamos el proyecto:

$ mvn compile

Ejecutamos:

$ mvn exec:java -Dexec.mainClass="com.codemonkey.HelloWorld"

¡Hemos creado nuestra primera aplicación con Akka!

En pocas palabras, Akka sirve para construir aplicaciones concurrentes, distribuidas y escalables en Java o Scala. Basado en el modelo de actores, facilita la gestión de procesos paralelos, comunicación asíncrona y sistemas tolerantes a fallos. Es ideal para aplicaciones en tiempo real, como chats, streaming, o microservicios, ya que simplifica la concurrencia y permite manejar grandes volúmenes de datos o usuarios de forma eficiente.

Enlaces:

https://akka.io/
https://emanuelpeg.blogspot.com/2022/09/por-que-usar-akka.html
https://www.bairesdev.com/blog/introduction-to-akka-an-open-source-library/
https://scalac.io/technologies/akka/
https://unpocodejava.com/2013/02/19/que-es-akka/


Jai un lenguaje de programación inspirado en C++

Hoy hablaremos de un nuevo lenguaje de programación llamado Jai . Se trata de un lenguaje de programación que está desarrolland...

Etiquetas

Archivo del blog