Search code examples
javagradlewarear

gradle build<ConfigurationName>: different packaging for ear and war (gradle v2.3)


I want to use gradle v2.3 configurations to package my application in two ways:

  1. ear with all libs in ear's lib directory and multipe wars inside ear (deps declared with providedCompile and earlib)
  2. multiple war files with libs included in each war in WEB-INF/lib (deps declared with compile)

I can perform each of those two tasks if i modify build.gradle files every time I want different packaging. I would like to use configurations to choose if jars are included in war files or not by using gradle build<ConfigurationName>.

Based on help and StackOverflow post How to use uploadConfigurationName and buildConfigurationName I composed the following file (this is for one of the wars):

apply plugin: 'war'

configurations {
        packEar
        packWar
    }

dependencies {
    configurations.packEar {
        providedCompile project(':Common') // jars will be included using earlib
    }

    configurations.packWar {
        compile project(':Common') // jars included in war
    }
}

artifacts {
        packWar war
        packEar war
}

The problem is that commands gradle buildpackWar and gradle buildpackEar produce equal wars that do not include jars from Common project. If I change configuration of packEar from providedCompile to compile both produce war with jars included.

Additional info: I tried using extendFrom compile / providedCompile but it didnt seem to affect anything. I included buildpackWar and buildpackEar methods but it didn't work either (might have been that I used those in a wrong way).

Thank you for your answers!

Best regards, Ziga


Solution

  • using the info provided by Ben Navetta I managed to produce a working configuration, it only required a few minor adjustments. Here are the files

    ACL war

    apply plugin: 'war'
    
    apply plugin: 'eclipse-wtp'
    
    configurations {
        shareable
        publishedWar // need this so war gets placed in ear instead of jar, 
                     // using archives puts both wars in ear
    }
    
    dependencies {
        providedCompile project(':Common');
        shareable project(':Common');
    }
    
    war {
        baseName = war.baseName + '-thin'
        classpath = war.classpath
    }
    
    task standaloneWar(type: War, dependsOn: war) {
        baseName = project.name  // sharable war's name without modifications
        classpath = war.classpath + configurations.shareable
    }
    
    artifacts {
        archives standaloneWar
        publishedWar war // to be included in ear
    }   
    

    Note:

    1. if providedCompile project(':Common'); is omitted this will not compile
    2. I added war {...} so I can rename the war which does not contain any of the dependencies and have name of the war which contains dependencies without modifications in its name

    EAR

    apply plugin: 'ear'
    
    evaluationDependsOn ':ACL' // probably not needed
    
    dependencies {
        deploy project(path: ':ACL', configuration: 'publishedWar')
        earlib project(path: ':ACL', configuration: 'shareable')
    }  
    
    ear {
        deploymentDescriptor {  
            webModule ('ACL-thin.war', "${project.name}/ACL") // set context root        
        }
    } 
    

    Note:

    1. if publishedWar configuration is not applied jar is placed in ear
    2. if archives is used both wars get places in ear
    3. if you use eclipse plugin consider changing earlib project(path: ':ACL', configuration: 'shareable') changing to earlib project(':Common') or you will have to modify deployment assembly in eclipse (the war will be included in ear's lib folder in eclipse