Generation of IntelliJ project files reorders dependencies

When generating project files for IntelliJ Gradle reorders dependencies in the files so that they do not match the order they are in the build file. This happened to me lately when importing https://github.com/grails/grails-data-mapping. I searched for the cause and found it in IdeaDependenciesProvider.java. The order of dependencies is project dependencies first, then repository dependencies and file dependencies last.
This is obviously a reordering. For demonstration purposes I constructed a case where this leads to a problem:

idea-dependency-demo.zip (2.5 KB)

If you gradle test your project everything is fine. Gradle prefers the newer version 19 and sets it as expected.
If you do a gradle idea, open and start the only test from inside IntelliJ you get an exception. Its cause is the reordering of the guava library. The IntelliJ project file for project a shows that the project dependency for project b was pushed to the front (not intented) and so was the Guava v18 dependency. The test was constructed specifically to use a feature of version 19 so it would fail with v18.

Now I know that it is bad to have two different versions of the same library in the project. But the demo was extreme. In grails-data-mapping, there were (probably, I did not dive in too much) minor version differences.

Two things I consider problematic:

  1. Generated files for IntelliJ do not benefit from the dependency version resolution. IntelliJ lists both versions of Guava as imported.
  2. Reordering of dependencies lead to differences in IntelliJ vs Gradle classpaths. If the reordering could be prevented somehow, libraries with differing versions could not have such a big impact. Maybe none at all.

Thank you for your attention.

1 Like

If anybody is interested in fixing this, the offending code is the design of the IdeDependenciesExtractor class - it provides the repo dependencies and local file dependencies in separate API calls, so there is no way for the IDE plugins to keep the relative ordering.

To get a better idea of the issue, see the usages of dependenciesExtractor IdeaDependenciesProvider#provideFromScopeRuleMappings()

P.S. Found my old post on the topic - Gradle messes up the classpath order in generated projects when there are mixed dependency types

1 Like