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
有问题的人注意事项
- 我之前尝试过
Class-Path: lib/*
,我更喜欢它,但是您不能在 Manifest1 中对 class 路径使用通配符。您仍然可以使用目录,但 class 加载程序不会检查此目录中的 jars 内容。
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
一些上下文
我正在尝试设计一个带有启动器的最小框架,这对多个项目都是通用的。然而,当涉及到 运行 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
有问题的人注意事项
- 我之前尝试过
Class-Path: lib/*
,我更喜欢它,但是您不能在 Manifest1 中对 class 路径使用通配符。您仍然可以使用目录,但 class 加载程序不会检查此目录中的 jars 内容。
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