Maven è uno tool creato dal team di Apache per la gestione della compilazione dei progetti Java con lo scopo di gestire e organizzare le dipendenze di un qualsiasi progetto. È pensato per semplificare il processo di compilazione e semplificare la gestione delle dipendenze del progetto. Apache Maven è ormai diventato uno strumento essenziale per qualsiasi sviluppatore Java diventato uno strumento standard universalmente usato.
Maven è pensato per gestire anche il ciclo di vita del software con una serie di plug-in per l’esecuzione di test e la creazione di documentazione, ciò semplifica la gestione del progetto e garantisce che tutto venga svolto in modo coerente ed efficiente.
In tutti i successivi articoli di questa categoria verrà usato questo tool quindi si da per scontato che lettore abbiamo installato Maven, in questo articolo vengono introdotti i pochi comandi base che devono essere usati per la gestione dei progetti con questa libreria, a titolo introduttivo vengono usati i comandi da riga di comando (la shell di GNU Linux oppure il “cmd” Ms Windows) ma dai prossimi articoli verrà usato Eclipse o Visual Studio Code che risultano molto più comodi visto che mettono a disposizione un tool grafico.
I comandi di Maven possono essere riassunti in pochi punti:
- mvn compile: usato per compilare un progetto
- mvn clean: rimuove tutti i compilati esistenti
- mvn test: esegue tutti gli step di testing se presenti
- mvn install: esegue il deploy del pacchetto (Jar o War) nel repository locale se configurato
- mvn package: esegue la compilazione, il testing e l’installazione, viene quasi sempre usato al posti dei precedenti 4 comandi
- mvn deploy: esegue il precedente comando e poi carica il pacchetto (Jar o War) in un repository remoto se configurato
Mentre il comando base per creare un progetto è:
mvn archetype:generate -DgroupId=it.alnao -DartifactId=progettoJava
con questo comando viene avviato il generatore di progetti indicando i due parametri base (gruppo e artefatto), il programma chiede all’utente di inserirli se non sono indicati nel comando.
Il progetto creato presenta tre files:
- pom.xml: file di configurazione del progetto
- App.java: classe java base
- AppTest.java: classe java di test, vedere la sezione dedicata per approfondire l’argomento
Il file pom.xml presenta tutta una serie di informazione del progetto tra cui:
- nome del progetto e dati base come artifactId, groupId, versione
- proprietà del compiilatore tra cui la versione (dalla 1.7 in poi)
- elenco di tutte le librerie dipendenti
- comandi per la compilazione e plug-in con le varie configurazioni
Come visto in precedente per compilare il progetto il comando principale è:
mvn package
nel dettaglio il processo di compilazione esegue tutta una serie di passi che verranno descritti nei prossimi articoli, se la compilazione va a buon fine viene creato un file jar all’interno della cartella target, il comando per avviare il jar è il classico di java:
java -jar ./target/*.jar
ma lanciando il primo progetto senza modifiche si potrebbe ottenere un errore di compilazione in quanto, di default, il jar creato non è auto-avviante e non c’è nessuna “main-class”, per configurare la classe da impostare come main modificare il file pom.xml aggiungendo il tag “configuration” nel plug-in “maven-jar-plugin”:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>dependency/</classpathPrefix>
<mainClass>it.alnao.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
come facilmente intuibile, nel tag xml è presente la configurazione che indica al compilatore di aggiungere nel manifest quale è la classe principale, in questo esempio è presente anche il “classpathPrefix” indispensabile se si vuole aggiungere qualche libreria dipendenza nel progetto.
Infatti è possibile aggiungere una dipendenza ad un progetto modificando il file pom.xml nella sezione-tag “depedencies”, per esempio per aggiungere log4j al progetto :
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
questa viene aggiunta ma il compilatore deve essere configurato per “portare” la libreria nella cartella target e quindi deve essere aggiunto un ulteriore plugin al pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
e il comando per la compilazione diventa
mvn clean dependency:copy-dependencies package
infatti per poter eseguire la compilazione è indispensabile prima copiare le dipendenze dentro alla cartella “dependency” configurata nel precedente plugin.
public class App {
private static final Logger logger = LogManager.getLogger(App.class);
public static void main( String[] args ) {
BasicConfigurator.configure();
System.out.println( "Hello World!" );
logger.info("We've just greeted the user!");
}
}
Questo è un semplice esempio di classe java per verificare che la libreria log4j venga correttamente inclusa nel progetto e copiata nella cartella target.
Per la creazione di progetti web è possibile usare un archetipo specifico, impostandolo fin dalla creazione del progetto con il comando
mvn archetype:generate -DgroupId=it.alnao -DartifactId=02webModule -DarchetypeArtifactId=maven-archetype-webapp
questo tipo di progetto crea sempre tre files ma di tipo diverso:
- una pagina jsp
- un file di configurazione dell’applicazione web.xml
- il file pom.xml con caratteristiche ben diverse da quelle viste nel progetto classico
questo tipo di progetto viene approfondito nel dettaglio nei prossimi articoli.
Esiste anche un tipo specifico chiamato “maven-archetype-j2ee-simple” che va a create una completa applicazione j2ee con dei sotto-progetti specifici per ear, projects, servlets e il codice sorgente nella cartella src.
I dettagli sulla tool maven è disponibile al sito ufficiale, tutti i dettagli sugli archetipi è disponibile in questa pagina della documentazione ufficiale, l’elenco completo di tutti i plugin e le librerie disponibili come dipendenze è disponibile al repository ufficiale (mvnrepository), è consigliato tenere sempre a portata di mano questi link. Questi semplici esempi sono disponibili nel respository:
https://github.com/alnao/JavaExamples/tree/master/GenericJava
In qualsiasi progetto Java, in progetti puri o in framework strutturati, la gestione del log è un tema molto importante che deve essere sempre tenuto sotto controllo, la libreria principale è log4j sviluppata dalla comunità open-source di Apache Software Foundation. Di questa libreria esisono due versioni (uno e due), nei nuovi progetti viene usata la versione 2 ma in tutti i progetti degli ultimi 10 anni è usata la versione 1 quindi è bene avere sempre sotto mano le specifiche di entrambe le versioni. L’importazione della prima versione nel file pom di maven:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
La seconda versione della libreria, presente di default in alcuni archetipi di maven, è importata con due dipendenze principali:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.0</version>
</dependency>
Storicamente la libreria necessita di un file di configurazione che deve essere posizionata nella cartella <resources> dentro al progetto, cioè nella cartella “src/main” se si tratta di un progetto java standard. La prima versione prevede un file properties dove è possibile configurare il sistema di logging, si rimanda alla documentazione ufficiale per tutti i dettagli su come impostare e usare al meglio la libreria. La seconda versione della libreria prevede un file di configurazione di tipo XML che deve essere “log4j2.xml”, la documentazione ufficiale è ricca di esempi, il più semplice file di configurazione è:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
La scelta di una delle due librerie implica il dover adattare il codice Java sorgente delle classi alla libreria scelta, in particolare la classe principale LogManager è presente in entrambe le versioni ma in pacakge differenti:
//V1
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
//V2
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class App {
private static final Logger logger = LogManager.getLogger(App.class);
public static void main( String[] args ) {
BasicConfigurator.configure(); //only in V1
logger.debug("We've just greeted the user!");
logger.info("We've just greeted the user!");
logger.fatal("We've just greeted the user!");
}
}
In ogni caso si rimanda sempre alla documentazione ufficiale per maggiori informazioni ed esempi.