google / google/auto

Add support for Kotlin Objects as services for autoService

Open
#785 5 comments 0 reactions 0 assignees View on GitHub
Component: service P3 type=addition
Dominant language
Java
Stars
10.6k
Forks
1.2k
Avg merge
6h 32m
Merged PRs (30d)
13

Description

Kotlin has a nice singleton system thanks to [kotlin objects](https://kotlinlang.org/docs/reference/object-declarations.html), it creates a class that works automatically as a singleton, which from the perspective of Java looks like [a class with a static field `INSTANCE`](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-methods) which contains the only instance of the class.

This is particularly helpful in the context of service loaders as it gives more control over the instance used as a service.

Unfortunately, the way `ServiceLoader` works currently requires classes that can be instantiated using their default constructor, which objects do not have.

But thanks to the magic of annotation processing this is actually fixable.
Without any processing this is what someone could write to make "their object" work with `ServiceLoader`:

```kotlin
interface MyInterface {
fun myMethod() : String
}

object MyObject : MyInterface {
override fun myMethod() : String = "hello"
}

@AutoService(MyInterface::class)
class MyObjectServiceLoaderProxy : MyInterface by MyObject
```

This uses the [delegation mechanism](https://kotlinlang.org/docs/reference/delegation.html) also provided in Kotlin; in short, if you are implementing an **interface**, using `by anImplementationOfSaidInterface`, instances of the class will delegate the non-explicitely implemented functions to `anImplementationOfSaidInterface`.
Note, this does not work with abstract classes, too bad but not the end of the world.

There, now we can use `ServiceLoader` "with objects", we just need to tidy it up a bit, having the annotation on the object and generating the class automatically should be doable and would provide all the benefits without requiring user intervention (as long as the "service" is represented by an interface). We can also give a non standard name to the class to avoid people using it by mistake, after all this is only meant to be for the eyes of the ServiceLoader.

Thoughts?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.