Introduction : La malédiction des mille JARs
\nAvez-vous déjà été dans une situation où votre projet Java s'agrandit et où le dossier lib/ se transforme en un véritable zoo avec des dizaines, voire des centaines de fichiers JAR ? Et à chaque lancement de l'application, vous vous rappelez péniblement quel JAR vous avez ajouté et lequel vous avez oublié ? Cela vous semble familier, n'est-ce pas ?
La question "Including all the jars in a directory within the Java classpath" est l'une des plus populaires sur Stack Overflow. Et pour cause. Une tâche apparemment triviale devient un casse-tête si l'on ne connaît pas les bons outils. Dans cet article, nous allons passer en revue toutes les méthodes : des plus anciennes, vieilles comme les dinosaures, aux plus modernes, utilisées par tout développeur Java qui se respecte en 2025.
\nPréparez-vous, nous partons pour un voyage passionnant à travers la jungle du classpath !
\n\nPourquoi est-ce un problème ? (ou "L'épopée du -cp")
\nAu bon vieux temps (avant Java 6), les développeurs devaient lister manuellement chaque fichier JAR. Cela ressemblait à peu près à ceci :
\njava -cp lib/guava.jar:lib/spring-core.jar:lib/log4j.jar:lib/jackson.jar MyApp\nImaginez maintenant que vous ayez 30 bibliothèques. Une seule faute de frappe et l'application plante avec une ClassNotFoundException. Un cauchemar ! C'est à ce moment-là que la communauté a commencé à chercher des moyens d'inclure tous les jars dans le classpath Java en une seule ligne.
Méthode n°1 : Wildcard — le sauveur de Java 6
\nDepuis Java 6, la JVM a introduit une fonctionnalité magique : le wildcard (joker). Il suffit d'indiquer le chemin vers le dossier avec un astérisque, et la JVM charge automatiquement tous les fichiers JAR qui s'y trouvent.
\nComment ça marche :
\njava -cp "lib/*" MyApp\nImportant ! Notez les guillemets. Sans eux, dans certains shells (par exemple sous Unix), l'astérisque peut être interprétée par le shell, et vous n'obtiendrez pas ce que vous attendez. Les guillemets garantissent que * est bien transmis à la JVM.
Cette méthode est toujours d'actualité. Elle est simple, élégante et résout 90 % des problèmes. Mais il y a un détail : le wildcard ne fonctionne pas de manière récursive. Si vous avez des dossiers imbriqués (lib/subdir/), leur contenu ne sera pas chargé. Pour cela, vous devez indiquer chaque niveau manuellement :
java -cp "lib/*:lib/subdir/*" MyApp\n\nQuand utiliser le wildcard ?
\n- \n
- Vous écrivez un script simple ou un utilitaire. \n
- Vous n'avez pas de système de build (Maven/Gradle). \n
- Vous devez lancer rapidement quelque chose "à la volée". \n
Méthode n°2 : Maven — le standard de l'industrie
\nSi vous travaillez sur un projet réel, vous utilisez probablement Maven. Et la question "comment inclure tous les JARs d'un dossier" se résout ici au niveau du build.
\nMaven gère lui-même les dépendances. Il suffit de les indiquer dans le pom.xml, et Maven télécharge les JARs nécessaires et les ajoute automatiquement au classpath.
Exemple de pom.xml :
<dependencies>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-web</artifactId>\n <version>3.2.0</version>\n </dependency>\n <dependency>\n <groupId>com.google.code.gson</groupId>\n <artifactId>gson</artifactId>\n <version>2.10.1</version>\n </dependency>\n</dependencies>\nLors du build (par exemple, mvn package), Maven crée un fat JAR (ou utilise le plugin maven-dependency-plugin) qui inclut toutes les dépendances. Vous n'avez plus à penser au classpath — il est emballé à l'intérieur.
Mais que faire si vous devez inclure tous les JARs d'un dossier local non géré par Maven ? Pour cela, il existe les System Dependencies (bien que cela soit considéré comme un anti-patron) :
\n<dependency>\n <groupId>com.example&