I want to do some ugly hacking to fix a Gradle iss...
# getting-started
a
I want to do some ugly hacking to fix a Gradle issue - is it at all possible to use Kotlin/JS dynamic in Kotlin/JVM? Or is there an alternative? (I want to call functions/read properties from an instance of a class, but because of Gradle build script classloader issues the class isn't present, and shading the class doesn't work, and adding the requisite dependency as compileOnly is not convenient for users).
j
If the class isn't present due to classloader issues, it means you're talking about runtime, right? If the class isn't present at runtime, you can't have an instance of it, so
dynamic
wouldn't help you. You would need to at least have an instance at runtime, and then you could have the "dynamic" aspect of it by using reflection (although it's not ideal if course)
a
https://github.com/adamko-dev/kotlin-binary-compatibility-validator-mu/issues/1 1. apply BCVSettingsPlugin to
settings.gradle.kts
2. BCVSettingsPlugin applies itself (BCVPlugin) to every subproject 3. if a subproject has the Kotlin KMP plugin applied, then BCVProjectPlugin reacts to it (so the KGP classes should be present) 4. however, while BCVProjectPlugin can see that Project has an extension with type
org.jetbrains.kotlin.gradle.plugin.KotlinTargetsContainer
it fails because KotlinTargetsContainer class isn't present. The workaround is to add KGP to the
settings.gradle.kts
classpath, which isn't ideal. It's unusual and non-standard and annoying to maintain and document. I think Gradle (sometimes?) isolates plugins classpaths, so even though BCVProjectPlugin is reacting to KGP inside
settings.gradle.kts
, that doesn't automatically inherit KGP's classpath. However, when BCVProjectPlugin is applied as to a project the classpath for the whole buildscript is present.
maybe I could split BCVSettingsPlugin/BCVProjectPlugin to separate Gradle subprojects/feature variants 🤔 • BCVSettingsPlugin would have a an implementation dependency on KGP • BCVProjectPlugin would have a an compileOnly dependency on KGP Then BCVPlugin would apply either using the plugin ID, not using the class
e
dynamic
would only be possible via reflection (which is what Groovy does, or Gradle Kotlin DSL's
withGroovyBuilder
)
under all normal circumstances KGP should be in the root project classpath (there's various issues if it's only in subprojects), so do you really need it in settings?
1
d
dynamic type is not possible to use at any platform expect js/wasm
a
thanks @ephemient,
withGroovyBuilder {}
works. It's a bit ugly but it's probably more stable than my custom dynamic typing. Adding KGP to the root project (with
apply false
) doesn't make a difference though, I still see
An exception occurred ... Type org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension not present
when BCVProjectPlugin runs and reacts to KGP. It's something weird where Gradle isn't 'updating' the classpath when a settings-plugin applies a project-plugin.
e
not sure what you mean by 'updating' the classpath
a
me neither, this is at the limits of my knowledge! Basically, when I write code in a
build.gradle.kts
I can access all classes from the plugins applied to that buildscript. When I write a custom Gradle plugin I can add a compileOnly dependency on KGP and react to KGP. I expect that the KGP class files are there at runtime. This works sometimes, but not always, and the behaviour is inconsistent. Sometimes it can be worked around by applying KGP to the root
build.gradle.kts
, but for whatever reason that's not working (the KGP classes are missing) when my custom plugin is applied to a
build.gradle.kts
but from inside
settings.gradle.kts
...
@dmitriy.novozhilov thanks! I expect that answer. It would be cool though, as an advanced 'hack around' option. `dynamic is just so nice to use in Kotlin/JS, it's so convenient to write code dynamically sometimes!
e
it won't. the core issue is that classes in parent classloaders can't statically reference classes in child classloaders, by design
☝️ 1