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

我的构建使用来自两个项目的源代码: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具有循环依赖性.这就是为什么他们必须共享源代码.

最佳答案 我会考虑使用子项目和项目来实现你的目标 –
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
    }
}

如果你运行jarB的jar任务,那么将创建jars,每个jar只包含自己的类和资源:projectA / build / libs / projectA.jar,projectB / build / libs / projectB.jar(‘JAR包含来自ProjectB的类和资源’正如你在评论中提到的那样)

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

这是我创建的项目文件夹结构的屏幕截图,模仿你的场景(据我所知):
《如何在Gradle中为自定义sourceSet指定output.classesDir?》

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

点赞