Gradle-没有主要的清单属性

tmn*_*tmn 75 java gradle

我在运行一个由Gradle构建的JAR文件时得到的这个错误让我很生气.错误读取"没有主要清单属性,在RxJavaDemo.jar中"我试图操纵Manifest属性,但我想我忘了添加依赖项或其他东西.我究竟做错了什么?

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'demo.MainDashboard'

dependencies {

    compile files ("H:/Processes/Development/libraries/hikari-cp/HikariCP-2.4.1.jar")
    compile files ("H:/Processes/Development/libraries/controls-fx/controlsfx.jar")
    compile files ("H:/Processes/Development/libraries/database_connections/sqlite-jdbc-3.8.6.jar")
    compile files ("H:/Processes/Development/libraries/guava/guava-18.0.jar")
    compile files ("H:/Processes/Development/libraries/rxjava/rxjava-1.0.12.jar")
    compile files ("H:/Processes/Development/libraries/rxjava-extras/rxjava-extras-0.5.15.jar")
    compile files ("H:/Processes/Development/libraries/rxjavafx/RxJavaFX-1.0.0-RC1-SNAPSHOT.jar")
    compile files ("H:/Processes/Development/libraries/rxjavaguava/rxjava-guava-1.0.3.jar")
    compile files ("H:/Processes/Development/libraries/rxjava-jdbc/rxjava-jdbc-0.6.3.jar")
    compile files ("H:/Processes/Development/libraries/slf4j/slf4j-api-1.7.12.jar")
    compile files ("H:/Processes/Development/libraries/tom-commons/tom-commons.jar")

}

sourceSets {
    main.java.srcDir "src/main/java"
    main.resources.srcDir "src/main/resources"
}

    jar { 
  manifest {
    attributes(
      "Class-Path": configurations.compile.collect { it.getName() }.join(' '))
  }
    from configurations.compile.collect { entry -> zipTree(entry) }
}
Run Code Online (Sandbox Code Playgroud)

Sta*_*lav 116

尝试更改清单属性,例如:

jar {
  manifest {
    attributes(
      'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
      'Main-Class': 'hello.HelloWorld'
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

然后只需更改'hello.helloWorld'到您的类,它有一个主要方法.在这种情况下,您在清单中创建一个指向此类的属性,然后运行一个jar.

  • 最新的 Gradle 版本已取代了“compile”。而是使用: `'Class-Path':configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')` (16认同)
  • 我需要删除`collect {}`部分才能让它为我工作.您的代码假定所有依赖项都与主类位于同一文件夹中. (8认同)
  • @DanielaMaia这只是一个完全合格的类名,请确保将其写为hello.HelloWorld,其中hello是HelloWorld类所在的包 (2认同)

cac*_*co3 14

要使jar文件可执行(以便java -jar命令工作),请Main-ClassMANIFEST.MF.

在 Gradle 中,您可以通过配置jar任务来完成。

  • 对于Groovy DSL,请参阅这些答案([1][2]
  • 对于Kotlin DSL,您可以使用以下代码片段:
tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.caco3.Main"
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么mainClassName不能按预期工作?

或者为什么mainClassName不在清单中指定属性?

mainClassName属性来自application插件。插件:

使在开发过程中在本地启动应用程序变得容易,并将应用程序打包TAR和/或ZIP, 包括操作系统特定的启动脚本

所以application插件并不针对生产可执行jar小号

当设置mainClassName属性时,则:

  1. $ ./gradlew runmain在属性中指定的类中启动方法
  2. 使用/ tasks构建的zip/ tararchive将包含一个脚本,该脚本将启动指定的先前类的方法。distZipdistTarmain

这是设置主类的shell脚本行:

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"
Run Code Online (Sandbox Code Playgroud)


Mah*_*zad 5

为了补充Denis Zavedeev 的回答,以下是Kotlin DSL (build.gradle.kts)的更多方法:

tasks.jar {
    manifest.attributes["Main-Class"] = "com.example.MyMainClass"
}
Run Code Online (Sandbox Code Playgroud)

另一种记法:

tasks.jar {
    manifest {
        attributes["Main-Class"] = "com.example.MyMainClass"
    }
}
Run Code Online (Sandbox Code Playgroud)

旁注:要创建可运行的 fat JAR(也称为 uber JAR),请参阅此帖子