我遇到从一个JAR文件运行多个不同类的问题。我知道我可以将JAR中的一个类设置为将在命令java -jar myjar.jar
之后运行的Main类,但我想要的是:
java -jar myjar.jar MyClass
是否有可能以这种方式执行此操作,或者我是否必须创建多个JAR(每个用于一个可运行的类),或者更好地创建“manager”类,该类将运行我的其他类传递给它们命令行参数?
我正在寻找文档或参考文献,但我找不到任何文件或参考文献。
答案 0 :(得分:66)
可执行Jar文件格式只允许您指定一个主类。为了能够执行不同的应用程序,您需要按照建议创建“管理器”,或者改为使用类路径:
java -cp myjar.jar MyClass
但是,此方法将忽略您在Jar的清单文件中配置的类路径。
答案 1 :(得分:12)
你将不得不使用:
java -cp myjar.jar MyClass
和
java -cp myjar.jar OtherMainClass
答案 2 :(得分:4)
你这样做:
java -cp myjar.jar MyClass
即。将JAR放入类路径中,然后可以通过指定其完全限定名称来运行具有main方法的任何类。 -jar
选项仅作为快捷方式存在,以便使用JAR清单中的信息(也可以在类路径中包含其他JAR以及指定主类)。
答案 3 :(得分:2)
如果提供了正确答案,那么您可以使用一种解决方案为每个具有不同清单的主类构建存根jar。这将允许您通过允许双击每个单独的程序来创建可运行的jar文件。
有几种方法可以实现这一点,但基本要点是将一个类似于下面的类调用传递args的预期main方法。
package com.acme.myapp;
public final class Stub1 {
public static void main(String[] args) {
App1.main(args);
}
}
至于打包,使用maven的一种方法是使用maven-assembly-plugin:jar-with-dependencies mojo。这里的优点是mojo将为自包含的目标main方法构建一个jar,并且不需要在类路径上有其他程序集。它通过将每个依赖jar的内容复制到生成的jar中来实现。
答案 4 :(得分:2)
使用" Launcher"你不会更好吗?主类,其功能只是将调用分派给实际的控制器类,并使用链接文件作为最终的包装器,而不是摆弄wm的-cp选项?
在Windows中,这样做非常容易。
"主要班级"不需要任何复杂的东西,比如
/**
* 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);
}
}
}
在Windows的一面,就像创建这种链接
就足够了javaw.exe -jar "jarfile" "a"
将链接放在" sendTo"中非常有用。文件夹...一个jar,隐藏,由激活其中一个方面的许多链接调用,可以更简单地部署jar逻辑的更新。
所选的实际文件将作为链接定义中的参数之后的字符串列表传递。
这样,您不必担心整个类路径问题。
答案 5 :(得分:1)
Jar文件在清单中只能包含一个Main-Class属性,这意味着java -jar myjar.jar
只能启动一个类。
您可以使用
启动其他可运行的类java -cp myjar.jar OtherClass
但这不会支持用户双击jar文件。
根据用户的熟练程度,可能命令行也可以。如果没有,您可以为每个可运行的类或一个脚本创建一个脚本,该脚本使用参数来选择正确的类。
答案 6 :(得分:1)
此doc会对您有所帮助。