如何从Jar中运行一个不是它的Manifest文件中的Main-Class的类

我有一个JAR有4个类,每个都有Main方法。 我希望能够根据需要运行其中的每一个。 我试图从Linux上的命令行来运行它。

Eg 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 

我知道我可以在我的Manifest文件中指定一个类作为main。 但是,有什么方法可以在命令行上指定一些参数来运行我希望运行的任何类?

我试过这个:

 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'是命令行参数)。

你可以在Manifest文件中创build没有Main-Class的jar。 然后 :

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

即使jar文件具有定义的Main-Class也可以从JAR文件中执行任何具有public final static main方法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 ,您还可以在您的Manifest Dispatcher类中创build主类。

例:

 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创build一个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在类path上设置jar,并使java在那里查找主类。

Nick认为Nick在评论中提到的另一个类似的选项是创build多个包装jar。 我还没有尝试过,但是我认为除了清单文件之外,它们可以是完全空的,它应该指定要加载的主类以及将MyJar.jar包含到类path中。

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运行它

在你的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> 

你可以用参数执行java命令(不是jar)来完成它。 有关可用选项的信息,请访问: https : //docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html