Search code examples
javagradle

Build fails in Gradle multi-project build due to dependency, which is not used


I am working on a Gradle multi-project that is what's happening:

Dependency X is used and declared in subproject A. Subproject B depends on subproject A. Build fails, because dependency X is missing in subproject B.

Edit I: Why does the build fail? Only A should need the dependency. This is the error message on :subprojectB:compileJava, where SomeClass comes from X.

C:\...\ClassSubpojectB.java:86: error: cannot access SomeClass
      //some code
                          ^
  class file for SomeClass not found
1 error

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':subprojectB:compileJava'.
> Compilation failed; see the compiler error output for details.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1m 53s

Edit II: Dao.get is marked red in my IDE.

Bla bla = Dao.get(Bla .class, new Key("id", id));

with

  public static <O> O get(Class<O> c, Key key) {
    SomeClass s = key.getSomeClass();
    return get(c, s);
  }

SomeClass is only used in the body of get, so it should not be exposed. I that not correct?


Solution

  • It looks like what's happening is that, on line 86 of ClassSubpojectB.java within subproject B, you call a method of a class in subproject A and that method returns a type from dependency X (namely SomeClass). Edit: Based on further information, it looks like one of the parameter types of that method (Key) exposes SomeClass as a return type on one of its methods.

    Such a method call will cause the compilation of subproject B to fail. See eg this Gradle documentation for further details.

    To fix, either:

    • change dependency X from an implementation dependency to an api dependency in subproject A (which requires applying the Java Library plugin in A if you've not done so already),
    • declare X as an implementation dependency in subproject B, or
    • refactor the API of A so that it does not expose any types from X, perhaps "wrapping" X types with your own.