Java JAR 中的多个可运行类,如何运行它们?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3976514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 07:49:27  来源:igfitidea点击:

Multiple runnable classes inside JAR, how to run them?

javajar

提问by wlk

I'm having problems with running multiple different classes from one JAR file. I know that I can set one of the classes inside JAR to by Main class that will be run after command java -jar myjar.jar, but what I want is something like:

我在从一个 JAR 文件运行多个不同的类时遇到问题。我知道我可以将 JAR 中的一个类设置为将在 command 之后运行的 Main 类java -jar myjar.jar,但我想要的是:

java -jar myjar.jar MyClass

Is it possible to do this that way, or do I have to create multiple JAR (each for one runnable class), or is it better to create 'manager' class that will run my other classes passing to them command line arguments?
I was looking for documentation or reference, but I couldn't find any.

是否可以这样做,或者我是否必须创建多个 JAR(每个 JAR 用于一个可运行的类),或者最好创建“管理器”类来运行我的其他类并传递给它们命令行参数?
我正在寻找文档或参考资料,但找不到。

采纳答案by iggymoran

The executable Jar file format only allows you to specify one main class. In order for you to be able to execute different applications, you'll need to either create a "manager" as you suggest, or to use the classpath instead:

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

java -cp myjar.jar MyClass

However, this approach will ignore the classpath you have configured in the Jar's manifest file.

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

回答by Gareth Davis

you will have to use:

你将不得不使用:

java -cp myjar.jar MyClass

and

java -cp myjar.jar OtherMainClass

回答by Michael Borgwardt

You do it like this:

你这样做:

java -cp myjar.jar MyClass

i.e. put the JAR into the classpath, then any class with a main method can be run by specifying its fully qualified name. The -jaroption only exists as a shortcut to use the information in the JAR's manifest instead (which can also include other JARs in the classpath as well as specify the main class).

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

回答by Cameron Skinner

Jar files can contain only one Main-Class attribute in the manifest, which means java -jar myjar.jarcan only start one class.

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

You can start other runnable classes with

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

java -cp myjar.jar OtherClass

but that won't support users double-clicking on the jar file.

但这不支持用户双击 jar 文件。

Depending on how skilled your users are, maybe the command line is OK for them. If not, you can create a script for each runnable class or one script that takes arguments to choose the right class.

根据您的用户的熟练程度,命令行可能适合他们。如果没有,您可以为每个可运行的类创建一个脚本,或者创建一个带有参数来选择正确类的脚本。

回答by Brett Ryan

As the correct answer has been provided there is a solution that you could use to build a stub jar for each main class with different manifests. This would allow you to create runnable jar files by allowing double-clicking for each separate program.

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

There are several ways of accomplishing this but the basics are to put a single class similar to the following which invokes the intended main method passing args.

有几种方法可以实现这一点,但基本方法是放置一个类似于以下内容的类,它调用传递参数的预期主要方法。

package com.acme.myapp;

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

As for packaging this, one way using maven would be with the maven-assembly-plugin:jar-with-dependenciesmojo. The advantage here is that the mojo will build a jar for the target main method that is self contained and does not need to have other assemblies on the classpath. It does this by copying the contents of each dependency jar into the resultant jar.

至于打包,使用 maven 的一种方法是使用 maven -assembly-pluginjar-with-dependenciesmojo。这里的优点是 mojo 将为目标 main 方法构建一个自包含的 jar,不需要在类路径上有其他程序集。它通过将每个依赖项 jar 的内容复制到生成的 jar 中来做到这一点。

回答by DBZ

Wouldn't you be better served with using a "Launcher" main class, whose function is just to dispatch the calls to the actual controller classes, and using a link file as a final wrapper, instead of fiddling with the -cp option of the wm?

使用“启动器”主类是否会更好,其功能只是将调用分派到实际控制器类,并使用链接文件作为最终包装器,而不是摆弄 -cp 选项嗯?

In windows, it is surprisingly easy to do so.

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

The "main class" needs not be anything much complex, something like

“主类”不需要很复杂,比如

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


        }
    }
}

On the windows side of things, it is enough something like creating a link of this kind

在 Windows 方面,创建此类链接就足够了

javaw.exe -jar "jarfile" "a"

It is very useful for placing link in the "sendTo" folder... one jar, hidden, called by many links that activate one of its aspects makes simpler to deploy updates of the jar logic.

将链接放置在“sendTo”文件夹中非常有用……一个 jar,隐藏,由许多激活其方面之一的链接调用,使部署 jar 逻辑的更新更简单。

The actual files selected are passed as a list of string after the params in the link definition.

所选的实际文件在链接定义中的参数之后作为字符串列表传递。

This way, you should not worry about the whole classpath issues.

这样,您就不必担心整个类路径问题。