Gradle-没有主要的清单属性


91

运行基于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) }
}

Answers:


142

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

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

然后只需更改'hello.helloWorld''<your packagename>.<the name of your Main class>'(您的Main类具有main方法)。在这种情况下,您可以在清单中创建一个指向此类的属性,然后运行一个jar。


1
@Stanislav'Main-Class'的值是主类吗?您的示例中的hello和helloWorld是什么?
Daniela Maia

2
@DanielaMaia这只是一个完全合格的类名称,请确保将其写为hello.HelloWorld,其中hello是HelloWorld类所在的包
Stanislav

9
我需要删除该collect {}部分以使其对我有用。您的代码假定所有依赖项都与主类位于同一文件夹中。
AutonomousApps

1

FWIW-我使用以下jar任务将所有编译依赖项汇编到jar文件中,并使用上述建议来正确设置类路径

apply plugin: 'java-library'

jar {
  manifest {
    attributes(
      'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
      'Main-Class': 'your.main.class.goes.here'
    )
  }

  // You can reference any part of the dependency configurations,
  // and you can have as many from statements as you need
  from configurations.compile  
  // I just copied them into the top of the jar, so it looks like the eclipse exported 
  // runnable jar, but you could designate a lib directory, and reference that in the 
  // classpath as "lib/$it.name" instead of it.getName()
  into ''   
}

0

要使jar文件可执行(使java -jar命令起作用),请在中指定Main-Class属性MANIFEST.MF

在Gradle中,您可以通过配置jar任务来做到这一点。

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

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

还是为什么mainClassName不在清单中指定属性?

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

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

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

当一个mainClassName属性集,则:

  1. $ ./gradlew runmain在属性中指定的类中启动方法
  2. 使用/任务构建的zip/tar归档文件将包含一个脚本,该脚本将启动以前指定的类的方法。distZipdistTarmain

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

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.