Ogni sistema JD Edwards che ha qualche anno di vita porta con sé una domanda senza risposta facile: quanti degli oggetti custom sviluppati nel tempo sono ancora sostanzialmente identici allo standard Oracle da cui derivano, e quanti si sono evoluti fino a diventare qualcosa di completamente diverso? È una domanda che diventa urgente quando si affronta un upgrade, una migrazione o semplicemente un audit della customizzazione. La risposta, nella maggior parte dei casi, non esiste — perché nessuno l'ha mai cercata sistematicamente. In questo articolo descrivo come affronto questo problema nel mio lavoro, e lo strumento proprietario che ho sviluppato per risolverlo

Cos'è JD Edwards e perché questo problema esiste

JD Edwards (comunemente noto come JDE) è un ERP enterprise sviluppato da Oracle, molto diffuso in aziende manifatturiere, di distribuzione e nei settori oil & gas e construction. Come tutti i sistemi ERP di fascia alta, JDE offre un set di oggetti "standard" — applicazioni, report, business function e business view — che coprono i processi aziendali di base.

La realtà operativa, però, è che nessuna azienda usa JDE puro. Ogni implementazione porta con sé decine, se non centinaia, di customizzazioni: oggetti standard che vengono copiati, rinominati con un prefisso custom (tipicamente nel range 55–69 secondo la nomenclatura JDE), e modificati per adattarsi ai processi specifici del cliente.

Questo crea un problema molto concreto: come si fa a sapere, anni dopo, quale standard si trova alla base di un custom? La tracciabilità si perde. I programmatori cambiano. La documentazione invecchia o non esiste.

Il problema tecnico: trovare l'origine di un oggetto custom

Nel mio lavoro di consulenza JDE mi ritrovo spesso a dover analizzare interi repository di oggetti custom — a volte centinaia di file — per rispondere a domande come:

  • Questo P55001 è una copia del P4210? E quanto si è discostato?
  • Questa Business Function è ancora sostanzialmente identica allo standard, o è stata riscritta?
  • Quali oggetti sono stati modificati in modo sostanziale e quali sono fermi all'originale?

Il problema non è banale per diverse ragioni.

Il contenuto è rumoroso. Gli export JDE contengono una quantità elevata di boilerplate: commenti standard, intestazioni copyright, dichiarazioni di struttura ripetitive. Se si confronta il testo grezzo, il rumore sovrasta il segnale.

I nomi non bastano. Un P554210 è probabilmente derivato dal P4210, ma un P55001 potrebbe derivare da P4101, P4201 o da un oggetto completamente diverso. La convenzione di naming non è sempre rispettata, e in alcuni casi il prefisso custom non segue alcuna logica rispetto all'originale.

La scala rende il confronto manuale impraticabile. Con 200 standard e 400 oggetti custom, un confronto manuale genera 80.000 combinazioni possibili. Non è un'operazione umana.

L'approccio: un motore di analisi ibrido

Per risolvere questo problema ho sviluppato COS-Analysis, un tool desktop proprietario che affronta il confronto su tre livelli distinti, combinati in un punteggio ponderato finale.

Livello 1 — Pulizia e normalizzazione del contenuto

Prima di qualsiasi confronto, ogni file viene sottoposto a una fase di preprocessing:

  • Rimozione del boilerplate fisso (intestazioni copyright, dichiarazioni strutturali ripetitive specifiche di JDE)
  • Rimozione del rumore di layout (posizioni, dimensioni, identificatori UI)
  • Sostituzione del nome specifico dell'oggetto con un placeholder generico, in modo da neutralizzare le differenze di naming durante il confronto testuale

Questo passaggio è critico: senza normalizzazione, due oggetti identici nel comportamento ma con diversi header copyright risulterebbero dissimili, e due oggetti diversi ma con lo stesso nome potrebbero risultare artificialmente simili.

Livello 2 — Confronto del contenuto testuale tramite WinnowingAlgoritmo di fingerprinting documentale: rappresenta ogni testo come un insieme di hash estratti da finestre scorrevoli di sequenze di caratteri. Nato per il rilevamento del plagio accademico, è robusto alle modifiche parziali del testo.

Il cuore del confronto testuale è basato sull'algoritmo di WinnowingAlgoritmo di fingerprinting documentale: rappresenta ogni testo come un insieme di hash estratti da finestre scorrevoli di sequenze di caratteri. Nato per il rilevamento del plagio accademico, è robusto alle modifiche parziali del testo., una tecnica di fingerprinting documentale originariamente sviluppata per il rilevamento del plagio accademico. L'idea è di rappresentare ogni documento come un insieme di fingerprint di k-gramUn k-gram è una sequenza contigua di k caratteri (o token) estratta da un testo. Ad esempio, con k=4 la parola "HELLO" genera i k-gram: HELL, ELLO. Il fingerprinting su k-gram permette di confrontare testi anche quando sono stati parzialmente modificati. testuali, estratti tramite una finestra scorrevole.

