How to configure Ear deployment descriptor lazy?

Hi,

we use Ear files and deploy some EJB and some WEB modules to them. We also need to adjust the context-root of the web modules. We usually configure them like this:

apply plugin: 'ear'

repositories { ... }

dependencies {
    deploy 'myorg:some-web:1.0.+'
}

ext {
    contextRoots = [
        'some-web' : '/webroot'
    ]
}

ear {
    deploymentDescriptor {
        configurations.deploy.files.each { moduleFile ->
            if (moduleFile.name.endsWith('war')) {
                def moduleContext = contextRoots.find { moduleFile.name.startsWith(it.key) }

                webModule(moduleFile.name, moduleContext.value)
            }
        }
    }
}

now the problem with this solution is, that we need to resolve the deploy configuration at configuration time only to configure the right context-paths.

While this was only a performance problem in the past, we now need to duplicate web modules to have them deployed to different context-roots.
So we tried to have a new dependency configuration with the duplicated modules, download them and rename the wars with a given pattern only to reuse the local directory as a flat repository and add the renamed files to the deploy configuration. But now we have the problem that configuring the project already resolves the deploy configuration, wich fails as the duplicated modules have not been downloaded and renamed yet.

configurations { duplicates }
repositories {
    flatDir {
        dirs 'build/lib'
    }
   ...
}
dependencies {
    duplicates 'myorg:some-web:1.0.+'
    deploy 'myorg:some-web:1.0.+'
    deploy 'myorg:some-web-2nd:1.0.+'
}
// this will never be callable, as the deploymentDescriptor configuration
// tries to resolve the deploy configuration wich is incomplete and will fail
task prepareDuplicates(type: Copy){
    from configurations.duplicates
    into 'build/lib'
    // Use a regular expression to map the file name
    rename ('(.*)web(.*)war', '$1web-2nd$2.war')
}

I guess one way to solve our problem would be to be able to map the context-roots for the deploymentDescriptor only when they are needed (lazy) and not during the configuration phase. This would also improve configuration time in general wich is very welcome!
Does anyone know how to do that or is there a simpler way to deploy wars under 2 context-roots ?

kind regards
Daniel

Ok I found a way to do it by manipulating the xml, as this is done after the application.xml has been generated the closure is somewhat lazy (it is still called 3 times in a clean project??) by nature:

ear {
    deploymentDescriptor {
        withXml { provider -> 
            def rootElement = provider.asElement()
            for(def contextElement : rootElement.getElementsByTagName('context-root')) {
                println contextElement.getTextContent()
                def moduleContext = contextRoots.find { contextElement.getTextContent().startsWith(it.key) }
                contextElement.setTextContent(moduleContext.value)
            }
        }
    }
}

Very strange is, that it is impossible to modify (adding works, but not changing something already generated) the xml via the documented (https://docs.gradle.org/current/userguide/ear_plugin.html#sec:ear_customizing) provider.asNode() API (Gradle Version 5.5.1), as this does not provide access to the already generated xml, only the asElement method works as expected, maybe a Dev can explain why and maybe update the documentation for others.

Hope this helps someone.