is it possible for a feature module to depend on a...
# android-architecture
d
is it possible for a feature module to depend on another feature module?
👌 2
a
what issues?
d
Like this:
Copy code
E/AndroidRuntime: FATAL EXCEPTION: GoogleApiHandler
    Process: redacted.package.name, PID: 19731
    java.lang.NoSuchMethodError: No virtual method setLogSessionId(Ljava/lang/String;)Lcom/google/android/gms/auth/api/signin/GoogleSignInOptions$Builder; in class Lcom/google/android/gms/auth/api/signin/GoogleSignInOptions$Builder; or its super classes (declaration of 'com.google.android.gms.auth.api.signin.GoogleSignInOptions$Builder' appears in /data/app/redacted.package.name-ASVDSF39812sdFD-AUZFA==/base.apk)
        at com.google.android.gms.auth.api.signin.internal.zzh.<init>(com.google.android.gms:play-services-auth@@18.1.0:5)
        at com.google.android.gms.auth.api.zzd.buildClient(com.google.android.gms:play-services-auth@@18.1.0:3)
        at com.google.android.gms.common.api.GoogleApi.zaa(Unknown Source:93)
        at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.<init>(Unknown Source:7)
        at com.google.android.gms.common.api.internal.GoogleApiManager.zab(Unknown Source:43)
        at com.google.android.gms.common.api.internal.GoogleApiManager.handleMessage(Unknown Source:173)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at com.google.android.gms.internal.base.zap.dispatchMessage(Unknown Source:8)
        at android.os.Looper.loop(Looper.java:219)
        at android.os.HandlerThread.run(HandlerThread.java:67)
a
Hmm, looks like you need to make sure to declare the dependencies on the feature module, or expose the dependency with
api
Copy code
// Option A

// feature_a.gradle
implementation "google.gms..." 
implementation project("feature_b")

// feature_b.gradle
implementation "google.gms..." 

// Option B
// feature_a.gradle
implementation project("feature_b")

// feature_b.gradle
api "google.gms..."
api approach is slower but more convenient in some cases
d
the
NoSuchMethodError
is on a method that should be implemented in a library included in the feature module that use it. like this: :feature-A depends on :feature-B :feature-B include the library and use it :feature-A open an activity from :feature-B ---> that kind of error is encountered. if I make
:feature-B
a standard android library it has no issue. If I include the dependency also in
:feature-A
(even if it's not used) it doesn't give error... or I can declare the dependency in :feature-B as
api
rather thank
implementation
I had weird behaviors like this that I couldn't explain and so I concluded that it is not possible / well supported to have 2 feature modules depends on each other
@allan.conda care to explain why I need to declare the dependency in the module that doesn't use it?
a
the 
NoSuchMethodError
 is on a method that should be implemented in a library included in the feature module that use it.
Yeah, exactly
are to explain why I need to declare the dependency in the module that doesn’t use it?
You have to declare it if
feature module B
exposes the dependency in its ABI. One example of such case is if you expose that dependency in a public method. Not sure for gms but for the case of RxJava for example. If you have a function like this in module B
Copy code
fun someObservable(): Observable<SomeObject>
Then you have to declare RxJava as a dependency in feature A
I’m not an expert on it, just had a similar concern in the past. This entry is useful in understanding more about gradle https://dev.to/autonomousapps/dependency-analysis-gradle-plugin-what-s-an-abi-3l2h
d
@allan.conda I completely understand the difference between
api
and
implementation
and it is clear to me that if your library/feature module expose an api that uses a library time that library type is not an implementation details but is part of my API. But the fact is that my feature-B DO NOT expose in any way the fact that internally it uses google api. I could as well completely replace the google API with something else without changing anything in the public API used by feature-A. This is why it puzzles me that I have to either declare the dependency as API (which is not) or include it in feature-A (which doesn't use the dependency at all). that dependency for me is an implementation details and I don't see why I need to expose it to the other feature module
a
It only has to be exposed publicly and don’t have to be used. Otherwise you’re right an implementation detail don’t need to be exposed. You could try that plugin in that article and it will show you exactly how the dependency is being exposed
d
Thanks I will!