如何在Gradle中为自定义sourceSet指定output.classesDir?

时间:2016-05-19 20:09:22

标签: gradle jar

我的构建使用来自两个项目的源代码:ProjectA和ProjectB,并使用ProjectB中的类和资源生成JAR。我定义了自定义sourceSet mainProjectB,它应该在一个单独的目录中输出:

sourceSets {
    mainProjectB {
        output.classesDir = "$buildDir/build/classes/projectB"
        output.resourcesDir = "$buildDir/build/resources/projectB"
        java { srcDirs = ['src/main/java']}
        resources { srcDirs = ['src/main/resources']}
    }
    mainProjectA {
        java { srcDirs = [
                '../projectA/src/main/java'
            ]}
        resources { srcDirs = [
                '../projectA/src/main/resources'
            ]}
    }
    test {
        java {
            srcDirs = [
                '../projectA/src/test/java',
                'src/test/java'
            ]}
        resources {
            srcDirs = [
                '../projectA/src/test/resources',
                'src/test/resources'
            ]}
    }
}

compileJava {
    source sourceSets.mainProjectB.allJava
    source sourceSets.mainProjectA.allJava
}

processResources {
    from sourceSets.mainProjectB.resources
    from sourceSets.mainProjectA.resources
}

jar {
    from sourceSets.mainProjectB.output.classesDir
    from sourceSets.mainProjectB.output.resourcesDir
}

问题:自定义sourceSet mainProjectB加入指定的输出目录。 目录" $ buildDir / build / classes / projectB"和" $ buildDir / build / resources / projectB"没有创建,因此,JAR包含来自两个项目(而不是ProjectB)的文件。

更新:
项目A和B具有循环依赖性。这就是他们必须共享源代码的原因。

1 个答案:

答案 0 :(得分:1)

我会考虑使用子项目和项目来实现您的目标 - gradel docs。使用以下方法,您可以获取任何类型的jar文件,具体取决于您的构建:

group 'CoreProject'
version '1.0-SNAPSHOT'
subprojects {
    apply plugin: 'java'
    repositories {
        mavenCentral()
    }
}

project (':projectA') {

}

project (':projectB') {
    def generatedResources = "$buildDir"
    //in case you want resources and classes to be written to custom location where 
    //redefined paths are relative to projectB root folder 
    sourceSets {
        main {
            output.classesDir = 'build/classes/projectB'
            output.resourcesDir = 'build/resources/projectB'
        }
    }
    dependencies {
        compile project(':projectA')
    }
    jar {
        manifest.mainAttributes(
                'Main-Class': "ProjectBClass"
        )
    }

    //To create fat Jar that will contain classes and resources from all dependencies
    task fatJar(type: Jar) {
        manifest.from jar.manifest
        classifier = 'all'
        from {
            configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
        } {
            exclude "ProjectAResource" //if want to exclude resources from projectA
            exclude "META-INF/*.SF"
            exclude "META-INF/*.DSA"
            exclude "META-INF/*.RSA"
        }
        with jar
    }
}

如果您运行projectB的 jar任务,将创建​​以下jar,每个jars仅包含自己的类和资源: projectA / build / libs / projectA.jar ,< strong> projectB / build / libs / projectB.jar (正如您在评论中提到的那样,' JAR包含来自ProjectB的类和资源')

如果您运行projectB的 farJar任务,将创建​​以下jar文件,其中包含来自两个项目的类和资源,您可以从projectA和projectB项目中排除任何文件模式以创建任何最终的jar例如: projectB / build / libs / projectB-all.jar

这是我创建的项目文件夹结构的屏幕截图,模仿你的场景(据我所知): enter image description here

P.S。还要确保没有任何文件夹projectB / build和projectA / build被任何进程锁定,并删除那些句柄(如果有的话),否则Gradle将无法运行。