4

We're moving from Maven to Gradle and are struggling with one thing. We have a multi-project Gradle-project based on the POMs from Maven. Most of it works fine, but we cannot find out a way to collect the WAR-files and ZIP-files which are the result from building the sub-projects. Each sub-project represents a micro service. We have found (also on Stackoverflow) ways to collect all of the jars and third party libs into a directory. However, we are looking for a way to collect the resources and libraries per micro service. In Maven we did something like this:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.0.0</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>Publish/</outputDirectory>
                        <artifactItems>
                            <artifactItem>
                                <groupId>....</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>zip</type>
                            </artifactItem>
                            <artifactItem>
                                <groupId>....</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>war</type>
                            </artifactItem>

I would like to end up with a directory where I can find:

project1.war
project2.war
project3.zip
etc.
Pieter
  • 3,339
  • 5
  • 30
  • 63

2 Answers2

3

In each of the projects which produce an artifact (eg zip) you'll add the artifact to a configuration. See artifact management

eg:

configurations {
   archives
}
task myZip(type: Zip) { ... }
artifacts {
   archives myZip
}

Then, in the uber project you'll use another configuration to reference the artifacts and a zip task to bundle them

configurations {
   uber
}
dependencies {
   uber project(path: ':project1', configuration: 'archives')
   uber project(path: ':project2', configuration: 'archives')
   uber project(path: ':project3', configuration: 'archives')
}
task uberZip(type: Zip) {
   from configurations.uber
   archiveName 'uber.zip'
   destinationDir "$buildDir/uber"
}    
lance-java
  • 25,497
  • 4
  • 59
  • 101
  • 1
    Looks interesting as it uses built-in functionality. However, I don't want an uber-zip, but rather several default artifacts (WARs and ZIPs) copied to a central directory. I don't know if that is also possible with these functions? – Pieter Aug 20 '17 at 14:50
  • 1
    Simple, just replace the `uberZip` task with an `uberCopy` task of type `Copy`. You can keep the `from` clause – lance-java Aug 20 '17 at 17:47
1

The following solution is hand-rolled but is simple, and offers flexibility if you need to tweak anything.

Below is a build.gradle in the root directory. For each subproject, it will:

  • Define a copyArtifacts task that copies war and zip files from the subproject's build/libs folder (using appropriate baseName, version, etc) to root/dist.
  • If a war task is found, then configure it so that it runs copyArtifacts afterwards.

This can be easily changed to look for other task names, match different filenames, etc. (One might want to delete older versions of a given artifact before the copy, and so on.)

subprojects { Project subProject ->
    task copyArtifacts {
        doLast {
            def baseName = subProject.archivesBaseName
            def version = subProject.version
            def group = subProject.group
            def DIST_DIR = "${rootDir}/dist"
            def SRC_DIR = "${buildDir}/libs"

            ant.mkdir(dir: DIST_DIR)
            ant.copy(todir: DIST_DIR) {
                fileset(dir: SRC_DIR,
                includes: "${baseName}*${version}*.war,${baseName}*${version}*.zip")
            }
        }
    }

    afterEvaluate {
        def warTask = subProject.tasks.find { it.name == 'war' }
        if (warTask) { 
            warTask.finalizedBy(copyArtifacts)
        }
    }
}
Michael Easter
  • 23,733
  • 7
  • 76
  • 107
  • This almost works, but ZIPs are stored in the distributions-directory. I've added a second tasks for projects which built a ZIP. It works and I only needed to change the main build.gradle and not any of the subprojects. That's seems easier to manage. – Pieter Aug 20 '17 at 14:51