Gestione delle dipendenze con IVY

La gestione delle librerie fornite da terzi  è parte dello sviluppo di un software.

E' possibile automatizzare la gestione delle dipendenze appogiandosi ad appositi strumenti. In questo articolo parleremo di uno di essi, cioè di Apache Ivy, definito sul proprio sito come "The agile dependency manager".

Cosa possiamo fare con un dependency manager? Gli indicheremo quali sono le librerie esterne al nostro progetto di cui abbiamo bisogno e lasceremo che sia lui a gestirle per noi. Semplicisticamente, ger gestire si intende:

  • download automatico delle librerie
  • download automatico ricorsivo delle dipendenze che a loro volta sono richieste dalle librerie che indichiamo (ad esempio potrebbe servirci la libreria Commons DBCP, ma questa libreria funziona soltanto se a priori è presente la libreria Commons Pool. Il dependency manager provvederà a procurare entrambe le librerie)
  • creazione di un proprio repository di componenti e pubblicazione di questi ultimi

Ivy è altamente integrato con Apache Ant, quindi utilizzando insieme questi strumenti potremo gestire in maniera centralizzata sia le dipendenze che il build del progetto (per un breve tutorial su Ant puoi leggere questo articolo).

Le dipendenze che possono essere indicate sono tutte quelle presenti su http://mvnrepository.com (veramente tante!), ma è anche possibile avere repository personalizzati.

Installazione di Ivy

Do per scontato che abbiate già Ant installato e configurato correttamente.

Scaricate Ivy dal sito ufficiale  e scompattatelo. Copiate il file ivy-2.2.0.jar in una cartella inclusa nel classpath di Ant (ad esempio in  ~vostoNomeUtente/.ant/lib oppure in $ANT_HOME/lib)

Utilizzo di Ivy

Per comprendere come utilizzare ivy scriviamo un classico programma "Hello World", nel quale però al posto di System.out.println utlizziamo Log4j per la stampa a video. Log4j è una libreria "esterna" (non è inclusa nella JDK) e quindi essa sarà la nostra dipendenza da dover gestire.

Struttura del progetto:

|- src
|   \- SayHello.java
|- lib
|- build.xml
\- ivy.xml

Nella cartella src ci sono i sorgenti (in questo caso un unico file Java), la cartella lib (inizialmente vuota) sarà automaticamente popolata da Ivy con le librerie necessarie, il file di configurazione di Ant è build.xml, mentre quello di Ivy è ivy.xml

Ecco il sorgente di SayHello.java

--- inizio file SayHello.java ---

import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;

public class SayHello {

 private static Logger logger = Logger.getLogger(Test.class);

 public static void main(String args[]) {
    BasicConfigurator.configure();
    logger.info("Hello world!");
 }
}

--- fine file SayHello.java ---

Senza la libreria di Log4j non riusciremmo neanche a compilare SayHello.java quindi istruiamo Ivy, indicandogli quali sono i componenti necessari per il progetto:

--- inizio file ivy.xml ---

<ivy-module version="2.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
            
    <info organisation="it.lorenzoingrilli" module="Test-Module" />
    
    <dependencies>
        <dependency org="log4j" name="log4j" rev="1.2.16"/>       
    </dependencies>
        
</ivy-module>

--- fine file ivy.xml ---

(in questo esempio stiamo indicando solo una dipendenza -log4j- ma  è possibile inserire più di un tag dependency in modo da indicare più dipendenze)

Adesso dobbiamo solo scrivere un buildfile per Ant che serva per attivare ivy e compilare il progetto.

--- inizio file build.xml ---

<project
    name="IVY Hello world"
    default="build"
    xmlns:ivy="antlib:org.apache.ivy.ant"
    >

<target name="build">    
    
    <mkdir dir="dist"/>        
    <mkdir dir="build"/>
    
    <ivy:retrieve/>
    
    <javac srcdir="src" destdir="build" extdirs="lib"/>
    <jar basedir="build" destfile="dist/helloworld.jar"/>

</target>
    
</project>

--- fine file build.xml ---

Come potete osservare, rispetto ad un classico buildfile, abbiamo solo aggiunto:

  • la definizione del namespace di ivy (xmlns:ivy="antlib:org.apache.ivy.ant")
  • la chiamata al task <ivy:retrieve/> Questo task si occupa di leggere l'elenco delle dipendenze indicate nel file ivy.xml, di scaricarle e di inserirle nella cartella lib

Non ci resta che compilare il progetto ed eseguirlo: quindi eseguite ant (che genererà in output un file dist/helloworld.jar) e poi java -cp 'dist/helloworld.jar:lib/*' SayHello ; dovreste vedere a video il messaggio "Hello World"

 

Approfondimenti

Ricordate che per ogni libreria sul sito mvnrepository.com trovate l'esempio esatto di come configurare ivy (es. http://mvnrepository.com/artifact/log4j/log4j/1.2.16#tabs-2)

Ivy consente di effettuare operazioni anche molto più complesse di quelle che vi ho mostrato, quindi vi invito a studiarne tutte le caratteristiche sulla documentazione ufficiale di Ivy