java—如果manifest.mf不存在,那么什么定义了主类

x4shl7ld  于 2021-06-26  发布在  Java
关注(0)|答案(2)|浏览(417)

在eclipse中导出到jar时有两个选项:导出为runnable jar和导出为jar。
我知道runnable jar包含一个manifest.mf文件,它定义了在执行jar时要执行的主类。
我也知道不可运行的jar只是类库,可以添加到类路径中,以便重用代码。它包含清单文件,但其中没有定义的主类。
如果没有定义主类,不可运行的jar文件如何执行?拥有一个定义主类的manifest.mf文件有哪些优点/缺点?一个比另一个稳定吗?

htrmnn0y

htrmnn0y1#

“runnable jar”是一个jar文件,其中清单文件包含允许 java javarunner命令以更简单的方式“运行”jar文件。
e、 g.如果 Foo.jar 文件具有 static void main(String[]) 类中的方法 Bar Package 内 com.example ,则可以使用以下命令运行程序:

java -cp Foo.jar com.example.Bar

如果jar文件清单文件包含以下行:

Main-Class: com.example.Bar

然后可以用一种更简单的方法运行jar文件i:

java -jar Foo.jar

当然,如果没有带 main() 方法,则jar文件中的代码不是“可运行的”,因此只是一个库文件。
真的就这些了。
例如,参见java™ 教程-设置应用程序的入口点以获取更多信息。

yyyllmsg

yyyllmsg2#

如果manifest.mf不存在,那么定义主类的是什么
如果jar文件没有“meta-inf/manifest.mf”组件,那么它就不是jar文件。它只是一个zip文件,不能使用 java -jar ... 一个zip文件(您可以在类路径中包含zip文件,但通常不会这样做。)
如果jar文件有manifest.mf而没有 Main-Class 属性,则不是可执行的jar文件,并且 java -jar ... 会失败的。
但是(如前所述)许多jar文件是库而不是应用程序。对他们来说,入门级课程毫无意义。
如果没有定义主类,不可运行的jar文件如何执行?
(首选的java术语是“可执行”而不是“可运行”。)
那样的话, java -jar ... 会失败的。相反,您可以这样运行应用程序:

java <options> com.example.MyApp.Main <args>

哪里 com.example.MyApp.Main 是主/入口点类。注意,应用程序jar文件可以包含多个入口点类,用户可以决定使用哪个入口点类。
拥有一个定义主类的manifest.mf文件有哪些优点/缺点?
首先,如果您使用 jar 命令,则它将具有manifest.mf。如果没有jar,该命令将无法创建jar。
此外,您还可以在manifest.mf中包含其他有用的内容。其中包括数字散列(用于签名jar)和 Class-Path 属性,以便在启动jar时使用 -jar . 有关更多详细信息,请参阅jar文件规范。
拥有一个 Main-Class jar文件中的属性是:
如果你想使用 -jar .
这意味着用户不需要知道(或键入)入口点类的全名。
没有明显的缺点,有一个 Main-Class 属性。如果用户不使用 java -jar ... 方法,则任何此类属性都将被忽略。但我想你可以说 Main-Class 库jar上的属性可能会导致天真的用户获得误导性错误。这是头发分裂。。。
一个比另一个稳定吗?
不是直接的。
你可以说 -jar 因为可执行jar忽略 CLASSPATH 环境变量和 -cp 命令行上的参数。但另一方面,你不能强迫用户使用 -jar (或双击)启动命令。通过提供shell脚本或bat文件来启动具有适当入口点类名和适当类路径的应用程序,您可以获得类似的稳定性。
我在eclipse中执行了一个不可运行的jar,没有类路径或项目文件,然后我运行了它,它成功了。它能够识别主类并从那里运行它。我的问题是:它是如何识别的?
好 啊。。。那是另一个问题。
这里实际发生的是eclipse项目有一堆配置信息,其中包括构建依赖项。它们为eclipse启动程序提供了默认的类路径。然后,当您使用eclipse的 run 如果没有现有的运行配置,eclipse将搜索当前项目中的所有类,查找具有 public static void main(String[]) 方法。如果只找到一个这样的类,它将假定它是入口点类,并为项目/类创建运行配置。当启动该配置时,eclipse执行与 java -cp <classpath> <class-name> <args> .
笔记:
这是特定于eclipse的行为。标准的java工具链不会做这样的事情。
eclipse没有使用 java -jar 在这里,因此将不参考清单来查找入口点类。
这是众所周知的破坏。例如,我听说如果删除主类并创建一个新类,启动配置不会更新,当您尝试“运行”它时,它会给出一个jvm启动错误。

相关问题