JAR包内有多个可运行类,如何运行它们?

64

我有一个问题,想要从一个JAR文件中运行多个不同的类。我知道可以将JAR文件中的一个类设置为主类,并在命令java -jar myjar.jar后运行它,但我想要的是:

java -jar myjar.jar MyClass

我是否可以通过这种方式实现,还是必须创建多个JAR文件(每个文件对应一个可运行类),或者创建一个“管理器”类来运行我的其他类并向它们传递命令行参数?
我正在寻找文档或参考资料,但我找不到任何信息。

6个回答

79

可执行的Jar文件格式只允许您指定一个主类。为了能够执行不同的应用程序,您需要创建一个“管理器”,或者使用classpath:

java -cp myjar.jar MyClass

然而,这种方法将会忽略您在Jar文件清单文件中配置的类路径。


忽略清单内的类路径一直是我的一个关注点。但我已经测试了这个解决方案,它似乎可以工作(但我真的不知道为什么,因为我已经在清单内设置了类路径)。 - wlk
3
这种启动方式不会读取清单文件,只有以-jar形式启动才会读取清单文件。 - Cameron Skinner

15

你将需要使用:

java -cp myjar.jar MyClass
并且
java -cp myjar.jar OtherMainClass

如何传递多个参数。我的意思是当我传递单个参数时,它可以工作 java -cp myjar.jar OtherMainClass foo 但是 java -cp myjar.jar OtherMainClass foo bar 不起作用。只接受第一个参数 foo - uttam

5

你是否更适合使用“启动器”主类,其功能仅是将调用分派给实际控制器类,并使用链接文件作为最终包装器,而不是在wm的-cp选项中摆弄?

在Windows中,这样做非常容易。

“主类”不需要太复杂,可以像这样:

/**
 * Sample launcher
 */
public class Launcher {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        if (args != null && args.length > 0) {
            String option= args[0]; 
            String[] args2=new String[0];               
            
            if( args.length>1){
                args2= new String[args.length-1];
                System.arraycopy(args, 1, args2, 0, args2.length); 
            }
            
            if(option.equals("a")) {
                new ClassA().exec(args2);
            }
            else if(option.equals("b")){                
                new ClassB().exec(args2);
            }
        }
    }
}

在Windows方面,只需要创建这样的链接即可:
javaw.exe -jar "jarfile" "a"

在“sendTo”文件夹中放置链接非常有用,一个隐藏的jar文件通过许多激活其方面的链接进行调用,使得更新jar逻辑更加简单。实际选择的文件在链接定义的参数后以字符串列表的形式传递。这样,您就不必担心整个类路径的问题。

4
你可以这样做:

java -cp myjar.jar MyClass

即将JAR文件放入类路径中,然后通过指定其完全限定名称运行任何具有main方法的类。 -jar 选项仅作为一种快捷方式存在,以使用JAR清单中的信息(该清单还可以包括类路径中的其他JAR以及指定主类)。


3

Jar文件在清单中只能包含一个Main-Class属性,这意味着java -jar myjar.jar只能启动一个类。

您可以使用以下命令启动其他可运行的类:

java -cp myjar.jar OtherClass

但这无法支持用户双击jar文件运行。根据用户的技能水平,也许命令行可以满足他们的需求。如果不行,您可以为每个可执行类创建脚本或者一个带有参数以选择正确类的脚本。

2

由于已提供正确答案,您可以使用一种解决方案为每个主类构建具有不同清单的存根jar。这将允许您创建可运行的jar文件,并允许双击每个单独程序。

有几种实现方法,但基本原理是放置一个类类似于以下内容,用于调用预期的main方法并传递args。

package com.acme.myapp;

public final class Stub1 {
    public static void main(String[] args) {
        App1.main(args);
    }
}

对于打包,使用Maven的一种方式是使用maven-assembly-plugin插件,并使用jar-with-dependencies Mojo。这里的优点是Mojo将为目标主方法构建一个自包含的Jar文件,不需要在类路径上拥有其他组合件。它通过将每个依赖Jar文件的内容复制到结果Jar文件中来实现这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接