Gradle能否将多个项目打包成一个jar文件?

9
可以使用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 - Ben Manes
这三个都是针对一个项目的。它们都不能压缩一个根项目及其子项目。 - djangofan
所有这些工作都基于项目应用的模型,其中其他项目是依赖项。 - Ben Manes
OneJar 明显是一个将单个项目压缩并包含所有依赖项在 .jar 文件中的项目。但它并不能解决我的这个问题。"应用程序 zip" 不起作用,因为 GitHub 已经为我做了这件事。我尝试过 fatJar,但指令不起作用,而且 Gradle 无法编译我的脚本。 - djangofan
将fatJar应用于您的项目所需的更改的Gist。只需运行gradle fatJar即可。 - Ben Manes
代码唯一的问题是.classes不是maintest的成员。从IDE中,您可以从下拉菜单中看到输出。 - Leon
4个回答

8
这应该可以满足你的需求。这应该在根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编译器给了我一个错误:“在项目上找不到属性'assemble'”。我尝试了各种方法来解决它,但是没有成功。我正在使用Gradle 1.2版本。我仍然保持希望并继续努力。 - djangofan
你可以尝试阅读有关Gradle的文档。听起来你正在进行复制粘贴,但什么都不起作用。“assemble”是Java插件提供给您的一个属性。如果您的子项目之一没有安装Java插件,则会出现您提到的错误。 - CaTalyst.X
我已经在“allprojects”部分添加了Java插件。这不应该适用于所有子项目吗?无论如何,我特别将Java插件添加到了发出抱怨的项目中,但没有起作用。今晚我会尝试将一个更简单的示例放到GitHub上以获得更好的帮助。 - djangofan
嗨,我是Gradle的新手。当我尝试这个时,Gradle编译器给了我一个错误。在'Gradle-Root'根项目上找不到方法archives(),参数为[task ':allJar']。请帮忙解决。 - Captain Buck
我有一个名为 buildRepackage 的任务,我认为这就是任务所执行的内容,但是我无法将一个包含所有依赖项的 jar 文件运行起来。您知道它们如何协同工作,以及我如何为 Spring Boot 应用程序完成此操作吗? - Dimitri Kopriwa

8

这是我的解决方案,相对简单一些:

// 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应用程序完成此操作吗? - Dimitri Kopriwa

4
下面的解决方案与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进行了测试。


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中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接