JAR 入口点实际上必须在 JAR 内部吗?

Does the JAR entry point actually have to be inside the JAR?

一些上下文

我正在尝试设计一个带有启动器的最小框架,这对多个项目都是通用的。然而,当涉及到 运行 JAR 时,我遇到了困难。

我的目的是拥有一个自给自足的 java -jar 命令:MANIFEST 知道 class 路径和入口点。微妙的一点是:因为我希望启动器对所有项目都是通用的,并且要符合 DRY,所以我有一个特定的 JAR,它将始终位于 classpath.

现在,我无法启动我的 jar:

java -jar test.jar

应该从清单中加载 class 路径和入口点。它确实找到了清单,但我最终得到了 Could not find or load main class.

使用更明确的细节启动 有效:

java -cp test.jar;lib/* org.keyboardplaying.test.TestLauncher

我的问题

我没有找到任何说明是否可行的规范,这不是标准情况,但是我可以在 MANIFEST.MF 中指定一个入口点吗?在 class 路径上找到但未包含在我的 JAR 中?


更多细节

我的MANIFEST.MF

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Chop
Build-Jdk: 1.7.0_45
Main-Class: org.keyboardplaying.test.TestLauncher
Class-Path: lib/slf4j-api-1.7.12.jar lib/logback-classic-1. 1.3.jar lib/logback-core-1.1.3.jar

有问题的人注意事项


1.其中一个来源:
2。 Class 非常有趣 link - MANIFEST 的路径条目:http://todayguesswhat.blogspot.com/2011/03/jar-manifestmf-class-path-referencing.html

Does the JAR entry point actually have to be inside the JAR?

不,不是。将启动器放入单独的 jar 文件中是完全合理的,只要它在清单指定的类路径中,就应该没问题。这是一个例子:

launch\Launchable.java:

package launch;

public interface Launchable {
    void launch();
}

launch\Launcher.java:

package launch;

public class Launcher {
    public static void main(String[] args) throws Exception {
        System.out.println("I am the launcher!");
        Class<?> clazz = Class.forName(args[0]);
        Launchable launchable = (Launchable) clazz.newInstance();
        launchable.launch();
    }
}

demo\Test.java:

package demo;

import launch.Launchable;

public class Test implements Launchable {
    public void launch() {
        System.out.println("I am Test, being launched");
    }
}

manifest.txt:

Manifest-Version: 1.0
Main-Class: launch.Launcher
Class-Path: launcher.jar

现在编译并运行:

$ javac -d . launcher/*.java
$ javac -d . demo/*.java
$ jar cvf launcher.jar launcher
$ jar cvfm demo.jar manifest.txt demo
$ java -jar demo.jar demo.Test
I am the launcher!
I am Test, being launched