Hi, I’ve had an issue that I know how to solve, but I don’t understand why it’s solved.
A project applies a custom plugin for code generation. Inside a task from this plugin, I run into an issue where a class couldn’t be initialized because it used the wrong protobuf-java version. The project declares protobuf-java:3.23.2
, but the classloader returned 3.17.2
.
The following logs prints resolving a protobuf java class from each classloader, bottom-up. (I know that children delegate resolution to parents)
java.net.URLClassLoader@179cf3cb -> protobuf-java-3.17.2.jar
ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:]:buildSrc[:]:root-project[:]:project-app(export)} -> protobuf-java-3.17.2.jar
ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:]:buildSrc[:]:root-project[:](export)} -> protobuf-java-3.17.2.jar
ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:CodegenConventionPlugins]:buildSrc[:CodegenConventionPlugins](export)}) -> Not found
The project where the plugin is applied
// settings.gradle
pluginManagement {
...
plugins {
id 'com.android.library' version "7.4.2"
}
}
// build.gradle
plugins {
id 'com.android.library' apply false
}
// app/build.gradle
plugins {
id 'com.android.library'
}
dependencies {
implementation("com.google.protobuf:protobuf-java:3.23.2")
}
If I remove the plugins
block from the root build.gradle
, things work because protobuf-java:3.17.2
is not in the classloader.
java.net.URLClassLoader@8c350d -> protobuf-java-3.23.2.jar
ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:]:buildSrc[:]:root-project[:]:project-app(export)} -> protobuf-java-3.23.2.jar
ClassLoaderScopeIdentifier.Id{coreAndPlugins:settings[:CodegenConventionPlugins]:buildSrc[:CodegenConventionPlugins](export)}) -> Not found
There’s no root-project
ClassLoader, but I don’t understand why.
I know that com.android.library
has a dependency on protobuf-java:3.17.2
, but I would like to understand at a deeper level how things work.
Also, are there other/better ways to enforce a transitive dependency version on plugin dependencies? This misuse of protobuf version went undetected for a long time because there wasn’t any breaking change until 3.22