Java 用Gradle创建可运行的JAR

Java 用Gradle创建可运行的JAR,java,jar,gradle,Java,Jar,Gradle,到目前为止,我通过Eclipse“导出…”功能创建了可运行的JAR文件,但现在我转而使用IntelliJ IDEA和Gradle实现构建自动化 这里的一些文章建议使用“应用程序”插件,但这并没有完全达到我预期的效果(只有一个JAR,没有启动脚本或类似的东西) 我如何才能实现Eclipse在“导出…”对话框中的相同结果?您是否尝试过“installApp”任务?它不是用一组启动脚本创建一个完整的目录吗 可执行jar文件只是一个jar文件,在其清单中包含一个主类条目。因此,您只需配置,即可将此条目添

到目前为止,我通过Eclipse“导出…”功能创建了可运行的JAR文件,但现在我转而使用IntelliJ IDEA和Gradle实现构建自动化

这里的一些文章建议使用“应用程序”插件,但这并没有完全达到我预期的效果(只有一个JAR,没有启动脚本或类似的东西)


我如何才能实现Eclipse在“导出…”对话框中的相同结果?

您是否尝试过“installApp”任务?它不是用一组启动脚本创建一个完整的目录吗


可执行jar文件只是一个jar文件,在其清单中包含一个主类条目。因此,您只需配置,即可将此条目添加到其清单中:

jar {
    manifest {
        attributes 'Main-Class': 'com.foo.bar.MainClass'
    }
}
您可能还需要在清单中添加类路径条目,但方法相同


参见

JB Nizet和Jorge_B的答案都是正确的

以其最简单的形式,用Gradle创建一个可执行JAR只需向。然而,更常见的情况是需要在类路径中包含依赖项,这使得这种方法在实践中很棘手

该方法提供了一种替代方法;它不创建可执行JAR,而是提供:

  • 一个
    run
    任务,可以方便地直接从构建中运行应用程序
  • 一个
    installDist
    任务,该任务生成一个目录结构,包括构建的JAR、它所依赖的所有JAR以及一个启动脚本,该脚本将所有JAR汇集到一个可以运行的程序中
  • distZip
    distTar
    创建包含完整应用程序发行版(启动脚本和JAR)的存档的任务
第三种方法是创建一个所谓的“fatjar”,它是一个可执行的JAR,不仅包含组件的代码,还包含其所有依赖项。有几个不同的插件使用这种方法。我已经包括了一些我知道的链接;我相信还有更多


您可以在模块设置(或项目结构)中定义jar工件

  • 右键单击模块>打开模块设置>工件>+>JAR>,从具有依赖关系的模块中选择
  • 设置主类
制作一个jar就像从Build菜单中单击“Build artifact…”一样简单。作为奖励,您可以将所有依赖项打包到一个jar中


在IntelliJ IDEA 14 Ultimate上测试。

正如其他人所指出的,为了使jar文件可执行,必须在清单文件的
主类
属性中设置应用程序的入口点。如果依赖项类文件未并置,则需要在清单文件的
类路径
项中设置它们

我已经尝试了各种插件组合,而不是为了创建一个可执行jar这样的简单任务,并且以某种方式包括依赖项。所有的插件似乎都缺乏这样或那样的方式,但最终我得到了我想要的。没有神秘的脚本,没有一百万个不同的小文件污染构建目录,一个非常干净的构建脚本文件,最重要的是:没有一百万个外来的第三方类文件合并到我的jar归档中

以下是为方便起见从中粘贴的副本

[如何]使用子目录
/lib
中的依赖项jar创建分发zip文件,并将所有依赖项添加到清单文件中的
类路径
项:

apply plugin: 'java'
apply plugin: 'java-library-distribution'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.2'
}

// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)

jar {
    // Keep jar clean:
    exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'

    manifest {
        attributes 'Main-Class': 'com.somepackage.MainClass',
                   'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
    }
    // How-to add class path:
    //     https://stackoverflow.com/questions/22659463/add-classpath-in-manifest-using-gradle
    //     https://gist.github.com/simon04/6865179
}
作为主旨主持

