La migliore strategia per gestire le dipendenze opzionali

Sono attualmente nel processo di rimozione della dipendenza Spring da Flyway . In futuro potrebbero essere necessari altri tipi di dipendenze per supportare un sottoinsieme di utenti (come il supporto di JBoss VFS).

Qual è il modo migliore per supportare dipendenze opzionali (opzionale = true in Maven POM)?

Le qualità della soluzione sarebbero:

  • Facilità d’uso per gli utenti finali (lavoro minimo richiesto per utilizzare la funzionalità se è presente la dipendenza)
  • Facilità d’uso per gli sviluppatori (il codice relativo alla dipendenza opzionale dovrebbe essere il più leggibile e il più semplice ansible)
  • Nessuna dipendenza necessaria non necessaria (se alcuni utenti finali non hanno bisogno di questa funzionalità, non è necessario inserire la dipendenza)

Penso che la funzionalità di dipendenza opzionale di Maven sia piuttosto limitata.

http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

Le dipendenze opzionali non verranno eliminate (come dipendenze transitive) per impostazione predefinita. Tuttavia, se gli utenti devono utilizzare queste funzioni opzionali, le dipendenze mancanti devono essere esplicitamente dichiarate, nel loro POM.

Personalmente, non mi è chiaro come ciò sia utile per gli utenti … Suppongo che le dipendenze opzionali nel tuo POM documentino da quali versioni dipende il tuo codice. Tuttavia, non tutti gli utenti leggeranno il POM, tutto quello che vedranno sarà l’errore “NoClassDef Found 🙁

La mia osservazione finale è che questo è uno di quei rari scenari in cui un manager delle dipendenze come edera offre maggiore flessibilità. Ivy ha un concetto chiamato “configurazioni”. Gli autori dei moduli possono assemblare diverse combinazioni di dipendenze, ad esempio “with spring” o “without-spring”.

C’è una scelta di:

  • mantenere il progetto in un unico modulo; e usa dipendenze opzionali.
  • dividere il progetto in più moduli; dove ogni modulo ha una dipendenza (non opzionale) da qualsiasi libreria;

Penso che il primo abbia più senso nella maggior parte dei casi: gli utenti devono capire il modo in cui circolano meno artefatti. In genere, dovranno aggiungere meno nuove dipendenze al loro pom. A meno che il codice per supportare i progetti di terze parti sia ampio, ciò contribuirà a migliorare anche i tempi di download (meno round-trip). Con quest’ultimo approccio, puoi trovarti in situazioni imbarazzanti in cui l’utente ha definito il proprio set di versioni, ma solo per alcune delle dipendenze di terze parti.

Preferisco vedere le dipendenze opzionali nel pom (a volte guardo per vedere quale versione è costruita contro). È vero che alcune persone potrebbero non guardare. Penso che i frammenti pom copiabili e copiabili sul sito Web siano la soluzione migliore per questo. Ad esempio, se hai una pagina sull’integrazione di Spring, puoi inserire il frammento pom relativo su quella pagina.

Suggerirei che le dipendenze non libere (o qualsiasi cosa non facilmente risolvibile) siano conservate in un modulo maven separato, in modo che i contributori siano sempre in grado di build l’artefatto principale. (Ho avuto quel problema con Quartz, che IIRC ha una dipendenza opzionale su un jar JDBC Oracle).

Modifica: se sei preoccupato per gli utenti che vedono NoClassDefFoundErrors, non farebbe male a controllare che la class possa essere risolta prima di provare a usarla. Ad esempio, è ansible eseguire un’eccezione e inviare un messaggio di errore più significativo che indirizza l’utente alla documentazione. SLF4J è un buon esempio di questo.