JARы в classpath: Как подключить все библиотеки из папки в 2025

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Проклятие тысячи JARов

Вы когда-нибудь оказывались в ситуации, когда ваш Java-проект разрастается, и папка lib/ превращается в настоящий зоопарк из десятков, а то и сотен JAR-файлов? И каждый раз, запуская приложение, вы мучительно вспоминаете, какой именно JAR вы добавили, а какой забыли? Знакомо, не правда ли?

Вопрос "Including all the jars in a directory within the Java classpath" — один из самых популярных на Stack Overflow. И не зря. Казалось бы, тривиальная задача превращается в головную боль, если не знать правильных инструментов. В этой статье мы разберем все способы: от древних, как динозавры, до самых современных, которые использует каждый уважающий себя Java-разработчик в 2025 году.

Готовьтесь, мы отправляемся в увлекательное путешествие по джунглям classpath!

Почему это вообще проблема? (или "Эпопея с -cp")

В старые-добрые времена (до Java 6) разработчики были вынуждены перечислять каждый JAR-файл вручную. Это выглядело примерно так:

java -cp lib/guava.jar:lib/spring-core.jar:lib/log4j.jar:lib/jackson.jar MyApp

А теперь представьте, что у вас 30 библиотек. Одна опечатка — и приложение падает с ClassNotFoundException. Кошмар! Именно тогда сообщество начало искать способы, как подключить все jar в classpath Java одной строкой.

Способ №1: Wildcard — спаситель из Java 6

Начиная с Java 6, в JVM появилась магическая возможность — wildcard (подстановочный знак). Вы просто указываете путь к папке со звездочкой, и JVM сама подгружает все JAR-файлы оттуда.

Как это работает:

java -cp "lib/*" MyApp

Важно! Обратите внимание на кавычки. Без них в некоторых оболочках (например, в Unix) звездочка может быть интерпретирована shell'ом, и вы получите не то, что ожидаете. Кавычки гарантируют, что * будет передан именно JVM.

Этот метод до сих пор актуален. Он прост, элегантен и решает 90% проблем. Но есть нюанс: wildcard не работает рекурсивно. Если у вас вложенные папки (lib/subdir/), их содержимое не подгрузится. Для этого нужно указывать каждый уровень вручную:

java -cp "lib/*:lib/subdir/*" MyApp

Когда использовать wildcard?

  • Вы пишете простой скрипт или утилиту.
  • У вас нет системы сборки (Maven/Gradle).
  • Вам нужно быстро запустить что-то "на коленке".

Способ №2: Maven — стандарт индустрии

Если вы работаете над реальным проектом, вы, скорее всего, используете Maven. И вопрос "как включить все JARы из папки" здесь решается на уровне сборки.

Maven сам управляет зависимостями. Вы просто указываете их в pom.xml, а Maven скачивает нужные JARы и добавляет их в classpath автоматически.

Пример pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.10.1</version>
    </dependency>
</dependencies>

При сборке (например, mvn package) Maven создает fat JAR (или использует плагин maven-dependency-plugin), который включает все зависимости. Вам больше не нужно думать о classpath — он упакован внутри.

Но что, если вам нужно подключить все JARы из какой-то локальной папки, не управляемой Maven? Для этого есть System Dependencies (хотя это считается антипаттерном):

<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-local-lib</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/my-local-lib.jar</systemPath>
</dependency>

Лучшая практика 2025: Избегайте system scope. Вместо этого установите локальный JAR в локальный репозиторий Maven с помощью mvn install:install-file или используйте частный репозиторий (Nexus, Artifactory).

Способ №3: Gradle — гибкость и скорость

Gradle — еще один популярный инструмент сборки. Он предлагает еще больше гибкости. Чтобы включить все JARы из папки в classpath, можно использовать fileTree:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

Этот код говорит Gradle: "Посмотри в папку libs и добавь все файлы с расширением .jar".

Если вам нужно подключить все JARы из нескольких папок, это тоже легко:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation fileTree(dir: 'external-jars', include: ['*.jar'])
}

Gradle также умеет создавать uber-JAR (fat JAR) с помощью плагина shadow или application. Это делает ваш проект самодостаточным.

Способ №4: Java 9+ и модульная система (JPMS)

С выходом Java 9 мир изменился. Появилась Java Platform Module System (JPMS). Теперь classpath — это не просто список JARов, а модули с явными зависимостями.

Если вы используете модули (module-info.java), то wildcard может не сработать так, как вы привыкли. Вместо этого вы должны явно указать модули:

java --module-path lib --add-modules ALL-MODULE-PATH MyApp

Или, если вы хотите добавить все JARы из папки как unnamed module (старый режим), можно использовать --class-path:

java --class-path "lib/*" MyApp

Лучшая практика 2025: Если вы пишете новый проект, используйте модульную систему. Это повышает безопасность и читаемость кода. Но для старых проектов или быстрых прототипов старый добрый classpath с wildcard все еще работает.

Способ №5

Блоги

Рекомендаций по книгам