Ran into a strange problem. I'm doing some cutting...
# apollo-kotlin
n
Ran into a strange problem. I'm doing some cutting edge Android development with Kotlin Multiplatform as a target for some GraphQL stuff. I'm simply trying to download the schema using the
downloadApolloSchema
gradle target, and wasn't able to. I've configured my multiplatform project exactly as the documentation says. But where this project differs is in the top level build gradle file which has:
Copy code
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.31")
        classpath("com.android.tools.build:gradle:7.0.0-alpha11")
I found that if I use android tools >
7.0.0-alpha06
I get the following error when downloading a schema through gradle:
Copy code
* What went wrong:
Execution failed for task ':shared:downloadApolloSchema'.
> Companion
If I
--stacktrace
that, a bit more information is present:
Copy code
Caused by: java.lang.NoClassDefFoundError: Could not initialize class okhttp3.internal.Util
        at okhttp3.RequestBody$Companion.create(RequestBody.kt:145)
        at okhttp3.RequestBody$Companion.create$default(RequestBody.kt:143)
        at com.apollographql.apollo.gradle.internal.SchemaHelper.executeQuery$apollo_gradle_plugin(SchemaHelper.kt:39)
Which doesn't make a lot of sense. Why would things change in
7.0.0-alpha07
that would cause this sort of issue? Any ideas?
w
You can look into the dependencies of the build,
./gradlew buildEnvironment
. Perhaps AGP 7 is pulling some incompatible version of okhttp, anyway seems like some mismatch between expected and provided OkHttp classes
Is there another cause in the stacktrace btw? Can you paste the entire thing?
You can try explicitly providing some recent version of the OkHttp in the
classpath()
configuration, see if it helps 🤔
n
Okay, I'll try the last one.
Yes, adding
Copy code
classpath 'com.squareup.okhttp3:okhttp:4.9.1'
made the build succeed, and I was also able to generate the apollo client code too. Thanks @wasyl
w
👍 seems like something was pulling incompatible version of OkHttp, although if you have time it’d be nice to figure out the version before, this shouldn’t happen as far as I understand, may a bug in OkHttp
m
If I understand correctly, this is a bug/limitation in the Gradle classloaders. In some cases, mostly using
buildSrc
, but also in other cases Gradle doesn't do dependency resolution and puts an "older" version of dependencies in the classpath
I've recently merged https://github.com/apollographql/apollo-android/pull/3012 that should help with this
👌 2
w
I recently heard about this issue when mixing plugins syntax with the old buildscript/classpath one btw
m
yep, I'm not thrilled by the fat jar thing but looks like this is happening more and more
w
Yeah, it’d be great if it were easy to also proguard just the shaded dependencies before publishing
1
n
So, just looking at the buildEnvironment, the following gets included:
Copy code
|    +--- io.grpc:grpc-all:1.21.1
|    |    +--- io.grpc:grpc-api:1.21.1 (*)
|    |    +--- io.grpc:grpc-auth:1.21.1
|    |    |    +--- io.grpc:grpc-api:1.21.1 (*)
|    |    |    \--- com.google.auth:google-auth-library-credentials:0.13.0
|    |    +--- io.grpc:grpc-core:1.21.1 (*)
|    |    +--- io.grpc:grpc-context:1.21.1
|    |    +--- io.grpc:grpc-netty:1.21.1 (*)
|    |    +--- io.grpc:grpc-okhttp:1.21.1
|    |    |    +--- io.grpc:grpc-core:1.21.1 (*)
|    |    |    +--- com.squareup.okhttp:okhttp:2.5.0
|    |    |    |    \--- com.squareup.okio:okio:1.6.0 -> 2.8.0
Which explains the issue. I can also clearly see that this dependency was introduced AGP alpha07, I wonder if there's any documentation on why this change was introduced?
m
Given it's pretty deep in the transitive dependencies, I even wonder if the AGP team is even aware of this 😅
☝️ 2
n
I'm not really even sure why grpc is even part of the build tools.
m
Yea right
grpc
looks interesting for a build tool
w
I think it’s used to communicate with adb/emulator
Interesting... Is that used during connected tests?
w
Seems like it. Overall right now AGP also listens to connected tests progress, and it’s some weird protobuf or something. I recall some improvements to adb communication recently and grpc was one of them
👍 1
So I’d guess this is switching to the better communication process. I recall browsing the sources for the current communication protocol at some point but can’t find it now
m
Yea, that codebase is a beast 😅
w
If someone’s interested, I think this is how it currently works: parser gets chunks of bytes encoded in protobuf and parses them continuously here: https://android.googlesource.com/platform/tools/base/+/2403d6b56cb1a3a27388350149658d8d82[…]/ddmlib/testrunner/InstrumentationProtoResultParser.java and the bytes are fed from here: https://android.googlesource.com/platform/tools/base/+/2403d6b56cb1a3a27388350149658d8d82[…]9/ddmlib/src/main/java/com/android/ddmlib/AdbHelper.java Also looks like the instrumentation test runner simply starts an ADB shell command and listens to output (feeding it to the parser as it comes). Here’s the changelog outlining gRPC-related changes: https://developer.android.com/studio/releases/emulator#29.0.6-grpc So maybe it’s something that will help in running instrumented tests over internet as well, with firebase test lab perhaps? Or maybe will just be more reliable/less overhead than a shell command?
🙏 2
👌 1
m
Ah super cool, thanks !!
I think some of it is also that grpc is used pretty extensively at Google so it's a pretty convenient hammer to use whenever bytes need to be sent/received.
☝️ 1
w
Yep might be an effort to unify stuff. Also I just realized the grpc communication for the emulator is important if you want to run the emulator inside docker
m
Makes sense
n
I sort of feel like now would be the time to guide Google to not bleed these dependencies? Maybe they should be the ones fat jar-ing their tools so that they don't affect other projects? Maybe this should be reported with their tracker at least?
w
Wouldn’t hurt to report. Using such old OkHttp is a weird decision in itself anyway
n
Okay, I'll make an attempt to report it.
m
@Neal Sanche Ah sorry I was focused on the issue tracker and did not see your message . I just filed https://issuetracker.google.com/issues/183511640
n
No worries, I had just been trying to figure out what category.
👍 1
m
I realized while writing it that okio is most likely the conflicting dependency
Since okhttp3 changed the package name, it shouldn't clash with okhttp2
n
I concur with that, tried adding an okio dependency instead of okhttp and my build works.
👍 1
136 Views