Запуск конкретного класса из JAR-файла: решение ошибки
Быстрый ответ
Для того, чтобы запустить класс, не определённый в манифесте JAR-файла как Main-Class
, выполните следующую команду:
java -cp YourJar.jar com.yourpackage.YourClass
В параметре classpath (-cp
) указывается ваш JAR-файл. Замените com.yourpackage.YourClass
на полное имя класса, который вы хотите запустить.
Управление зависимостями и формирование classpath
Если целевой класс в JAR-файле имеет зависимости от других классов или библиотек, крайне важно внести все зависимости в classpath. Если сборка проекта осуществляется с помощью Maven, обычно создаётся директория lib
с необходимыми зависимостями. Чтобы добавить их в classpath, выполните команду:
java -cp "YourJar.jar;lib/*" com.yourpackage.YourClass
Отметим, что символ ";" служит разделителем в списке classpath.
Для UNIX-систем в качестве разделителя используется символ :
.
Разбор сообщений об ошибках
При запуске класса могут возникнуть ошибки. В основном их устранение происходит через следующие этапы:
- Проверка корректности написания имён классов и пакетов.
- Убеждение, что в целевом классе имеется статический метод main с корректной сигнатурой
public static void main(String[] args)
. - Убеждение в наличии всех требуемых JAR-файлов и директорий в classpath.
Запуск проектов на Spring Boot
Для запуска приложений на Spring Boot применяется особенный подход. Вместо стандартной опции java -jar
используйте PropertiesLauncher:
java -cp YourJar.jar -Dloader.main=com.yourpackage.YourClass org.springframework.boot.loader.PropertiesLauncher
С помощью флага -Dloader.main
вы определяете главный класс для загрузчика Spring Boot. При упаковке приложения убедитесь, что вы выполнили:
mvn package spring-boot:repackage
Визуализация
Jar-файл можно представить как ящик (📦), где главный класс выступает в роли мастер-ключа (🔑).
Jar (📦): [Класс1🔒, Класс2🔒, Главный класс🔑, Класс4🔒]
Для доступа к любому другому классу применяется соответствующий мастер-ключ (🗝️):
java -cp app.jar com.yourpackage.Класс2
Теперь доступ открыт! 🔓 Найти и использовать мастер-ключ для доступа к нужному классу — вот ваша задача.
Продвинутые способы выполнения
Создание диспетчерского класса
В ряде случаев требуется динамически определять класс, подлежащий запуску. Диспетчерский класс в обрамлении JAR может принимать аргументы и вызывать main метод нужного класса с помощью рефлексии.
Пример реализации диспетчера выглядит так:
public class Dispatcher {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName(args[0]);
Method method = clazz.getMethod("main", String[].class);
// Передаем методу подсказку: "Время проснуться!"
String[] mainArgs = Arrays.copyOfRange(args, 1, args.length);
method.invoke(null, (Object) mainArgs);
}
}
Создание обёрточного JAR
Более надёжным решением может стать создание обёрточного JAR, включающего основной JAR в Class-Path
своего манифеста. Обёрточный JAR дает возможность определять различные главные классы и перенаправлять аргументы командной строки.
Полезные материалы
- API вызовов — официальная документация Oracle о динамическом исполнении Java-кода.
- Выполнение Java-приложения в отдельном процессе — советы от сообщества разработчиков и практические примеры запуска Java-класса.
- Понимание механизма загрузки классов в Java — подробное руководство по механизму загрузки классов в Java.
- Управление Java Classpath во время выполнения — статья IBM о управлении classpath для динамического управления классами.
- Установка точки входа приложения — учебник по настройке точек входа приложений в Jar-файлах.
- Руководство по API рефлексии — знакомство с основами Java Reflection API для динамического анализа и исполнения классов.
- Как динамично загружать Jar-файлы во время выполнения? — обсуждение о динамической загрузке JAR-файлов для исполнения классов.