Ответ 1
Вы можете создать свой кувшин без Main-Class в файле Manifest. Затем:
java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt
У меня есть JAR с 4 классами, каждый из которых имеет метод Main. Я хочу иметь возможность запускать каждый из них по мере необходимости. Я пытаюсь запустить его из командной строки в Linux.
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" являются аргументами командной строки).
Вы можете создать свой кувшин без Main-Class в файле Manifest. Затем:
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
.
Выполнить основной класс:
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
, вы также можете сделать основной класс в своем манифесте класса 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);
}
}
Прежде всего 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 искать основной класс там.
Другой подобный вариант, который, как мне кажется, кратко упоминается в комментариях, заключается в создании нескольких баннеров-оберток. Я не пробовал, но я думаю, что они могут быть полностью пустыми, кроме файла манифеста, который должен указывать основной класс для загрузки, а также включение 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
Вы можете выполнить его, выполнив команду java (не jar) с параметрами. Информацию о доступных опциях можно найти здесь: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html
Добавьте ниже плагин в свой файл 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>