# 'testFixtures' don't work with 'implementation' in Eclipse only

**URL:** <https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275>\
**Category:** Buildship\
**Created:** [December 16, 2023, 12:53am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275 "2023-12-16T00:53:57Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [December 16, 2023, 12:53am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/1 "2023-12-16T00:53:57Z")

</div>

As has been reported by posts such as

> <https://github.com/gradle/gradle/issues/21853>
>
> Classes from \`src/main/java\` in projects containing text fixtures can no longer …be resolved in Eclipse (i.e. \`Xyz cannot be resolved to a type\`). It works with 7.4.2, but does not work with 7.5 or 7.5.1.
> 
> \### Expected Behavior
> Eclipse should be able to resolve the classes, as it previously did.
> 
> \### Current Behavior
> The classes from \`src/main/java\` cannot be resolved in Eclipse.
> 
> \### Context
> 
> 
> 
> \### Steps to Reproduce 
> 1. Clone https://github.com/mweber03/gradle-test
> 2. Import into Eclipse
> 4. In Eclipse, \`Gradle \> Refresh Gradle Project\` (note the clean build, no red Xs on classes)
> 5. Upgrade project to Gradle 7.5.1 (\`./gradlew wrapper --gradle-version 7.5.1\`)
> 6. In Eclipse, \`Gradle \> Refresh Gradle Project\` (note classes can no longer be resolved)
> 
> \### Your Environment
> Build scan URL: https://gradle.com/s/lpfpi33q6j54o

> <https://github.com/eclipse/buildship/issues/1206>
>
> \### Expected Behavior
> Eclipse compiles if I use testImplementation testFixtures… and implementation of the same project as it does with \`Gradle 7.4.2\`!
> 
> \### Current Behavior
> As soon as I need the above listed configurations, Eclipse doesn't compile successful.
> 
> \### Context
> A minimal setup to reproduce is present here: https://github.com/BisonSchweizAG/gradleproblem/tree/main
> 
> \### Steps to Reproduce 
> Clone above project, import into Eclipse --\> will not compile!
> Build on command line will work.
> Remove needed line \`testImplementation testFixtures(project(':projectA'))\` from \`build.gradle\` --\> Eclipse compiles, command line build won't!
> 
> \### Your Environment
> \`\`\`
> Eclipse:
> Version: 2022-06 (4.24.0)
> Build id: 20220609-1112
> 
> Gradle: 7.5.1
> 
> Buildship: 3.1.6.v20220511-1359
> \`\`\`

> <https://github.com/redhat-developer/vscode-java/issues/2784>
>
> Hi, I have a multi-modules gradle/java project in which I'm trying to centralize… some test fixtures (aka test helper classes to help build test data etc) in some kind of library module, so that those java test fixtures classes can then be shared in multiple dependant modules (I'm referring precisely to this \[gradle test fixtures feature\](https://docs.gradle.org/current/userguide/java\_testing.html#sec:java\_test\_fixtures)).
> 
> The problem I'm having in VS Code (with the Java extension) is that once I've defined my test fixtures in the lib module (see steps to reproduce below), as soon as I try to "consume" them by adding the dependency in a gradle dependant module build file (\[as explained here in gradle doc\](https://docs.gradle.org/current/userguide/java\_testing.html#consuming\_test\_fixtures\_of\_another\_project)), something like:
> \`\`\`
> dependencies {
> implementation(project(":lib-module"))
> 
> testImplementation(testFixtures(project(":lib-module")))
> }
> \`\`\`
> it will create compile errors under the vs code Problems tab that the dependant module can no longer see any dependency imports made by the basic \`implementation(project(":lib-module"))\`.
> 
> However, if I build everything with gradle, it will work just fine. The reported compile errors are only visual, within the Problems tab of the vscode editor.
> 
> Then, if I comment out the gradle testFixtures dependency import as follow:
> \`\`\`
> dependencies {
> implementation(project(":lib-module"))
> 
> //testImplementation(testFixtures(project(":lib-module")))
> }
> \`\`\`
> all compile errors will be gone from the vs code Problems tab, BUT, then if I try to run a gradle build task, it will fail saying that my tests no longer have access to the test fixtures imports from the lib module.
> 
> This seems to me like an issue with the vscode-java extension (or upstream?) not supporting properly the gradle testFixtures feature, preventing us from sharing in a very simple way test fixtures among multiple modules.
> 
> 
> \##### Environment
> Operating System: macOS big sur (11.6.5)
> JDK version: openjdk version "17.0.4.1" 2022-08-12
> Visual Studio Code version: 1.71.0
> Java extension version: 1.12.0
> 
> \##### Steps To Reproduce
> 1. Create a multi-modules gradle java project (2 modules should be enough, the lib exposing both normal lib utility/service classes and also test fixtures)
> 2. Create one normal utility class in the lib module, can be just a simple pojo... (\`\<lib-module\>/src/main/java/com/...\`)
> 3. Create one test fixture class also under the lib module, can be just a simple pojo... (\`\<lib-module\>/src/testFixture/java/com/...\`)
> 4. Add the gradle test Fixtures plugin under your lib gradle build file (\`\<lib-module\>/build.gradle\`)
> \`\`\`
> plugins {
> // A Java Library
> id 'java-library'
> // which produces test fixtures
> id 'java-test-fixtures'
> }
> \`\`\`
> 5. In the second dependant module, create one normal class that will consume/import the utility class from the lib module created in step 2 (\`\<dependant-module\>/src/main/java/com/...\`)
> 6. In the second dependant module, create a test class that will consume/import the test fixture class from the lib module created in step 3 (\`\<dependant-module\>/src/test/java/com/...\`), the test class can just be a simple pojo, no need to import any test framework for this, we're just testing dependencies between gradle modules...
> 7. Add the dependencies under the dependant module's gradle build file, so that it sees both the utility class AND the test fixture class from the lib module (\`\<dependant-module\>/build.gradle\`):
> \`\`\`
> dependencies {
> implementation(project(":lib-module"))
> 
> testImplementation(testFixtures(project(":lib-module")))
> }
> \`\`\`
> 8. Save everything, and you should expect to see compile errors in the vs code Problems tab, complaining about the fact that your dependant module's normal pojo class created in step 5 is unable to import the utility class from the lib module (that's right, the error might not even be inside your test class, but it could, it all depends where you've imported the lib utility class in this example, whether it's within the normal class in step 5, but it could have been under your test class of step 6 too; bottom line is, the compile error will be related to the normal lib classes that can no longer be imported in the dependant module(s); the test fixtures classes 'are' being imported properly.. So it really seems like if importing the 'test fixtures' will PREVENT the normal lib classes from being imported).
> 
> \### Sample project
> I've created this basic sample project which reproduces the error:
> https://github.com/Frank-D/multi-modules-root
> 
> \##### Current Result
> Compile errors showing under vs code Problems tab (e.g., using gradle test fixtures lib dependency hides the basic lib module dependency).
> 
> \##### Expected Result
> No compile errors showing under vs code Problems tab (e.g. using gradle test fixtures works without any issue within vs code using the vscode-java extension).
> 
> \##### Additional Informations
> Here's a screenshot of the vs code Problems, when reproducing the described error with the previous 'Sample project':
> !\[vscode\_gradle-for-java\_testfixtures-error\](https://user-images.githubusercontent.com/6005986/200182583-f9d53540-9c2f-4cfe-8e86-da552c5ab9b0.png)

declaring

```gradle
dependencies {
    implementation project(':my-project')
    testImplementation testFixtures(project(':my-project'))
}

```

Causes compilation errors in Eclipse, while things work well from Gradle and in other IDEs. The above dependency configuration is not only valid, but also recommended in such cases. For example, here at 4:50:

[![](https://global.discourse-cdn.com/gradle/original/2X/b/b51b5157029af7da814935fc9b489dcbab06a343.jpeg "Understanding Gradle #20 – Test Fixtures") ](https://www.youtube.com/watch?v=fSRN6YKa5B0&t=292)

I read about the changes in Gradle 7.5 and the 2 classpaths in Eclipse ([The Eclipse Plugins](https://docs.gradle.org/7.5/userguide/eclipse_plugin.html#sec:test-sources)). Note that [7.5+ - Eclipse cannot resolve types from projects with text fixtures · Issue #21853 · gradle/gradle · GitHub](https://github.com/gradle/gradle/issues/21853) is still active, requesting a fix, and like the last comment there by effad, I also have to wonder about the choice that was made when both `test=false` and `test=true` are present. The above configuration means “I need the main source set of the dependency for my main source set and the testFixtures source set for my tests source set”.

This configuration should be made valid in Eclipse out of the box since it’s valid in Gradle and we shouldn’t need to choose one or the other. It seems that this is something Buildship should do (or is it the responsibility of the `eclipse` plugin?).

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [January 11, 2024, 8:42am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/2 "2024-01-11T08:42:49Z")

</div>

@donat Can you have a look?

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [August 3, 2024, 7:14am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/3 "2024-08-03T07:14:40Z")

</div>

Hi @nlisker!

This problem has been solved with Gradle 8.9 ([Gradle 8.9 Release Notes](https://docs.gradle.org/8.9/release-notes.html)).

These related issues have been closed:

- [Depending on multiple configurations leads to broken buildship classpath · Issue #21968 · gradle/gradle · GitHub](https://github.com/gradle/gradle/issues/21968)
- [Eclipse Test Dependency Configuration Overrides Regular Dependency · Issue #22838 · gradle/gradle · GitHub](https://github.com/gradle/gradle/issues/22838)

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [September 28, 2024, 1:00am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/4 "2024-09-28T01:00:48Z")

</div>

Thanks for fixing this!

However, there seems to be either a related problem or the fix didn’t cover all cases. If the project that contains the test fixtures is a modular project (with module-info), then the consuming project can’t see the test fixtures. Running from Gradle doesn’t have issues, bit Eclipse won’t compile any test class that tries to `import` from a text fixture class.

Should I open a new bug or did I miss some configuration? If it’s a bug, is there a workaround?

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [September 29, 2024, 9:39am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/5 "2024-09-29T09:39:31Z")

</div>

The problem seems to be that the consumed project (`fixtures` in my example) is not recognized as modular. Open: _Project \> Properties: Java Build Path_

 ![grafik](https://global.discourse-cdn.com/gradle/original/2X/3/3b6e6f73909aed8df8e2048f0de3cb2cf87979b9.png)

This problem only affects project dependencies. For library dependencies the presence of the module descriptor is correctly recognized.

The missing attribute can be set manually in `build.gradle` of the consuming project:

```gradle
plugins {
  // [...]
  id 'eclipse'
}

eclipse {
  classpath {
    file {
      whenMerged {
        it.entries.find { it.path == '/fixtures' }.entryAttributes['module'] = true
      }
    }
  }
}

```

Now required packages should be able to be imported in the `module-info.java` of the consuming project.

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [September 29, 2024, 10:35am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/6 "2024-09-29T10:35:34Z")

</div>

For me the project appears as modular already.

The `fixtures` project is modular and looks like

```gradle
plugins {
	id("java-library")
	id("java-test-fixtures")
	id("eclipse")
}

```

and has a `src/testFixtures/java` folder with the test fixture classes.

The consuming project `server` is not modular and looks like this:

```gradle
plugins {
	id("java")
	id("war")
	id("jvm-test-suite")
	id("eclipse")
}

testing {
	suites {
		configureEach {
			useJUnitJupiter()
			dependencies {
				implementation(project())
				implementation(testFixtures(project(":fixtures")))
			}
		}
		...
	}
}

```

This looks like the same setup you have.

Then, in the Libraries view as you show, I do have `fixtures` as modular. Yet, if I try to import a class from `src/testFixtures/java` in `fixtures` inside a class in `src/test/java` in `server`, I get a “The import cannot be resolved” error.

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [October 12, 2024, 10:24am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/7 "2024-10-12T10:24:22Z")

</div>

It is difficult to reproduce this problem from the description alone. Could you provide a minimal complete example project?

As a starting point you can use [GitHub - oleosterhagen/gradle-test-fixtures](https://github.com/oleosterhagen/gradle-test-fixtures.git). This Gradle build can be successfully imported into Eclipse.

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [October 16, 2024, 6:47pm UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/8 "2024-10-16T18:47:41Z")

</div>

Here is a project similar to yours. A parent project contains a `lib` modular project that defines text fixtures, and a `consumer` non-modular project that tries to import those test fixtures, but can’t.

[testFixtures.zip](https://discuss.gradle.org/uploads/short-url/xspIc7m1e7FVzlapscficHgzNKe.zip) (64.7 KB)

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [October 19, 2024, 5:15pm UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/9 "2024-10-19T17:15:47Z")

</div>

Thank you for providing an example project.

Eclipse separates the **main** classpath from the **test** classpath. The `module-info.java` of project `lib` is on the main classpath and does not export packages from the test classpath. So the test classes of the project `lib` are not visible in the project `consumer`.

A second `module-info.java` for the test classpath could be a solution. But Eclipse JDT does currently only support one `module-info.java` per project. This limitation is currently discussed

- in an issue of JDT: [Support additional module-info.java for tests, if that ends up being de-facto standard · Issue #1465 · eclipse-jdt/eclipse.jdt.core · GitHub](https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1465)
- and on the eclipse-dev mailing list: [eclipse-dev Archive (Thread View - Most Recent First)](https://www.eclipse.org/lists/eclipse-dev/threads.html#12341)

As a workaround you can set the `module` attribute to `false` in the project dependency in `/consumer/build.gradle`:

```gradle
eclipse {
  classpath {
    file {
      whenMerged {
        it.entries.findAll { it.path == '/lib' }.each { it.entryAttributes['module'] = false }
      }
    }
  }
}

```

The lack of support in Eclipse JDT also affects the Maven integration (m2e): [Build path contains duplicate entry: 'module-info.java' for project 'Test' · Issue #173 · eclipse-m2e/m2e-core · GitHub](https://github.com/eclipse-m2e/m2e-core/issues/173)

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [October 19, 2024, 6:10pm UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/10 "2024-10-19T18:10:06Z")

</div>

Thanks for the relevant links!

Won’t this workaround move `lib` to the classpath completely? I build an image of `consumer` with jlink, so I need `lib` to be a module dependency. It’s only the tests that need to be on the classpath.

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [October 20, 2024, 7:18am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/11 "2024-10-20T07:18:33Z")

</div>

When `jlink` will be invoked from the Gradle build script, everything should work as before. The workaround `eclipse.classpath.file...` only affects the classpath in Eclipse, e.g. when compiling sources with JDT or launching the tests within Eclipse.

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [October 20, 2024, 10:22am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/12 "2024-10-20T10:22:08Z")

</div>

When it’s invoked yes, but my `consumer` project has to be modular, and if I put `lib` on the classpath, its `module-info` throws errors because `consumer` defines a `requires` entry on packages in `lib`.

Can it be added to the test classpath and the compile modulepath maybe? Or some other workaround that fixes the test issue without causing problems in the main sources?

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [October 20, 2024, 5:15pm UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/13 "2024-10-20T17:15:17Z")

</div>

I have imported your example project and added the workaround in `consumer`. Everything compiles in Eclipse and no errors are shown.

> […] its `module-info` throws errors […]

What do I have to do now to get these errors? Are these errors shown in Eclipse or when invoking the Gradle build?

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [October 20, 2024, 8:29pm UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/14 "2024-10-20T20:29:02Z")

</div>

Sorry, I didn’t put a module-info into consumer. Here is the updated project:  
[testFixtures.zip](https://discuss.gradle.org/uploads/short-url/o0e6lbHxN3NWFPBY9swmUygmYu5.zip) (67.2 KB)

If I apply the workaround, the tests see the fixtures, but the module is not available. If I don’t, the module is available, but the fixtures aren’t.

---

<div class="post-metadata">

**Author:** ![oleosterhagen](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/oleosterhagen/32/11914_2.png) [@oleosterhagen](https://discuss.gradle.org/u/oleosterhagen)\
**Post date:** [October 21, 2024, 11:32am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/15 "2024-10-21T11:32:10Z")

</div>

Because `consumer` is now modular in the updated example project, the dependency to `lib` must also stay modular and the workaround cannot be applied anymore.

The test class `LibraryTest` is not exported in the `module-info.java` of `lib`. Without a second `module-info.java`, which isn’t currently supported by JDT, this class cannot be imported in `consumer`.

JDT has a concept for separating main and test sources and maintaining different classpaths for them, but a project dependency like `lib` can only be imported as a main _or_ test dependency. So it is not possible to configure `lib` as modular for the main classpath and non modular for the test classpath the same time.

Splitting the `lib` project into two separate projects - one for the main sources and one for the test sources - could possibly work. As proposed in [Support additional module-info.java for tests, if that ends up being de-facto standard · Issue #1465 · eclipse-jdt/eclipse.jdt.core · GitHub](https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1465#issuecomment-2365280774) Maven (or Gradle) could do this under the hood. But I think, the different representations of projects in Gradle (or filesystem) and Eclipse are hard to understand and lead to a bad user experience.

---

<div class="post-metadata">

**Author:** ![nlisker](https://avatars.discourse-cdn.com/v4/letter/n/71c47a/32.png) [@nlisker](https://discuss.gradle.org/u/nlisker)\
**Post date:** [October 21, 2024, 11:58am UTC](https://discuss.gradle.org/t/testfixtures-dont-work-with-implementation-in-eclipse-only/47275/16 "2024-10-21T11:58:01Z")

</div>

> [@oleosterhagen](#):
>
> Because `consumer` is now modular in the updated example project, the dependency to `lib` must also stay modular and the workaround cannot be applied anymore.

This is what I thought too.

> [@oleosterhagen](#):
>
> JDT has a concept for separating main and test sources and maintaining different classpaths for them, but a project dependency like `lib` can only be imported as a main _or_ test dependency. So it is not possible to configure `lib` as modular for the main classpath and non modular for the test classpath the same time.

Yes, this is the core of the problem. I had hoped there was a “trick” to put main on the modulepath and test on the classpath, but looks like there isn’t.

> [@oleosterhagen](#):
>
> Splitting the `lib` project into two separate projects - one for the main sources and one for the test sources - could possibly work. As proposed in [Support additional module-info.java for tests, if that ends up being de-facto standard · Issue #1465 · eclipse-jdt/eclipse.jdt.core · GitHub](https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1465#issuecomment-2365280774) Maven (or Gradle) could do this under the hood.

I might end up doing this split unfortunately. It decouples code that should be coupled, so there’s some danger there.

> [@oleosterhagen](#):
>
> But I think, the different representations of projects in Gradle (or filesystem) and Eclipse are hard to understand and lead to a bad user experience.

Tell me about it. Took me a long time to understand the surface level of Gradle-Eclipse integrations. I can see how problems in this area cause people to stop using either Gradle or Eclipse, although the alternatives have their own flaws. Some of these issues could be bridged with more investment into Buildship, but the seat in the peanut gallery is free.

Anyway, you fixed the non-modular problem in 8.9 🎉 and explained why there is no viable solution for the modular case. I consider the case closed 🙂 .
