Vai al contenuto principale
JavaEnterprise

Legacy J2EE: Cosa Ho Imparato Lavorando con i Mainframe

FC

Francesco Careri

Senior Software Engineer

23 dicembre 20254 min lettura
Condividi:

Servlet, JSP, CICS, DB2... tecnologie 'vecchie' che insegnano lezioni preziose sulla robustezza del software enterprise.

Quando ho iniziato a lavorare su sistemi bancari legacy, la mia reazione iniziale è stata: "Ma davvero si usano ancora queste tecnologie?". Servlet, JSP, WebSphere, CICS, mainframe z/OS... sembrava di tornare indietro di 20 anni.

Poi ho capito qualcosa di importante: questi sistemi funzionano. Da decenni. Senza interruzioni.

Il contesto: core banking

Lavoro su sistemi che gestiscono milioni di transazioni al giorno, dove un bug non si risolve semplicemente con "ricarica la pagina" o "spegni e riaccendi", dove un bug significa potenzialmente migliaia di euro persi o conti correnti sballati.

La stack è "antica":

  • J2EE: Servlet e JSP (non Spring, non framework moderni)
  • WebSphere Application Server: il container enterprise di IBM
  • DB2: il database su mainframe
  • CICS: il transaction manager
  • COBOL: sì, ancora COBOL per le logiche core

Lezione 1: La semplicità scala

I framework moderni sono comodi, ma aggiungono layer su layer; una Servlet, invece, è brutalmente semplice:

JAVA
public class TransactionServlet extends HttpServlet {
    
    @Override
    protected void doPost(HttpServletRequest req, 
                          HttpServletResponse resp) {
        String accountId = req.getParameter("accountId");
        BigDecimal amount = new BigDecimal(req.getParameter("amount"));
        
        // Logica di business diretta
        transactionService.transfer(accountId, amount);
        
        // Risposta
        resp.sendRedirect("/success.jsp");
    }
}

Niente dependency injection magica, niente annotation processing, niente proxy dinamici. Il codice fa esattamente quello che vedi.

Quando il sistema deve reggere 10.000 TPS, ogni millisecondo conta.

Lezione 2: La backward compatibility è sacra

In un sistema bancario, non puoi "fare breaking changes", mai! I clienti usano ancora interfacce create nel 2005.

Questo mi ha insegnato a:

  • Pensare alle API come contratti immutabili
  • Versionare tutto
  • Deprecare gradualmente invece di rimuovere
  • Testare la compatibilità all'indietro
💡
Pro tipPrima di modificare un'API, chiediti: "Questo romperà qualcosa che funziona da 15 anni?"

Lezione 3: Il mainframe non è morto

Il mainframe z/OS processa il 90% delle transazioni bancarie mondiali. Non è legacy, è battle-tested.

Caratteristiche che lo rendono imbattibile:

  • Uptime: 99.999% (circa 5 minuti di downtime all'anno)
  • Throughput: milioni di transazioni al secondo
  • ACID garantito: le transazioni sono atomiche, sempre
  • Security: isolamento hardware tra workload

Certo, parliamo di strumenti datati, ma quando devi garantire che un bonifico da 10 milioni non fallisca a metà, vuoi un sistema provato.

Lezione 4: La documentazione è tutto

I sistemi legacy vivono o muoiono in base alla documentazione. Senza di essa, nessuno sa più perché certe scelte sono state fatte.

Ho trovato commenti del tipo:

JAVA
// Non modificare questa logica - bug fix del 2003 
// per gestire il caso XYZ della banca ABC

Questi commenti sono oro. Spiegano il perché, non solo il cosa.

Da allora, documento sempre:

  • Il motivo delle scelte architetturali
  • I workaround per bug esterni
  • Le assunzioni implicite

Lezione 5: Testing in produzione non è un'opzione

In ambiente enterprise, non puoi "deployare e vedere cosa succede". Il testing deve essere:

  • Completo: ogni path, ogni edge case
  • Automatizzato: regression suite che girano a ogni commit
  • Simulato: ambienti di test che replicano la produzione

Ho visto ambienti di test con copie anonimizzate di dati reali, infrastrutture parallele, simulatori di mainframe. Il costo è enorme, ma l'alternativa (bug in produzione) costa di più.

Cosa porto nel mondo moderno

Queste lezioni le applico anche quando sviluppo in Spring Boot o Next.js:

  1. Keep it simple: meno layer = meno bug
  2. Backward compatibility first: pensa sempre a chi usa la tua API
  3. Documenta il perché: il codice dice il cosa, i commenti il perché
  4. Testa come se fossi in banca: ogni bug è un bug in produzione

Conclusione

Lavorare con legacy J2EE non è glamour, ma è educativo, ti insegna cosa significa software che deve funzionare, non software che "sembra figo".

La prossima volta che qualcuno parla di "codice legacy" con disprezzo, ricordagli che quel codice probabilmente gestisce i suoi risparmi.

Lavori anche tu su sistemi legacy? Mi piacerebbe sapere la tua esperienza.

Ti è piaciuto l'articolo? Condividilo!

Condividi:

FC

Francesco Careri

Senior Software Engineer @ ReActive (Gruppo AlmavivA). Scrivo di sviluppo enterprise, security e le cose che imparo lungo il percorso.