Gradle - 没有主要清单属性

Posted

技术标签:

【中文标题】Gradle - 没有主要清单属性【英文标题】:Gradle - no main manifest attribute 【发布时间】:2015-12-10 14:16:00 【问题描述】:

我正在使用 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) 

【问题讨论】:

【参考方案1】:

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

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。

【讨论】:

@Stanislav 'Main-Class' 值是主类吗?您的示例中的 hello 和 helloWorld 是什么? @DanielaMaia 只是一个全限定类名,一定要写成hello.HelloWorld,其中hello是HelloWorld类所在的包 我需要删除 collect 部分才能让它为我工作。您的代码假定所有依赖项都与您的主类位于同一文件夹中。 @AutonomousApps 你是怎么做到的? 它有效,但我只添加了'Main-Class'属性。【参考方案2】:

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

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

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

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

或者为什么mainClassName没有在manifest中指定属性?

mainClassName 属性来自application plugin。插件:

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

所以application 插件的目的不是生成可执行的jars

当设置了mainClassName 属性时,则:

    $ ./gradlew run 将在属性中指定的类中启动main 方法 使用distZip/distTar 任务构建的zip/tar 存档将包含一个脚本,该脚本将启动指定的先前类的main 方法。

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

$ grep Main2 gradletest
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLETEST_OPTS -classpath "\"$CLASSPATH\"" com.caco3.gradletest.Main2 "$APP_ARGS"

【讨论】:

【参考方案3】:

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 ''   

【讨论】:

以上是关于Gradle - 没有主要清单属性的主要内容,如果未能解决你的问题,请参考以下文章

使用 Intellij 2016 创建 Jar - 没有主要清单属性

android studio 导出的jar中没有主清单属性

java 在jar中没有主要的清单属性

mvn clean package:没有主要清单属性[重复]

Java jar - 没有主要清单属性

错误:“Elevator.jar 中没有主要清单属性”