Java 如何使用Gradle创建一个独立的自执行jar文件?

Java 如何使用Gradle创建一个独立的自执行jar文件?,java,gradle,Java,Gradle,我试图用Java实现一个protoc插件。这需要一个独立的自执行jar,因为不能将类路径传递给协议 我发现很多文章都在讨论如何创建一个自动执行的jar(eg)。不过,没有一个考虑到依赖项与自执行jar的捆绑。这意味着自执行jar不是独立的。如何做到这一点?以下内容是从现有项目中复制的,可能使用了代码片段中未包含的某些内容(例如Nebula插件): 注: com.github.johnrengelman.shadow用于创建uber jar com.example.Main是执行的Java入口点

我试图用Java实现一个
protoc
插件。这需要一个独立的自执行jar,因为不能将
类路径
传递给
协议


我发现很多文章都在讨论如何创建一个自动执行的jar(eg)。不过,没有一个考虑到依赖项与自执行jar的捆绑。这意味着自执行jar不是独立的。如何做到这一点?

以下内容是从现有项目中复制的,可能使用了代码片段中未包含的某些内容(例如Nebula插件):

注:

  • com.github.johnrengelman.shadow
    用于创建uber jar
  • com.example.Main
    是执行的Java入口点
  • 指定
    分类器
    对于
    protoc
    Gradle插件(默认情况下,它包括
    分类器
    中的操作系统)来说更为重要,并且不是严格需要的。发布的
    protoc
    插件的客户端必须使用
    0.8.3
    或更高版本的
    protoc
    Gradle插件,该插件支持覆盖
    分类器
  • createJarExe
    使用uber jar并遵循文件上的帖子
  • 连接依赖项
    确保在分发之前创建uber jar

可能相关:是的,相关但不充分。问题是jar本身不能有一个引用jar的
类路径。这给我们敲响了警钟。“做一个格拉德尔牧马人是吃力不讨好的。”VinceEmigh,据我所知,社区维基不会提供你声称的优势。
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'

mainClassName = 'com.example.Main'

jar {
  manifest {
    attributes 'Main-Class': 'com.example.Main'
  }
}

publishing {
  publications {
    nebulaIvy(IvyPublication) {
      artifact(tasks.findByName('createJarExe').outputs.getFiles().getSingleFile()) {
        classifier '_-jdk8'
        extension 'exe'
        type 'exe'
      }
    }
  }
}

task createJarExe(dependsOn: installShadowDist) {
  final outputFile = file("${buildDir}/install/${project.name}-shadow/bin/${project.name}-${project.version}.exe")

  doLast {
    outputFile.text = '#!/bin/bash\n'
    outputFile.append('exec java -jar "$0" "$@"')
    outputFile.append(inputs.files.first().readBytes())
    outputFile.setExecutable(true)
  }

  inputs.files "${tasks.findByName('installShadowDist').outputs.getFiles().getSingleFile()}/lib/${project.name}-${project.version}-all.jar"
  outputs.file outputFile
  doFirst {
    mkdir outputFile.getParent()
  }
}

// wire the dependencies
tasks.whenTaskAdded { task ->
  if (task.name == 'publishNebulaIvyPublicationToDistIvyRepository') {
    task.dependsOn('createJarExe')
  }
}