Avatar ·

Как подключить все JAR-файлы из папки в classpath Java?

Всем привет! Я начинающий Java-разработчик, пишу небольшое консольное приложение с использованием библиотек Apache Commons и Gson. У меня есть папка `lib`, в которой лежат все JAR-файлы: `commons-lang3-3.12.0.jar`, `gson-2.8.9.jar` и ещё несколько. Когда я компилирую проект вручную через командную строку, я прописываю каждый JAR отдельно: ```bash javac -cp ".;lib/commons-lang3-3.12.0.jar;lib/gson-2.8.9.jar" MyApp.java ``` Но это ужасно неудобно: если добавить новую библиотеку, приходится переписывать команду. Я слышал, что в Java 6+ можно использовать wildcard `*`, но у меня не получается. Пробовал так: ```bash javac -cp ".;lib/*" MyApp.java ``` Компилятор выдаёт ошибку, что не может найти классы из JAR-файлов. В чём проблема? Как правильно указать classpath, чтобы автоматом подхватывались все JAR из папки? И ещё вопрос: будет ли это работать для запуска (`java`), а не только для компиляции (`javac`)? Заранее спасибо! *(ОС: Windows 10, Java 11)* <<>>

Правильное использование wildcard (*) в classpath

Вы на верном пути, но есть один важный нюанс: wildcard * работает только в контексте каталога, а не пути к файлам. Ошибка возникает из-за того, что вы пишете lib/*, а нужно указать каталог, в котором лежат JAR-файлы, но без звёздочки? Нет, звёздочка нужна, но ставится она после слеша, обозначая "все JAR в этой папке".

Правильный синтаксис для Windows:

javac -cp ".;lib\*" MyApp.java

Обратите внимание на обратную косую черту \ (для Windows) и * после неё. Для Linux/Mac:

javac -cp ".:lib/*" MyApp.java

Почему ваш вариант не работал?

Вы написали lib/* с прямой косой чертой. На Windows это неверно, так как разделитель пути — обратная косая. Компилятор пытался найти папку с именем lib/* (как буквальную строку), не находил её и игнорировал.

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

  • lib\* означает: "все файлы с расширением .jar в папке lib".
  • Wildcard * заменяет только JAR-файлы, не подпапки и не ZIP.
  • Вы можете указать несколько папок: .;lib\*;ext\*

Полный пример для компиляции и запуска

Допустим, структура проекта:

MyProject/
├── src/
│   └── MyApp.java
├── lib/
│   ├── commons-lang3-3.12.0.jar
│   └── gson-2.8.9.jar
└── out/

Компиляция:

cd MyProject
javac -d out -cp ".;lib\*" src/MyApp.java

Запуск:

java -cp "out;lib\*" MyApp

Важные замечания

  • Wildcard * не рекурсивен — он не заходит в подпапки. Если JAR лежат в lib/subdir/, их нужно указывать отдельно: lib\subdir\*.
  • Символ * нужно экранировать в некоторых shell (например, в bash на Linux можно использовать кавычки).
  • В Java 9+ появилась возможность использовать --class-path вместо -cp, но синтаксис тот же.
  • Если вы используете Maven или Gradle, эта проблема решается автоматически — они сами собирают classpath из зависимостей.

Проверка: работает ли?

Чтобы убедиться, что JAR-файлы подхватились, выполните:

java -cp "out;lib\*" -verbose:class MyApp

Вы увидите загрузку классов из ваших JAR-файлов.

Теперь ваш проект будет легко расширять: просто копируйте новый JAR в lib и перекомпилируйте/запускайте — ничего менять не нужно!

<<>>

Альтернативное решение: собираем classpath скриптом

Если вы работаете на Windows и хотите более гибкого контроля, можно написать batch-скрипт, который сам составит classpath из всех JAR-файлов.

@echo off
setlocal enabledelayedexpansion
set CP=.
for %%j in (lib\*.jar) do set CP=!CP!;%%j
javac -cp "%CP%" MyApp.java
java -cp "%CP%" MyApp
endlocal

Этот скрипт:

  • Собирает все JAR из папки lib в переменную CP.
  • Использует её и для компиляции, и для запуска.
  • Легко модифицируется: можно добавить другие папки или фильтры.

Недостаток: на больших проектах скрипт может работать медленнее, чем встроенный wildcard. Но для небольших проектов это надёжное решение, не зависящее от особенностей синтаксиса Java.

Кстати, на Linux можно сделать аналогичный bash-скрипт:

#!/bin/bash
CP="."
for jar in lib/*.jar; do
    CP="$CP:$jar"
done
javac -cp "$CP" MyApp.java
java -cp "$CP" MyApp

Этот подход полезен, когда нужно исключить какие-то JAR из classpath или добавить дополнительные пути.