Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle dependency not shared with dependent module

Context

I have two modules in my project:

  • Java/Kotlin module common
  • Android/Kotlin module app

common depends on Koin, which is a Kotlin library for dependency injection:

dependencies {
  implementation 'org.koin:koin-core:1.0.2'
}

Usage example:

class MyPresenter: KoinComponent {
  ...
}

app does not depend on the Koin library because I do not need to inject anything in the Android code, all the injections are in the common code (presenters, interceptors, etc).

But app depends on common:

dependencies {
  implementation project(':common')
}

Usage example:

class MyFragment {
  private val presenter = MyPresenter()
}

Problem

I can compile common, I can run unit tests in common, but when I try to compile app I get this error:

Supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class xxx.common.presenter.MyPresenter, unresolved supertypes: org.koin.standalone.KoinComponent

When I run ./gradlew :app:dependencies

debugCompileClasspath
+--- project :common
debugRuntimeClasspath
+--- project :common
|    +--- org.koin:koin-core:1.0.2

The dependency is in the runtime configuration, but is missing from the compile configuration.


What I have tried so far:

Obviously I don't want to declare the Koin dependency in app so I have tried several things:

Change Koin dependency for api:

dependencies {
  api 'org.koin:koin-core:1.0.2'
}

Not working - I get the exact same dependency tree as with implementation.

Change project dependency configuration:

dependencies {
  implementation project(path: ':common', configuration: `compile`)
}

Not working - I wasn't sure of this one but I was hoping it would get the dependencies of common in compile configuration.

Change Koin dependency for compile:

dependencies {
  compile 'org.koin:koin-core:1.0.2'
}

Working! The dependency appears in the debugCompileClasspath and I am able to run the app.


Questions

Now I am confused:

  • As app does not use Koin directly, I though it would not need the dependency. Why does it? Is it because the static type of MyPresenter is KoinComponent?
  • I thought api was the same than the deprecated compile. It seems not.
  • Is there another way other than using the deprecated compile?
like image 806
Tijee Avatar asked Nov 07 '22 21:11

Tijee


1 Answers

  • Because you make Koin types appear in the APIs of common, then consumers of common need to know about the Koin types. They effectively become API.
  • The api configuration is what you should use and should work
  • The most likely explanation is that between the Android/Kotlin project on one side and the Java/Kotlin project on the other side have a different definition of what api is, how the consumable configuration apiElements is built or accessed or ...

To debug that, I would recommend creating a simple project that reproduces the problem and that can be shared as there might be a bug behind that in the android or kotlin plugin.

like image 179
Louis Jacomet Avatar answered Nov 15 '22 10:11

Louis Jacomet