Java 8 qui.Gradle può aiutare a risolvere l'inferno in qualche modo?
dire che c'è una versione del widget
libray, con coordinate Maven widgetmakers:widget:1.0.4
, che ha una classe definita in questo modo:
public class Widget {
private String meow;
// constructor, getters, setters, etc.
}
anni passano. I manutentori di questa libreria widget
decidono che uno Widget
non dovrebbe mai meow
, piuttosto che dovrebbe in effetti bark
. E così una nuova release è fatto, con le coordinate Maven widgetmakers:widget:2.0.0
e con Widget
cercando come:
public class Widget {
private Bark bark;
// constructor, getters, setters, etc.
}
Così ora vado a costruire la mia app, myapp
. E, volendo utilizzare le ultime versioni stabili di tutte le mie dipendenze, dichiaro le mie dipendenze in questo modo (all'interno di build.gradle
):
dependencies {
compile (
,'org.slf4j:slf4j-api:1.7.20'
,'org.slf4j:slf4j-simple:1.7.20'
,'bupo:fizzbuzz:3.7.14'
,'commons-cli:commons-cli:1.2'
,'widgetmakers:widget:2.0.0'
)
}
Ora diciamo che questo (fittizia) fizzbuzz
biblioteca ha sempre dipendeva da un Versione 1.x della libreria widget
, dove Widget
meow
.
Così ora, mi sto specificando 2 versioni di widget
sul mio compilazione classpath:
widgetmakers:widget:1.0.4
che è attratto dalla libreriafizzbuzz
, come una dipendenza di essa; ewidgetmakers:widget:2.0.0
che sto riferimento diretto
Così, ovviamente, a seconda di quale versione di Widget
viene classloaded prima, vi applicheremo una Widget#meow
o un Widget#bark
.
Gradle fornisce delle strutture per aiutarmi qui? Esiste un modo per inserire più versioni della stessa classe e configurare le classi fizzbuzz
per utilizzare la versione precedente di Widget
e le mie classi per utilizzare la nuova versione? In caso contrario, le uniche soluzioni mi viene in mente sono:
- potrei essere in grado di realizzare una sorta di shading- e/o soltuion fatjar-based, dove forse mi tira in tutte le mie dipendenze come pacchetti sotto
myapp/bin
e quindi dai loro differenti prefissi di versione. Devo ammettere che non vedo una soluzione chiara qui, ma sono sicuro che qualcosa sia fattibile (eppure totalmente hacky/brutto). Oppure ... - Ispeziona attentamente l'intero grafico delle dipendenze e assicurati che tutte le mie dipendenze transitive non siano in conflitto tra loro. In questo caso per me, questo significa inviare una richiesta di pull ai manutentori
fizzbuzz
per aggiornarlo alla versione più recentewidget
o, purtroppo, eseguire il downgrade dimyapp
per utilizzare la versione precedentewidget
.
Ma Gradle (finora) è stato magico per me. Quindi chiedo: c'è qualche magia di Gradle che può servirmi qui?
L'unico modo in cui vedo che è possibile utilizzare correttamente due versioni diverse della stessa libreria è il riferimento a ciascuna versione, laddove richiesto dall'utente o dalla libreria. In caso contrario, si dovrà dipendere dalla versione che Gradle fornirebbe. Inoltre otterrete un'eccezione classe/metodo non trovata se è la versione sbagliata. Gradle può trovare dipendenze che mancano e trascinarle, ma sabotare manualmente il meccanismo di risoluzione delle dipendenze di Gradle confondendolo con 2 librerie non andrà bene a lungo termine. –
Grazie a @WeareBorg (+1). ** (1) ** Quando dici "* riferendosi a ogni versione, ovunque tu sia richiesto da te o dalla biblioteca *", puoi approfondire un po '? Sono stato uno sviluppatore JVM per oltre 10 anni e non ho familiarità con questa strategia/approccio! Puoi dare un esempio di cosa intendi? E ** (2) ** qual è il comportamento predefinito di Gradle in questa situazione? Lasciato intatto, quale versione della libreria 'widget' sarà in Gradle recuperare/risolvere? Grazie ancora! – smeeb
1) Intendevo qualcosa di semplice, ma conosco la sintassi per Maven, dove puoi escludere la libreria che non ti servirà con una versione specifica, quindi l'altra versione viene automaticamente richiamata.2) Per il gradle a causa delle aggiunte del classpath, sarà il primo in lista, per Maven, sarà l'ultimo. –