Dependency modification behaviour has been deprecated

During my build process I lookup and modify dependency configurations quite often. This is causing my builds to spit out errors like the following:

Attempting to resolve configuration ':project-struts:compile' that has been resolved previously. Changes made since the configuration was originally resolved are ignored. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0

Changed dependencies of configuration ':project-sap:runtime' after it has been included in dependency resolution. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0

Changed dependencies of configuration ':project-struts:providedCompile' after it has been included in dependency resolution. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0.

Changed dependencies of parent of configuration ':project-struts:compile' after it has been resolved. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0

Changed strategy of configuration ':project-struts:compile' after it has been resolved. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0

Changed dependencies of configuration ':project-struts:grettyProvidedCompile' after it has been included in dependency resolution. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0

I’m wondering what the proper way to access and update dependencies programmatically is, or when the best time is to do it in the build process. I can’t seem to find any documentation on this, and it appears it will be important to resolve in the near future.

when a task need a defined configuration, it is resolved, in order to get the artifacts + transitive artifacts declared by the dependency.

So any modification on a given configuration must be done before the configuration is needed, otherwise its resolution might lead to a different set of files, and a different behavior.

There is nothing more to say about that. Each configuration is different, and you can add your own ones. You just need to be sure NOT to change the configuration content once it’s resolved (which happens when the set of files corresponding to the configuration is queried)

well yes, that’s nice, but how do I go about doing that? From what I can
tell, all my tasks are executed after resolution occurs. How can I tell the
build script that my task is something that needs to happen first?

It’s hard to give more advice without looking at your build file.

Why are you modifying existing configurations during your task execution?
What are you trying to achieve with this logic?
Can’t you just create a new copy of the configuration, with the modification you want to perform?

this is one of my build files. The reason I do this is because SAP does not allow you to modify the jar name. They check it in static initializers and throw a runtime exception if you do. This code allows me to store a versioned JAR artifact in my local nexus repo but then renames the jar back to the unversioned “allowed” name before being included in the project dependencies.

configurations { prepareSAP }

task prepareSAP << {
    configurations.prepareSAP.resolvedConfiguration.resolvedArtifacts.each { artifact ->
        project.copy {
            from artifact.file
            into "libs"
            rename { "${artifact.name}.${artifact.extension}" }
        }
        project.dependencies.add 'runtime', files("libs/${artifact.name}.${artifact.extension}")
    }
}

compileJava.dependsOn prepareSAP

clean {
    delete fileTree('libs').include("*sap*")
}

dependencies {
    prepareSAP group: 'com.sap', name:'sapjco3', version:'3.0.13'
    //also works with non-jar depends
    //prepareSAP group: 'com.sap', name:'sapjco3', version:'3.0.13', classifier:'ntamd64', ext:'dll'
    //prepareSAP group: 'com.sap', name:'libsapjco3', version:'3.0.13', classifier:'linuxamd64', ext:'so'
    ... more depends
}

however, this causes the error message to come up as:

Changed dependencies of configuration ':project-sap:runtime' after it has been included in dependency resolution. This behaviour has been deprecated and is scheduled to be removed in Gradle 3.0

To ensure this is done before the runtime configuration gets resolved, you can try to use a beforeResolve

configurations.runtime.incoming.beforeResolve{
configurations.prepareSAP.resolvedConfiguration.resolvedArtifacts.each { artifact ->
project.copy {
from artifact.file
into "libs"
rename { “${artifact.name}.${artifact.extension}” }
}
project.dependencies.add ‘runtime’, files(“libs/${artifact.name}.${artifact.extension}”)
}}

And get rid of your prepareSAP.

Would this work and suit your need?

I have this now:

configurations { prepareSAP }

configurations.runtime.incoming.beforeResolve{
    configurations.prepareSAP.resolvedConfiguration.resolvedArtifacts.each { artifact ->
         println "*********** ${artifact.file} ************"
         project.copy {
            from artifact.file
            into "libs"
            rename { "${artifact.name}.${artifact.extension}" }
        }
        project.dependencies.add 'runtime', files("libs/${artifact.name}.${artifact.extension}")
    }
}

clean {
    delete fileTree('libs').include("*sap*")
}

dependencies {
    prepareSAP group: 'com.sap', name:'sapjco3', version:'3.0.13'
    //prepareSAP group: 'com.sap', name:'sapjco3', version:'3.0.13', classifier:'ntamd64', ext:'dll'
    //prepareSAP group: 'com.sap', name:'libsapjco3', version:'3.0.13', classifier:'linuxamd64', ext:'so'
   ... more depends
}

I ran ./gradlew clean test but when I check the libs directory, I don’t see any files, nor do I see output from the println

if I change it to compile.incoming.beforeResolve I get my dependency added to the lib dir and the output from the println, however, I once again get the deprecation warning about modifying the runtime configuration.

ok, so it appears the issue is that ‘testRuntime’ does not resolve ‘runtime’ directly, so when running tests, I need to update the testRuntime configuration as well. Here is my final draft:

ext.updateDepends = { artifact, config ->
    println "*********** $config : ${artifact.file} ************"
    project.copy {
        from artifact.file
        into "libs"
        rename { "${artifact.name}.${artifact.extension}" }
    }
    project.dependencies.add config, files("libs/${artifact.name}.${artifact.extension}")
}

configurations {
    prepareSAP
    runtime.incoming.beforeResolve{
        configurations.prepareSAP.resolvedConfiguration.resolvedArtifacts.each { artifact ->
            project.updateDepends(artifact,'runtime');
        }
    }
    testRuntime.incoming.beforeResolve{
        configurations.prepareSAP.resolvedConfiguration.resolvedArtifacts.each { artifact ->
            project.updateDepends(artifact,'testRuntime');
        }
    }
}

Is there a way to simplify this further, or is that about as good as it will get?