-
Notifications
You must be signed in to change notification settings - Fork 434
KT-6653: Implementing Gradle's Java Bean structured interfaces in Kotlin is incredibly verbose #1026
Comments
Yep, the required extra ceremony is annoying. Given the following Java interface: public interface InterfaceWithJavaBeanProperty {
String getFoo();
void setFoo(String value);
} when implementing in Kotlin one has to write: class JavaBeanPropertyFromJavaInterface(
private var foo: String
) : InterfaceWithJavaBeanProperty {
override fun getFoo(): String = foo
override fun setFoo(value: String) { foo = value }
} It feels like this should be enough: class JavaBeanPropertyFromJavaInterface(override var foo: String) : InterfaceWithJavaBeanProperty Could be seen as a Kotlin Java interop issue/feature. @JLLeitschuh could you please try find related KT issues? @sdeleuze, any chance you could enlight us if something was done for Spring about that? |
The TL;DR this is a really complicated issue that I don't think will ever be fixed in the Kotlin Compiler. https://youtrack.jetbrains.com/issue/KT-6653
|
@JLLeitschuh thanks, that's unfortunate |
@JLLeitschuh actually, nevermind, I edited the issue title |
@JLLeitschuh you beat me to it, good, I like your new title |
A simple fix would be to simply convert those interfaces to Kotlin but that would mean adding the Kotlin compiler to the core Gradle build. I'm guessing that will cause a heated discussion. |
@JLLeitschuh don't forget that the Gradle Java API is consumed by codebases in Java, Groovy, Kotlin, etc... |
Having these interfaces implemented in Kotlin I don't think would add a dependency upon the Kotlin standard lib. I think that this compiled by the java compiler interface Named {
String getName();
} And this compiled by the kotlin compiler: interface Named {
val name: String
} Will produce pretty much the same bytecode. The kotlin compiler simply adds a bunch of meta annotations to the interface. Converting these interfaces to Kotlin wouldn't impact consumers in Java or Groovy as far as I'm aware. |
This same problem arises when a plugin author overrides a task like For example, if you have this before: @CacheableTask
open class KtlintCheckTask @Inject constructor(
private val objectFactory: ObjectFactory
) : SourceTask() {
} Interacting with this task in Kotlin looks like this: tasks.withType<KtlintCheckTask>().configure {
source.matching { [whatever] }
} When you want to make the task cacheable, you have to change it to this: @CacheableTask
open class KtlintCheckTask @Inject constructor(
private val objectFactory: ObjectFactory
) : SourceTask() {
@InputFiles
@SkipWhenEmpty
@PathSensitive(PathSensitivity.RELATIVE)
override fun getSource(): FileTree { return super.getSource() }
} Which becomes an API breaking change requiring API consumers to change their code to this: tasks.withType<KtlintCheckTask>().configure {
getSource().matching { [whatever] }
} |
As an plugin developer implementing interfaces in Kotlin, some of the bean interfaces can be incredibly verbose to implement.
For example, if, in my plugin, I want to implement
Named
I need to create a separate property and also override thegetName
method.If the
Named
interface were instead something like the below:The implementation of such a class would be far simpler:
There are various other locations throughout the Gradle API where there are Bean style interfaces that would be simpler for plugin developers to work with if they were kotlinified.
An alternative to this, is to dynamically weave in the Kotlin annotations into the bytecode so that the Kotlin compiler sees these bean interfaces as having properties. I think spring does something similar with their API's to allow for better interop with Kotlin.
This change wouldn't be a binary breaking change for any existing Java or Groovy plugins, however, making such a change after the 1.0 release of the Kotlin DSL would constitute an API breaking change for Kotlin plugins.
Longer Example
This problem gets more complicated when you start getting even bigger bean interfaces
The text was updated successfully, but these errors were encountered: