Как запустить класс из Jar, который не является основным классом в файле манифеста

у меня есть JAR с 4 классами, каждый из которых имеет основной метод. Я хочу иметь возможность запускать каждый из них в соответствии с необходимостью. Я пытаюсь запустить его из командной строки в 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.свойства " и " / home/myhome / input.txt ' - аргументы командной строки).

6 ответов


вы можете создать свой jar без Main-Class в своем файле манифеста. Затем:

java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt

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

Выполнить 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.


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

пример:

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);

    }
}

в первую очередь jar создает банку, и не запустить его. Попробуй!--1--> вместо.

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

Edit:

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


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

MyJar1.jar\META-INF\манифест.MF

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

MyJar2.jar\META-INF\манифест.MF

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

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


добавить ниже плагин в вашем 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>