Questo approccio ha un vantaggio fondamentale rispetto al TF-IDFTerm Frequency–Inverse Document Frequency: tecnica statistica che misura quanto una parola è rilevante in un documento rispetto a una collezione. Parole molto frequenti ovunque ricevono peso basso; parole rare e specifiche ricevono peso alto. classico (che uso come fallback): è robusto alle trasformazioni parziali. Se un oggetto è stato modificato solo in alcune sezioni, il Winnowing rileva comunque l'overlap strutturale nelle parti invariate, producendo un punteggio di similarità significativo anche in presenza di modifiche sostanziali.

La computazione più pesante del Winnowing è implementata tramite un modulo nativo compilato in Rust, integrato in Python. Questo abbatte i tempi di analisi su repository grandi in modo significativo rispetto a un'implementazione puramente Python.

Livello 3 — Fingerprint strutturaleUna "impronta digitale" dell'oggetto JDE: invece di confrontare il testo completo, si estrae un insieme ridotto di token semanticamente significativi (form, tabelle, view, join) che rappresentano la struttura logica dell'oggetto, indipendentemente dal codice. tramite JaccardL'indice di Jaccard misura la similarità tra due insiemi: è il rapporto tra gli elementi in comune (intersezione) e il totale degli elementi distinti (unione). Valore 1 = insiemi identici, valore 0 = nessun elemento in comune.

Il confronto testuale da solo non è sufficiente. Due oggetti JDE possono avere contenuto testuale simile ma struttura completamente diversa. Per questo ho aggiunto un secondo layer basato sul concetto di structural fingerprintUna "impronta digitale" dell'oggetto JDE: invece di confrontare il testo completo, si estrae un insieme ridotto di token semanticamente significativi (form, tabelle, view, join) che rappresentano la struttura logica dell'oggetto, indipendentemente dal codice.: un insieme di token semanticamente rilevanti estratti dal file.

Per ogni tipo di oggetto JDE il set di token è diverso:

  • Per le APPL: Form ID e Business View collegata
  • Per le UBE: View e Report Interconnect
  • Per le BSVW: tabelle e definizioni di join
  • Per le BSFN: nome della funzione interna e DSTR associata

La similarità tra i due insiemi di token viene calcolata tramite l'indice di JaccardL'indice di Jaccard misura la similarità tra due insiemi: è il rapporto tra gli elementi in comune (intersezione) e il totale degli elementi distinti (unione). Valore 1 = insiemi identici, valore 0 = nessun elemento in comune. (rapporto tra intersezione e unione), che misura quanto i due oggetti condividono la stessa "anatomia", indipendentemente da come è scritto il codice.

Livello 4 — Meta-logic sul nome normalizzato

Il quarto componente è più semplice ma ha un impatto importante sulla precisione. Ogni oggetto custom viene analizzato per identificare il suo "genitore teorico": rimuovendo il prefisso numerico custom dal nome (es. P55P, R564R), si ottiene il nome dell'oggetto standard da cui molto probabilmente deriva.

Se questa corrispondenza esiste nel repository degli standard, il punteggio del candidato corrispondente riceve un bonus ponderato. Questo meccanismo riduce drasticamente i falsi positivi nei casi in cui la convenzione di naming è stata rispettata.

Il punteggio finale e la classificazione

I tre componenti — Winnowing, Jaccard strutturale e meta-logic — vengono combinati con pesi definiti per produrre un punteggio finale di similarità compreso tra 0 e 1. Il risultato viene quindi classificato in quattro categorie:

Soglia Classificazione
≥ 0.95 Copia identica / Exact Copy
≥ 0.75 Copia con modifiche minori
≥ 0.50 Copia con modifiche sostanziali
< 0.50 Oggetto nuovo

Per ogni match, il tool genera automaticamente il comando di confronto per Beyond Compare (uno strumento diff molto diffuso nell'ecosistema JDE), in modo che l'analista possa aprire immediatamente il diff visuale tra il custom e il suo standard di riferimento con un singolo click.

Output e utilizzo pratico

Al termine dell'analisi, COS-Analysis produce un report Excel con tutti i risultati, ordinati per tipo di oggetto e punteggio di similarità decrescente. Ogni riga include il nome dell'oggetto analizzato, il miglior standard di riferimento trovato, la percentuale di similarità, la classificazione e il comando Beyond Compare pronto all'uso.

Nella mia pratica quotidiana, questo report diventa il punto di partenza per le attività di upgrade assessment, gap analysis e documentazione della customizzazione. In contesti dove si affronta una migrazione verso una nuova release JDE, sapere con precisione quali custom sono fermi all'originale e quali si sono discostati significa poter pianificare le attività di reingegnerizzazione in modo informato, non a intuito.

Conclusioni

Il problema dell'identificazione delle copie degli standard JDE è un problema reale, ricorrente, e spesso sottovalutato nella pianificazione dei progetti. L'approccio ibrido multi-livello che ho implementato in COS-Analysis — combinando preprocessing semantico, Winnowing con motore Rust, similarità strutturale Jaccard e meta-logic sul naming — permette di ottenere risultati accurati anche su repository di grandi dimensioni, in tempi che rendono l'analisi praticabile.

Se gestisci un sistema JDE e ti trovi di fronte a queste sfide, sono disponibile a discuterne.