Запуск конкретного класса из JAR-файла: решение ошибки

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для того, чтобы запустить класс, не определённый в манифесте JAR-файла как Main-Class, выполните следующую команду:

Bash
Скопировать код
java -cp YourJar.jar com.yourpackage.YourClass

В параметре classpath (-cp) указывается ваш JAR-файл. Замените com.yourpackage.YourClass на полное имя класса, который вы хотите запустить.

Кинга Идем в IT: пошаговый план для смены профессии

Управление зависимостями и формирование classpath

Если целевой класс в JAR-файле имеет зависимости от других классов или библиотек, крайне важно внести все зависимости в classpath. Если сборка проекта осуществляется с помощью Maven, обычно создаётся директория lib с необходимыми зависимостями. Чтобы добавить их в classpath, выполните команду:

Bash
Скопировать код
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:

Bash
Скопировать код
java -cp YourJar.jar -Dloader.main=com.yourpackage.YourClass org.springframework.boot.loader.PropertiesLauncher

С помощью флага -Dloader.main вы определяете главный класс для загрузчика Spring Boot. При упаковке приложения убедитесь, что вы выполнили:

Bash
Скопировать код
mvn package spring-boot:repackage

Визуализация

Jar-файл можно представить как ящик (📦), где главный класс выступает в роли мастер-ключа (🔑).

Markdown
Скопировать код
Jar (📦): [Класс1🔒, Класс2🔒, Главный класс🔑, Класс4🔒]

Для доступа к любому другому классу применяется соответствующий мастер-ключ (🗝️):

Bash
Скопировать код
java -cp app.jar com.yourpackage.Класс2

Теперь доступ открыт! 🔓 Найти и использовать мастер-ключ для доступа к нужному классу — вот ваша задача.

Продвинутые способы выполнения

Создание диспетчерского класса

В ряде случаев требуется динамически определять класс, подлежащий запуску. Диспетчерский класс в обрамлении JAR может принимать аргументы и вызывать main метод нужного класса с помощью рефлексии.

Пример реализации диспетчера выглядит так:

Java
Скопировать код
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 дает возможность определять различные главные классы и перенаправлять аргументы командной строки.

Полезные материалы

  1. API вызовов — официальная документация Oracle о динамическом исполнении Java-кода.
  2. Выполнение Java-приложения в отдельном процессесоветы от сообщества разработчиков и практические примеры запуска Java-класса.
  3. Понимание механизма загрузки классов в Java — подробное руководство по механизму загрузки классов в Java.
  4. Управление Java Classpath во время выполнения — статья IBM о управлении classpath для динамического управления классами.
  5. Установка точки входа приложения — учебник по настройке точек входа приложений в Jar-файлах.
  6. Руководство по API рефлексии — знакомство с основами Java Reflection API для динамического анализа и исполнения классов.
  7. Как динамично загружать Jar-файлы во время выполнения? — обсуждение о динамической загрузке JAR-файлов для исполнения классов.