Как запустить класс из Jar, который не является Main-Class в его файле манифеста - PullRequest
134 голосов
/ 29 марта 2011

У меня есть JAR с 4 классами, у каждого есть метод Main.Я хочу быть в состоянии управлять каждым из них согласно потребности.Я пытаюсь запустить его из командной строки на Linux box.

E.g. The name of my JAR is MyJar.jar

Он имеет структуру каталогов для основных классов следующим образом:

com/mycomp/myproj/dir1/MainClass1.class
com/mycomp/myproj/dir2/MainClass2.class
com/mycomp/myproj/dir3/MainClass3.class
com/mycomp/myproj/dir4/MainClass4.class

Я знаю, что могу указать одинкласс как основной в моем файле манифеста.Но есть ли способ указать аргумент в командной строке для запуска любого класса, который я хочу запустить?

Я пробовал это:

jar cfe MyJar.jar com.mycomp.myproj.dir2.MainClass2 com/mycomp/myproj/dir2/MainClass2.class /home/myhome/datasource.properties /home/myhome/input.txt

И я получил эту ошибку:

com/mycomp/myproj/dir2/MainClass2.class : no such file or directory

(В приведенной выше команде аргументы командной строки '/home/myhome/datasource.properties' и '/home/myhome/input.txt').

Ответы [ 6 ]

170 голосов
/ 29 марта 2011

Вы можете создать свою банку без Main-Class в файле Manifest. Тогда:

java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt
113 голосов
/ 07 сентября 2015

Вы можете выполнить любой класс , который имеет метод public final static main из файла JAR, , даже если для файла JAR задано Main-Class .

Выполнить главный класс:

java -jar MyJar.jar  // will execute the Main-Class

Выполнить другой класс с помощью метода public static void main:

java -cp MyJar.jar com.mycomp.myproj.AnotherClassWithMainMethod

Примечание: первый использует -jar, второй использует -cp.

14 голосов
/ 29 марта 2011

Помимо вызова java -jar myjar.jar com.mycompany.Myclass, вы также можете сделать основной класс в своем манифесте классом Dispatcher.

Пример:

public class Dispatcher{

    private static final Map<String, Class<?>> ENTRY_POINTS =
        new HashMap<String, Class<?>>();
    static{
        ENTRY_POINTS.put("foo", Foo.class);
        ENTRY_POINTS.put("bar", Bar.class);
        ENTRY_POINTS.put("baz", Baz.class);
    }

    public static void main(final String[] args) throws Exception{

        if(args.length < 1){
            // throw exception, not enough args
        }
        final Class<?> entryPoint = ENTRY_POINTS.get(args[0]);
        if(entryPoint==null){
            // throw exception, entry point doesn't exist
        }
        final String[] argsCopy =
            args.length > 1
                ? Arrays.copyOfRange(args, 1, args.length)
                : new String[0];
        entryPoint.getMethod("main", String[].class).invoke(null,
            (Object) argsCopy);

    }
}
2 голосов
/ 29 марта 2011

Прежде всего jar создает банку и не запускает ее. Попробуйте java -jar вместо.

Во-вторых, почему вы передаете класс дважды, как FQCN (com.mycomp.myproj.dir2.MainClass2) и как файл (com/mycomp/myproj/dir2/MainClass2.class)?

Редактировать:

Кажется, что java -jar требует указания основного класса. Вы можете попробовать java -cp your.jar com.mycomp.myproj.dir2.MainClass2 ... вместо этого. -cp устанавливает jar на путь к классам и позволяет java искать там основной класс.

1 голос
/ 07 мая 2015

Еще одна похожая опция, на которую, как мне кажется, Ник кратко упомянул в комментариях, - это создание нескольких jar-пакетов. Я не пробовал, но думаю, что они могут быть совершенно пустыми, кроме файла манифеста, в котором должен быть указан основной класс для загрузки, а также включение MyJar.jar в путь к классам.

MyJar 1 .jar \ META-INF \ MANIFEST.MF

Manifest-Version: 1.0
Main-Class: com.mycomp.myproj.dir1.MainClass1
Class-Path: MyJar.jar

MyJar 2 .jar \ META-INF \ MANIFEST.MF

Manifest-Version: 1.0
Main-Class: com.mycomp.myproj.dir2.MainClass2
Class-Path: MyJar.jar

и т.д.. Затем просто запустите его с java -jar MyJar2.jar

0 голосов
/ 21 сентября 2017

Добавьте плагин ниже в вашем файле pom.xml и укажите Основной класс с полным именем в элементе.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.2.5.RELEASE</version>
    <configuration>
        <mainClass>**main Class name with full qualified name**</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>
...