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:

  • Keep it simple: meno layer = meno bug
  • Backward compatibility first: pensa sempre a chi usa la tua API
  • Documenta il perché: il codice dice il cosa, i commenti il perché
  • 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.