Travailler avec des dépendances
Pendant l'écriture et le débogage de notre application, il peut être tentant d'utiliser beaucoup de System.out.println
pour imprimer la trace d'exécution, pour "voir où cela commence à échouer".
// ...
if (user == null) {
if (enableDebug) {
System.out.println("foo 1")
System.out.println("Error: user is null")
}
// ...
}
C'est une très mauvaise façon de créer des logs :
- Elle alourdit à la fois le code et la sortie.
- Cela ralentit l'exécution du programme.
- Vous oublierez de les supprimer après le débogage, ce qui entraînera beaucoup de bruit dans le code.
Pour faciliter le débogage de votre code, il est préférable d'utiliser un Logger car :
- Il existe plusieurs niveaux de log (
DEBUG
,INFO
,WARN
,ERROR
). Vous pouvez donc choisir celui qui convient le mieux à votre environnement (ex :INFO
pour les besoins de production,DEBUG
pour les environnements de développement...) - Il peut écrire les logs dans un fichier plutôt que dans la console.
- Il est indépendant de la plateforme.
- Il offre de meilleures performances avec des flux tamponnés.
- Il permet aux bibliothèques installées de logger avec votre Logger afin d'éviter l'encombrement de plusieurs loggers.
Dans ce chapitre, nous utiliserons l'API de journalisation SLF4J.
SLF4J
Installez SLF4J
- Ajoutez la dernière version de
slf4j-api
dans la partiedependencies
du fichierpom.xml
.
Afficher le pom.xml résultant
tip
- Lorsque vous cherchez une bibliothèque Maven, ne cherchez pas sur Google. Parcourez simplement Maven central.
- Si vous utilisez un IDE comme Intellij, lancez la synchronisation des dépendances Maven lorsque vous ajoutez de nouvelles dépendances, pour lui permettre de vous donner les bonnes suggestions d'importation.
Utilisez SLF4J
- Modifiez App.java et réécrivez le message initial Hello world ! pour utiliser le logger.
app.java
- Lancez le code :
Failure
Comme l'indique l'erreur, SLF4J a besoin d'une implémentation. slf4j-api
est seulement une API qui ne fait donc rien par elle-même : elle s'appuie sur d'autres dépendances pour implémenter les fonctionnalités de logging.
Dans ce chapitre, nous utiliserons slf4j-log4j12
comme implémentation pour SLF4J.
Installez et configurez log4j
- Ajoutez
slf4j-log4j12
dans la partiedependencies
du fichierpom.xml
.
Afficher le pom.xml résultant
Info
Certaines dépendances peuvent avoir des versions alignées (ex : slf4j-log4j12
avec slf4j-api
). Pour les garder alignées et éviter le copier-coller, c'est une bonne pratique d'utiliser <properties>
au-dessus du pom.xml
pour déclarer les versions comme des variables.
pom.xml
<properties>
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${slf4j.version}</maven.compiler.target>
<slf4j.version>2.0.6</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
Configurez Log4j
- Créez un dossier dans
src/main/resources
s'il n'existe pas. - Mettez-y un nouveau fichier appelé
log4j.properties
, avec la configuration suivante.
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
- Exécutez à nouveau le code. Cette fois, le journal devrait apparaître sur la sortie standard :
Error: No SLF4J providers were found.
Vous avez à nouveau cette erreur ?
Avez-vous correctement défini le <scope>
à compile
pour la dépendance slf4j-log4j12
?
Exécutez sans IDE
Dans cette étape, nous allons compiler et exécuter le code sans avoir besoin d'un IDE.
Failure
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at io.takima.agencymanagement.App.<clinit>(App.java:11)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 1 more
Une autre erreur d'exécution. Cette fois, Java exécute le jar
, mais notre application dépend d'une dépendance externe org/slf4j/LoggerFactory
.
Parce que cette dépendance est gérée par Maven, elle a été installée dans votre dépôt local .m2
. Cependant, Java ne va pas automatiquement y chercher des classes supplémentaires, d'où l'erreur.
Pour activer cette dépendance, vous devez configurer le classpath de la JVM avec l'option java -classpath
.
Dans l'étape suivante, nous allons explorer une technique appelée fat JAR.
Fat JAR
Un fat JAR, également appelé uber JAR, ou jar-with-dependencies, est un jar
qui regroupe toutes les dépendances nécessaires, de sorte que l'application ne dépende pas des dépendances installées localement.
Ce type de jar
peut être construit avec l'aide de maven-assembly-plugin
.
Info
- Un fat JAR ne nécessite pas de configurer le CLASSPATH.
- Un fat JAR a une taille plus importante que les JARs normaux.
- Editez le
pom.xml
et ajoutez ou remplacez lemaven-jar-plugin
existant, avec la configuration suivante :
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in manifest make a jar executable -->
<archive>
<manifest>
<mainClass>io.takima.agencymanagement.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
- Créez à nouveau le paquet, puis exécutez le fichier
*-with-dependencies.jar
.
mvn clean package assembly:single
java -jar target/takima-agencymanagement-1.0-SNAPSHOT-jar-with-dependencies.jar
Le jar-with-dependencies n'est pas généré ?
Il se peut que vous deviez supprimer la balise pluginManagement
dans le fichier pom.xml.
Fichiers modifiés
N'oubliez pas de Commit
votre travail !