Gradle:将多项目打包成一个jar

时间:2018-02-20 14:51:43

标签: gradle fatjar

我有一个gradle多项目,想要创建一个包含我的子项目和外部依赖项的所有类的jar(库)。

我有以下项目结构。每个项目都有自己的第三方依赖项。常见依赖项包含在根项目中。两个模块A和B依赖于核心。

+ root-project (only build.gradle and settings.gradle)
  - core       (src/main/java, src/main/resources, ..)
  - module-A   (src/main/java, src/main/resources, ..)
  - module-B   (src/main/java, src/main/resources, ..)

要导出单个jar,我将以下任务添加到根项目的build.gradle中:

apply plugin: "java"

subprojects.each { subproject -> evaluationDependsOn(subproject.path)}

task allJar(type: Jar, dependsOn: subprojects.jar) {
    baseName = 'multiproject-test'
    subprojects.each { subproject ->
        from subproject.configurations.archives.allArtifacts.files.collect {
            zipTree(it)
        }
    }
}

artifacts {
    archives allJar
}

此方法有效,但仅收集项目源文件。第三方依赖项将被忽略。所以我尝试了Shadow Plugin(http://imperceptiblethoughts.com/shadow/),它也应该包含外部依赖项。

不幸的是,该插件根本不收集任何东西。这很可能是由于根项目及其子项目之间缺少依赖关系。如何告诉影子插件,它应该收集子项目的来源?或者有更好的方法从多个项目中导出单个库吗?

使用shadow插件完成build.gradle:

/****************************************
 * instructions for all projects
 ****************************************/
allprojects {
    apply plugin: 'idea'
    apply plugin: 'eclipse'

    group = 'com.test.multi-project'
    version = '1.0'
}

/****************************************
 * instructions for each sub project
 ****************************************/
subprojects {
    apply plugin: "java"

    sourceCompatibility = 1.9
    targetCompatibility = 1.9

    repositories {
        mavenCentral()
    }

    dependencies {
        compile "org.slf4j:slf4j-api:1+"
        compile "ch.qos.logback:logback-core:1+"
        compile "ch.qos.logback:logback-classic:1+"

        testCompile "junit:junit:4+"
    }
}

/****************************************
 * Single jar out of all sub projects
 ****************************************/
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.2'
    }
}

apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'java'

shadowJar {
    baseName = 'multiproject-test'
} 

子模块包含在根项目的settings.gradle中

rootProject.name = 'myproject-root'

// submodules
include ":core"

include ":module-A"
include ":module-B"

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

如此简单的事情:

task fatJar(type: Jar) {
    subprojects.each { subproject ->
        from subproject.configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

答案 1 :(得分:1)

我用这里解释的解决方案解决了我的问题:https://discuss.gradle.org/t/how-to-get-gradle-install-to-actually-bundle-all-project-subproject-classes-resources-etc/12070/4

我的build.gradle现在看起来像这样:

/****************************************
 * instructions for all projects
 ****************************************/
allprojects {
    apply plugin: 'idea'
    apply plugin: 'java'

    repositories {
        mavenCentral()
    }

    group = 'com.test.multiproject'
    version = '1.0'

    sourceCompatibility = 1.9
    targetCompatibility = 1.9
}

/****************************************
 * instructions for each sub project
 ****************************************/
subprojects {

    // common dependencies
    dependencies {
        compile "org.slf4j:slf4j-api:1+"
        compile "ch.qos.logback:logback-core:1+"
        compile "ch.qos.logback:logback-classic:1+"

        testCompile "junit:junit:4+"
    }
}

/****************************************
 * Single library jar containing all sub projects and 3rd party dependencies
 ****************************************/
configurations {
    childJars
}

dependencies {
    subprojects.each {
        childJars project(it.path)
    }
}

jar {
    dependsOn configurations.childJars
    from { configurations.childJars.collect { zipTree(it) } }
}

答案 2 :(得分:0)

如何在构建jar本身时获取所有运行时库

jar {
    archiveName 'Some.jar'

    manifest {
        attributes 'Implementation-Title': 'Some',
        'Plugin-Class': 'main'
    }
    from {configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it)}}
}