结果可以在
build/distributions
中找到,解压缩的内容如下所示:

lib/commons-lang3-3.3.2.jar
MyJarFile.jar

MyJarFile.jar#META-INF/MANIFEST.mf的内容

清单版本:1.0
主类:com.somepackage.MainClass
类路径:lib/commons-lang3-3.3.2.jar


对我来说,最省力的解决办法就是利用

除了应用插件,还需要做的是:

配置jar任务以将主类放入清单中

jar {
  manifest {
   attributes 'Main-Class': 'com.my.app.Main'
  }
}
运行gradle任务

./gradlew shadowJar
从build/libs/获取应用程序版本all.jar

并最终通过以下方式执行:

java -jar app-version-all.jar

谢谢你,康斯坦丁,它就像一个没有细微差别的魅力。出于某种原因,将main类指定为jar清单的一部分并不十分有效,它需要的是mainClassName属性。下面是build.gradle中的一个片段,其中包括使其工作的所有内容:

plugins {
  id 'java' 
  id 'com.github.johnrengelman.shadow' version '1.2.2'
}
...
...
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
...
...
mainClassName = 'com.acme.myapp.MyClassMain'
...
...
...
shadowJar {
    baseName = 'myapp'
}

运行gradle shadowJar后,您在构建文件夹中获得myapp-{version}-all.jar,它可以作为java-jar-myapp-{version}-all.jar运行。

我查看了很多解决方案的链接,最后完成了下面提到的步骤以使其正常工作。我正在使用Gradle2.9

在生成的gradle文件中进行以下更改:

  • 提及插件:

    apply plugin: 'eu.appsatori.fatjar'
    
  • 提供构建脚本:

    buildscript {
    repositories {
        jcenter()
    }
    
    dependencies {
        classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
    }
    }
    
  • 提供主类:

    fatJar {
      classifier 'fat'
      manifest {
        attributes 'Main-Class': 'my.project.core.MyMainClass'
      }
      exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
    }
    
  • 创建fatjar:

    ./gradlew clean fatjar
    
  • 从/build/libs/运行fatjar:

    java -jar MyFatJar.jar
    

  • 您可以使用SpringBoot插件:

    plugins {
      id "org.springframework.boot" version "2.2.2.RELEASE"
    }
    
    创建jar

    gradle assemble
    
    然后运行它

    java -jar build/libs/*.jar
    
    注意:要使用此插件,您的项目不需要是SpringBoot项目

  • 将主类配置到清单中
  • 如果您使用的是gradle项目,只需将以下内容添加到build.gradle中

    jar {
        manifest {
            attributes(
                   'Main-Class': 'pokerhandscorer.PokerHandScorer'
            )
        }
    }
    
    • 其中,'pokerhandscorer'是包名的名称, PokerHandScorer是主类名
    这将在\build\libs{jarFilename}.jar中创建一个jar文件

  • 使用java-jar/{path}/{jarFileName.jar}运行jar文件
  • java-jar/{path}/{jarFileName.jar}


    这是我用Gradle 6.7尝试的解决方案

    可运行的fat Jar(将所有依赖库复制到Jar)

    将所有依赖项复制到目录并将类路径添加到清单中的可运行jar

        def dependsDir = "${buildDir}/libs/dependencies/"
        task copyDependencies(type: Copy) {
            from configurations.compile
            into "${dependsDir}"
        }
        task createJar(dependsOn: copyDependencies, type: Jar) {
          
            manifest {
                attributes('Main-Class': 'com.example.gradle.App',
                        'Class-Path': configurations.compile.collect { 'dependencies/' + it.getName() }.join(' ')
                )
            }
            with jar
        }
    
    如何使用

    • 将上述任务添加到
          def dependsDir = "${buildDir}/libs/dependencies/"
          task copyDependencies(type: Copy) {
              from configurations.compile
              into "${dependsDir}"
          }
          task createJar(dependsOn: copyDependencies, type: Jar) {
            
              manifest {
                  attributes('Main-Class': 'com.example.gradle.App',
                          'Class-Path': configurations.compile.collect { 'dependencies/' + it.getName() }.join(' ')
                  )
              }
              with jar
          }