我最近刚开始在java中玩Maven。测试我的项目的时候到了,它在NetBeans窗口中运行得很好,运行App.java(com.MyCompany.App)中的主类,但当我试图从命令行运行它时,我得到了一个错误:
java -jar fileName.jar
fileName.jar 中的"无主清单属性"
我尝试添加了一个manifest.mf文件来指定main是什么,我还加入了项目属性并将其添加为主文件。。。
怎么回事?
您需要maven-jar-plugin
(请参阅Maven的示例)。该插件将在项目构建时在清单文件中创建所需的条目。
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
您需要版本,否则,项目将无法生成。fully.qualified.MainClass
从包层次结构开始。
希望您的清单文件中有问题。一些基本的检查可能会解决你的问题。
- 它应该在
/META-INF/MANIFEST.MF
下 - 内容应具有
Main-Class:com.MyCompany.App
如果您正在使用任何IDE,应该有一个将项目导出为runnable jar
的选项,您可以利用它让IDE处理正确的清单。
从命令行jar cfm filename.jar Manifest.txt com/MyCompany/*.class
生成具有以下内容的清单文件
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Main-Class: com.MyCompany.App
然后您可以运行jar命令java -jar fileName.jar
。
这些类型的问题虽然微不足道,但会耗费大量时间,只需确保文件的内容和位置正确即可。
您可以将其用于命令行:
java -cp jarFileName.jar full.package.className
在这种情况下,您不必详细说明Manifest文件。
使用JAR工具设置入口点:
"e"标志(用于"entrypoint")创建或重写清单的Main Class特性。它可以在创建或更新JAR文件时使用。使用它可以指定应用程序入口点,而无需编辑或创建清单文件。例如,此命令创建app.jar,其中清单中的Main Class属性值设置为MyApp:
jar cfe app.jar MyApp MyApp.class
您可以通过运行以下命令直接调用此应用程序:
java -jar app.jar
如果入口点类名在包中,则可能使用"."(点)字符作为分隔符。例如,如果Main.class在一个名为foo的包中,则可以通过以下方式指定入口点:
jar cfe Main.jar foo.Main foo/Main.class
如果您查看项目的属性对话框(在项目选项卡中,右键单击项目并选择属性),您会看到"类别"窗口中有一个"运行"项。单击它,您将看到一个对话框,您可以在其中指定jar的Main Class。这些信息最终会出现在你的清单中。
我在Netbeans 8.0和"Java应用程序"项目原型的内置Maven项目中遇到了这个问题。此外,我有Maven 3,我发现网上的一些建议与Netbeans使用的Maven代码不匹配。
无论如何,这里有一个简单的方法,让JAR文件运行主类并嵌入依赖库。我通过比较其他项目的POM文件来完成这项工作,我发现这些文件与子项目JAR-s一起工作,所以如果有人对Maven有更好的了解,请发言。此外,我留下了一些正常的东西来提供上下文。示例如下:
<properties>
<packageName>trials.example</packageName>
<mainClass>${packageName}.CmdApp</mainClass>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4jVersion>1.7.7</slf4jVersion>
<log4jVersion>1.2.17</log4jVersion>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
本节告诉Maven介绍该项目。
- packageName。。。是主类的Java包
- mainClass。。。。。main()方法的类的完全限定名称
您将在maven jar插件中看到这些用法。
内置示例原型没有做的另一件事是将我的子项目打包到JAR中,这样我就可以从命令行运行了。这是通过下面的maven依赖插件完成的。有趣的一点是,我们不需要打包系统内容,并且我们希望将依赖类打包到我们的JAR中。
这些用途如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeScope>system</excludeScope>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
<packageName>${packageName}</packageName>
<addClasspath>true</addClasspath>
<classpathPrefix>classes/</classpathPrefix>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
希望这能为你节省几个小时的检查和测试时间。干杯,威尔。