我正在尝试设计一个带有启动器的最小框架,这对于几个项目来说是通用的。然而,在运行JAR时,我遇到了困难。
我的目的是拥有一个自给自足的java -jar
命令:MANIFEST知道类路径和入口点。精巧的一点是这样的:因为我希望启动器对所有项目都是通用的,并且要符合DRY标准,所以我有一个特定的JAR,它总是在类路径上。
现在,我无法启动我的jar:
java -jar test.jar
应该从Manifest加载类路径和入口点。它确实找到了Manifest,但我最终得到了Could not find or load main class
。
使用更明确的详细信息启动 工作:
java -cp test.jar; lib / * org.keyboardplaying.test.TestLauncher
我没有找到任何说明是否可能,这不是标准情况,但是我可以在我的MANIFEST.MF中指定一个可以在类路径上找到的入口点,但不是包含在我的JAR中?
清单 - 版本:1.0
Archiver-Version:Plexus Archiver
创建者:Apache Maven
内置:印章
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/*
我更喜欢,但你不能在Manifest 1 中使用通配符。您仍然可以使用目录,但类加载器不会检查此目录中的jar内容。 <子> 1。其中一个来源:https://stackoverflow.com/a/4756762/1734119
<子> 2。 MANIFEST的Class-Path条目非常有趣的链接:http://todayguesswhat.blogspot.com/2011/03/jar-manifestmf-class-path-referencing.html
答案 0 :(得分:3)
JAR入口点实际上是否必须在JAR中?
不,它没有。将启动器放入一个单独的jar文件是完全合理的,只要它在清单指定的类路径中,它应该没问题。这是一个例子:
发射\ Launchable.java:
package launch;
public interface Launchable {
void 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();
}
}
演示\ 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