Eclipse classpath contains all gradle dependencies as libraries

I’m using the eclipse plugin for gradle. Here’s my build.gradle file:

apply plugin: 'java'
apply plugin: 'eclipse'
  sourceCompatibility = 1.5
version = '1.0'
jar {
 manifest {
  attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
 }
}
  repositories {
 mavenCentral()
}
  dependencies {
 compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
 testCompile group: 'junit', name: 'junit', version: '4.+'
}
  test {
 systemProperties 'property': 'value'
}
  uploadArchives {
 repositories {
  flatDir {
   dirs 'repos'
  }
 }
}
  eclipse {
   classpath {
  containers 'org.springsource.ide.eclipse.gradle.classpathcontainer'
}

When the eclipseClasspath is executed I get all gradle dependencies in two places:

  • in the Gradle Dependencies folder

  • and as separate libraries:

And this is my .classpath file:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
 <classpathentry kind="src" path="src/main/java"/>
 <classpathentry kind="src" path="src/main/resources"/>
 <classpathentry kind="src" path="src/test/java"/>
 <classpathentry kind="src" path="src/test/resources"/>
 <classpathentry exported="true" kind="lib" path="C:/Users/drusev/.gradle/caches/modules-2/files-2.1/commons-collections/commons-collections/3.2/f951934aa5ae5a88d7e6dfaa6d32307d834a88be/commons-collections-3.2.jar" sourcepath="C:/Users/drusev/.gradle/caches/modules-2/files-2.1/commons-collections/commons-collections/3.2/73d0340eaecbb0ec9d3e0ace90547ef08cbfaf27/commons-collections-3.2-sources.jar"/>
 <classpathentry exported="true" kind="lib" path="C:/Users/drusev/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar" sourcepath="C:/Users/drusev/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/28e0ad201304e4a4abf999ca0570b7cffc352c3c/junit-4.11-sources.jar"/>
 <classpathentry exported="true" kind="lib" path="C:/Users/drusev/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar" sourcepath="C:/Users/drusev/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar"/>
 <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 <classpathentry exported="true" kind="con" path="org.springsource.ide.eclipse.gradle.classpathcontainer"/>
 <classpathentry kind="output" path="bin"/>
</classpath>

Why does this happen? I can fix the problem if I add the following code to the build.gradle file:

file {
 whenMerged { classpath ->
  classpath.entries.removeAll { entry ->
   entry.kind == 'lib'
  }
 }
}

Is there any other way to fix the problem?

How are you integrating with Eclipse? Are you perhaps mixing running ‘gradle eclipse’ and using the STS Gradle plugin? Which versions of Gradle and the STS plugin are you using?

I’m using Gradle IDE, version 3.5.1.201404300713-RELEASE, id: org.springsource.ide.eclipse.gradle.feature.feature.group, provided by Pivotal Software, Inc. and my gradle installation is 1.9

And how do you import the build. Do you ever run ‘gradle eclipse’?

No, I created the project, using the Eclipse Gradle Wizard File -> New -> Project -> Gradle Project, and I refresh the dependencies by clicking on the project with the right mouse button -> Gradle -> Refresh All, which executes the tasks cleanEclipse and eclipse. So eventually, yes, I do use gradle eclipse.

IMO you can opt for one of the few approaches:

  • to use STS plugin with or without its classpath container. You can get there if you remove eclipse.classpath.container and whenMerged hooks and import the project into Eclipse using plugin import wizard. You do not have to run ‘gradle eclipseClasspath’ then and you will just update (synchronize) the project inside Eclipse.

  • use ‘gradle eclipseClasspath’ and again avoid eclipse.classpath.container in your Gradle script

BTW: Out of curiosity - why did you add that container there? Is there any documentation suggesting to do this?

If I remove the container, then the “Gradle dependencies” folder disappears, and Eclipse doesn’t recognize any of the gradle dependencies. I’d like to hear more about this plugin import wizard.

I suppose you removed the container and the hook that call removeAll() on you lib entries. And the STS plugin add some settings to your project whether to use classpath container or not that is separate from what you have in build.gradle.

https://github.com/spring-projects/eclipse-integration-gradle/wiki can have some documentation.

Yes, I removed the hook, and when I click gardle -> refresh All on the project, the dependencies appear right under the project node, not under a “gradle dependency” folder. If there are many dependencies, that would be a problem. I’d like the dependencies to be neatly ordered in a folder.

If I understand correctly, using the container and executing

gradle eclipseClasspath

are mutually exclusive, I should choose one of these two options, right?

STS plugin uses Gradle Tooling API to obtain project classpath and then generates .classpath file with container element and keeps data how to expand container into classpath entries in memory. Or it creates .classpath with usual lib entries. Tooling API asks Gradle Eclipse plugin to get classpath information. And that’s the problem as you try to add container there and delete the actual classpath entries. So either you have container added by Gradle and STS plugin or you miss the classpath.