首页 文章

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

提问于
浏览
119

我有一个包含4个类的JAR,每个类都有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

我知道我可以在我的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'是命令行参数) .

6 回答

  • 2

    在pom.xml文件中添加以下插件,并在element中指定具有完全限定名称的Main Class .

    <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>
    
  • 101

    您可以在其Manifest文件中创建没有Main-Class的jar . 然后 :

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

    您可以从JAR文件执行任何具有 public final static main 方法的类,即使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 .

  • -2

    除了调用 java -jar myjar.jar com.mycompany.Myclass 之外,您还可以在Manifest中创建一个Dispatcher类的主类 .

    Example:

    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);
    
        }
    }
    
  • 12

    首先 jar 创建一个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能够在那里查找主类 .

  • 1

    我认为尼克在评论中简要提到的另一个类似选项是创建多个包装 jar . 我没有尝试过,但我认为除了清单文件之外它们可能是完全空的,清单文件应该指定要加载的主类以及将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 运行它

相关问题