【问题标题】:Can Gradle jar multiple projects into one jar?Gradle 可以将多个项目打包到一个 jar 中吗?
【发布时间】:2012-11-26 17:57:54
【问题描述】:

Gradle 可以将多个项目打包到一个 jar 中吗?

我知道您可以使用以下方法为单个项目执行此操作:

task packageTests(type: Jar) {
  from sourceSets.test.classes
}

但是一个人如何将多个子项目压缩到一个 jar 中呢?

我试过了,还是不行:

task packageTests(type: Jar) {
  from project(':core').sourceSets.main.classes
  from project(':core:google').sourceSets.test.classes
  from project(':core:bing').sourceSets.test.classes
}

【问题讨论】:

  • 您可以使用fatJar、OneJar 或application zip
  • 所有这 3 个都是 1 个特定于项目的。它们都不会压缩根项目及其所有子项目。
  • 所有这些都基于项目应用的模型以其他模型为依赖项。
  • OneJar 显然是一个压缩单个项目并在 .jar 中包含所有依赖项的项目。它并没有为我解决这个特殊问题。 “应用程序 zip”不起作用,因为 GitHub 已经为我做到了。我尝试了 fatJar,但指令不起作用,Gradle 无法编译我的脚本。
  • Gist 将 fatJar 应用到您的项目所需的更改。只需运行gradle fatJar

标签: java build gradle


【解决方案1】:

我知道已经回答了这个问题,但是由于答案很旧(当前的 Gradle 版本是几个较新的主要版本 - 6.2.2)并且该线程在搜索引擎中的出现率很高,我将发布对我有用的解决方案.

通常我的问题与原始帖子中所述的问题相似/相同:我想从所有子项目中获取类并将它们压缩到一个 jar 中(最好尽可能使用最默认的设置)。最后我发现下面的代码可以解决问题:

jar {
  from subprojects.sourceSets.main.output
}

但是虽然它可以正确构建 jar,但我还希望能够将此 jar 作为单个工件发布到 Maven 存储库,这取决于所有子项目所做的一切。为了实现这一点,主项目必须依赖子项目依赖项,由以下方式完成:

subprojects.each { evaluationDependsOn(it.path) }
dependencies {
  api(externalSubprojectsDependencies('api'))
  implementation(externalSubprojectsDependencies('implementation'))
}
private externalSubprojectsDependencies(String configuration) {
  subprojects.collect { it.configurations[configuration].allDependencies }.flatten()
      .findAll { !it.properties['dependencyProject'] } // this looks like hack, I'd love to see better solution
}

只有外部依赖项被复制 - 我们不希望在pom.xml 中列出内部(项目)依赖项,因为它们的所有类都在 jar 中。

【讨论】:

    【解决方案2】:

    下面的方案和CaTalyst.X提出的方案很相似,但是直接使用jar任务。

    subprojects.each { subproject -> evaluationDependsOn( subproject.path ) }
    jar.dependsOn subprojects.tasks['classes']
    jar {
      baseName = 'MyApp'
      manifest {
        attributes 'Main-Class': 'org.abc.App'
      }
      subprojects.each { subproject ->
        from subproject.sourceSets.main.output.classesDir
        from subproject.sourceSets.main.output.resourcesDir
      }
    }
    

    已针对 Gradle 2.1 和 2.2.1 进行了测试

    【讨论】:

      【解决方案3】:

      这是我的解决方案,稍微简单一点:

      // Create a list of subprojects that you wish to include in the jar.  
      def mainProjects = [':apps',':core',':gui',':io']
      task oneJar( type: Jar , dependsOn: mainProjects.collect{ it+":compileJava"}) {
          baseName = 'name of jar'
          from files(mainProjects.collect{ project(it).sourceSets.main.output })
      }
      

      代码已在 Gradle 1.12 上测试

      【讨论】:

      • 我有一个名为 buildRepackage 的任务,我认为这就是任务的作用,但我不能让一个 jar 可以在整个依赖项下运行。您知道它们是如何协同工作的,以及我如何为 Spring Boot 应用程序完成这项工作吗?
      【解决方案4】:

      这应该适用于您想要做的事情。这应该在根 gradle 构建文件中。

      subprojects.each { subproject -> evaluationDependsOn(subproject.path)}
      
      task allJar(type: Jar, dependsOn: subprojects.assemble) {
         baseName = 'your-base-name'
         subprojects.each { subproject -> 
            from subproject.configurations.archives.allArtifacts.files.collect {
               zipTree(it)
             }
          }
       }
      

      您可以通过将其添加为存档来发布它:

      artifacts {
         archives allJar
      }
      

      【讨论】:

      • 这个答案几乎回答了我的问题。它给了我很多我尝试过的想法,但我从来没有解决过。 gradle 编译器给了我错误:在 project 上找不到属性“assemble”。我试图以各种方式解决它,但不能。我正在使用 Gradle 1.2。我仍然充满希望并仍在努力。
      • 您可以尝试阅读 Gradle 上的文档。听起来您正在复制和粘贴,但没有任何效果。 'assemble' 是 java 插件提供给你的一个属性。如果您的子项目之一没有 java 插件,那么您将收到您提到的错误。
      • 我在“allprojects”部分添加了 java 插件。这不应该适用于我所有的子项目吗?无论如何,我专门将 java 插件添加到抱怨的项目中,但它没有帮助。今晚我会尝试在 GitHub 上放一个更简单的示例以获得更好的帮助。
      • 您好,我是 gradle 新手。当我尝试这个时,gradle 编译器给了我错误。在根项目“Gradle-Root”上找不到参数 [task ':allJar'] 的方法 archives()。请帮忙
      • 我有一个名为 buildRepackage 的任务,我认为这就是任务的目的,但我不能使一个 jar 可以在整个依赖项下运行。您知道它们是如何协同工作的,以及我如何为 Spring Boot 应用程序完成这项工作吗?
      猜你喜欢
      • 2018-07-30
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多