13

I have two Gradle projects, let's call them Blue and Green. Green depends on Blue, as declared in its build.gradle:

repositories {
  mavenLocal()
}

dependencies {
    compile 'org.example:blue:1.0'
}

Blue uses the Maven plugin to build the appropriate artifact:

apply plugin: 'maven'
group = 'org.example'
version = '1.0'

If I run the install task on Blue, it creates a JAR and a POM and puts them in my ~/.m2/repository, no problem.

I import Blue's build.gradle into my IDEA project, and it creates a module for Blue, again no problem.

If I now import Green's build.gradle into my IDEA project, it creates a module for Green, picks up the Mavenized version of Blue from the repository, creates a corresponding library, and adds the Blue library to the Green module as a dependency.

However, if I now make a code change in Blue, that code change isn't picked up in Green. Green is going to continue to use the now-stale copy from the Maven repository. The only way to get the Blue changes is to re-install Blue, and as for refactoring something in Blue and having the refactoring cover the usages in Green, forget about it. Problem.

How can I get IDEA to recognize the interdependencies between my Gradle projects and their corresponding IDEA modules?


Edited to add: Multi-module isn't really an option because the dependencies in question are shared between multiple application projects (not to mention other shared-library projects) and don't fit neatly into a single hierarchical directory structure.


Edited to add: For a pointer to what I eventually came up with, see this answer. It still requires manually creating multi-module projects when you want to work on both a project and its dependencies, but it lets you swap source and binary dependencies in and out more or less freely.

Community
  • 1
  • 1
David Moles
  • 48,006
  • 27
  • 136
  • 235
  • Official response from JetBrains support: "Such setup (on a jar library) will not work. You'll meet the same problem if build 'green' from Gradle. You need to make use of Gradle multi module setup." – David Moles Apr 24 '14 at 21:16
  • 3
    Please vote for https://youtrack.jetbrains.com/issue/IDEA-134885 :) – Hendy Irawan Dec 30 '14 at 14:50
  • May be this is what you have been waiting for: https://docs.gradle.org/current/userguide/composite_builds.html – darwinbaisa Oct 25 '16 at 09:37
  • is this still a problem with the latest versions? – Rüdiger Schulz Apr 02 '18 at 21:23
  • @RüdigerSchulz I couldn't tell you -- I'm not working at that job any more, and the things I work on now are self-contained enough to use multi-module projects. – David Moles Apr 03 '18 at 00:13

2 Answers2

6

Discovered the following workaround:

After importing Green's build.gradle, open Module Settings for the Green module (or select it under Project Structure). Then, on the Dependencies tab, manually add the 'live' dependencies and move them above the Gradle versions in the list:

screenshot of manually-added 'live' dependencies

This will persist even through a "Refresh external project" on Green's build.gradle, which is helpful when you're editing it to add third-party libraries etc.

Note that you can delete the Gradle versions (Gradle: blue-2.0-snapshot etc.), but they'll get re-added when you refresh the project.

Also worth noting: This will let you live-edit and refactor Blue, Yellow, and Green together, but if you need to do a Gradle build for any reason (e.g. if you're using Gradle's jettyRun task to launch a webapp), you'll need to make sure you Gradle-install Blue and Yellow, because (as long as we're not talking about a multi-module project) Gradle is only ever going to use the canned versions from the repo.

David Moles
  • 48,006
  • 27
  • 136
  • 235
  • Since this is error prone and something what should be shared by all teammembers I'd suggest to automate this modifications with XML hooks where you can rewrite dependencies generated by Gradle IDEA plugin. See http://www.gradle.org/docs/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html – Radim Jun 04 '14 at 09:23
  • What I eventually went with was a script to cobble together multi-module gradle projects on the fly, along with `build.gradle` and `settings.gradle` files that (assuming a known directory structure and naming scheme) would automatically detect any dependencies that were present as local source and replace them at resolution time. Then IDEA can just import the synthetic top-level project's `build.gradle` as normal. – David Moles Jun 13 '14 at 17:23
  • 2
    Unfortunately in IDEA 2017.2 this no longer works: After doing a gradle refresh (and (auto-)saving) the manually added module dependencies are lost. – eekboom Jun 22 '17 at 08:52
2

Perhaps it would be better for you to create a Gradle build with two sub-projects and then both Gradle and IDEA will pick up the changes immediately.

The other possibility is to replace the dependency on a JAR in .m2/repository with JAR file in build of your Blue project or better yet with a module dependency. Then you can skip the publication step. You can do this manually or put it into build.gradle as IDEA module customization - http://www.gradle.org/docs/current/userguide/idea_plugin.html

Radim
  • 4,721
  • 1
  • 22
  • 25
  • 2
    In practice, we have dozens and dozens of shared-code library projects that can be combined in various ways under a smaller number of top-level application projects, so I don't know how feasible the sub-project approach is. As for replacing the JAR dependency with a module dependency, yes, that's exactly what I want, but I don't want developers to have to do it by hand. I should look into the IDEA plugin though, my understanding was that it had been superseded in 13 by JetGradle but it looks like they actually do fairly different things. – David Moles Apr 21 '14 at 20:43
  • FWIW, I eventually came up with a fairly baroque and site-specific system for creating multi-module gradle projects on the fly and replacing their dependencies programmatically. – David Moles Jun 02 '14 at 16:51
  • @DavidMoles would you be able to share your solution, if it involves using the Gradle idea plugin? – Καrτhικ Mar 25 '16 at 13:03
  • @Καrτhικ I don't use the Gradle IDEA plugin -- I prefer just having IDEA load the `build.gradle` with "New project from existing sources". I'm not working any more at the company I was at when I developed that hack, but the basic outline of it is in [this answer](http://stackoverflow.com/a/23574904/27358). – David Moles Mar 28 '16 at 18:14