Maven - Come non perdere il controllo delle dipendenze java


INTRODUZIONE

Ogni qualvolta che effettuo un packaging di un progetto java oramai è automatico l'utilizzo di apache maven.

Non tutti però sanno che maven ha all'interno un ottimo algoritmo per la gestione delle dipendenze java che calcola sia le dipendenze dirette che quelle indirette.

Questo algoritmo però è influenzato innanzitutto dalle librerie inserite nel file pom.xml (perchè hanno la precedenza) e volte possiamo trovarci con un progetto cresciuto molto negli anni di cui perdiamo l'esatta cognizione di quante e quali libreria utilizza.

In questo post grazie a due plugin vedremo come capire bene lo status delle dipendenze incluse.

CI SONO LIBRERIE INUTILIZZATE?

Il plugin dedicato alle dipendenze (dependency) ha un goal specifico per capire e analizzare le librerie utilizzate (a compile time)

L'output di questo comando dependency:analyze produrrà 3 sezioni:

  • Usate e dichiarate
  • Usate e non dichiarate
  • Inutilizzate e dichiarate

Come detto precedentemente in un progetto possiamo addirittura avere dipendenze su di una stessa libreria ma con versioni differenti.

Sarà l'algoritmo a scegliere effettuare la migliore scelta per noi

Se invece non vogliamo perdere il controllo della situazione possiamo utilizzare l' Enforcer Plugin

ENFORCER PLUGIN


L'enforcer plugin permette la gestione di regole predefinite o definibili.

I goals che il plugin mette a disposizione sono
  • display-info
    • Che permette di visualizzare le informazioni relative al sistema in uso
  • enforce
    • Che esegue le regole indicate
In questo caso ci interessa sia il goal enforce che il tag dependencyConvergence e questo è un esempio di codice da inserire nel pom.xml



<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
               <goal>enforce</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <rules>
            <dependencyConvergence/>
            <requireJavaVersion>
                <version>1.8</version>
            </requireJavaVersion>
        </rules>
    </configuration>
</plugin>

In pratica il plugin recupera dal dependency-tree le librerie indicate e poi effettua un matching cercando eventuali conflitti (per conflitti si intende differenti versioni di librerie a pari di artifactId e groupId)

Nel caso in cui vengano trovate dei conflitti l'output è il seguente:

Dependency convergence error for commons-collections:commons-collections:3.2.1 paths to dependency are:
+-my.package:sample:1.0.0
  +-net.sf.jasperreports:jasperreports:6.3.0
    +-commons-beanutils:commons-beanutils:1.9.0
      +-commons-collections:commons-collections:3.2.1
and
+-my.package:sample:1.0.0
  +-net.sf.jasperreports:jasperreports:6.3.0
    +-commons-collections:commons-collections:3.2.2
and
+-my.package:sample:1.0.0
  +-net.sf.jasperreports:jasperreports:6.3.0
    +-org.codehaus.castor:castor-xml:1.3.3
      +-commons-collections:commons-collections:3.2.1

OPERAZIONE DI BONIFICA

Come indicato dall'output precedente la libreria in conflitto è la 

<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>

Come si legge dall'output del comando, maven indentifica 2 versioni (3.2.1 e 3.2.2) che potenzialmente sono in conflitto fra loro. Naturalmente l'algoritmo ne sceglierà solamente una in compile time.

Analizzando in maniera più approfondita, il conflitto nasce perchè la libreria jasperreports versione 6.3.0 indica come dipendenza la versione 3.2.2, cosa che invece una delle sue dipendenze (castor-xml) indica a sua volta la versione 3.2.1

Per bonificare la situazione occorre inserire all'interno del pom.xml la libreria incriminata a dirgli di escludere la sua dipendenza (tanto viene ugualmente risolta)

<dependency>
   <groupId>org.codehaus.castor</groupId>
   <artifactId>castor-xml</artifactId>
   <version>1.3.3</version>
   <exclusions>
       <exclusion>
           <groupId>commons-collections</groupId>
           <artifactId>commons-collections</artifactId>
       </exclusion>
     </exclusions>
</dependency>

Alla prossima

Commenti

Post popolari in questo blog

Hadoop, how to create a single node cluster using docker

How to install IOTA node with docker

Apache Spark - Try it using docker!