Gradle messes up the classpath order in generated projects when there are mixed dependency types

Consider the following build:

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'eclipse'

repositories {
    jcenter()
}

dependencies {
    compile files('lib/foo.jar')        
    compile 'org.slf4j:slf4j-api:1.7.13'
}

task dumpClassPath(dependsOn: ['idea', 'eclipse']) {
    doLast {
        println "Gradle classpath:\n- " + configurations.compile.files*.name.join("\n- ")
        println "-------\n"
        println "IDEA classpath: \n- " + file(project.name + ".iml").readLines()
                .grep(~/.*"jar:.*/).collect { it.split("[\\/]")[-3].trim() }.join("\n- ")
        println "-------\n"
        println "Eclipse classpath: \n- " + file(".classpath").readLines()
                .grep(~/.*kind="lib".*/).collect { it.split("[\\/]")[-2].trim() }.join("\n- ")
    }
}

defaultTasks = ['dumpClassPath']

It is supposed to produce the same dependencies in the same order for the Gradle, IDEA, and Eclipse cases, but in practice, the dependencies specified as local files are ordered correctly for Gradle and come always at the back for the IDE’s. In our case this was leading to tests mysteriously failing in Eclipse (for whatever reasons, this build we are using local file to shadow some classpath).

» gradle -q

Gradle classpath:
- foo.jar
- slf4j-api-1.7.13.jar
-------

IDEA classpath:
- slf4j-api-1.7.13.jar!
- slf4j-api-1.7.13-sources.jar!
- foo.jar!
-------

Eclipse classpath:
- slf4j-api-1.7.13.jar"
- foo.jar"

On the other hand, if we import the Gradle project in IDEA, the classpath is imported correctly, which leads me to believe that it is a problem in the Gradle project generation tasks.

The problem actually stems from the ClasspathFactory implementation.

In particular, the librariesCreator is putting the local files after the repo dependencies. And project dependencies are always at the start of the classpath.

Considering that the only reason to check-in a dependency would be that you can not get it from a repo, I would suggest that changing librariesCreator to put the local files before the repo dependencies would be “less broken” than the status quo.

Of course, it would be best if we can retain the precise classpath order, though that would require a deeper change.