JetBrains / Exposed

Kotlin SQL Framework
http://jetbrains.github.io/Exposed/
Apache License 2.0
8.05k stars 676 forks source link

feat: EXPOSED-327 Support GraalVM native images with Spring Boot #2039

Closed bog-walk closed 3 months ago

bog-walk commented 3 months ago

Implements a new class ExposedAotContribution and registers it in an aot.factories file as required. This class upholds the contract for all runtime hints necessary to enable building a GraalVM native image of a Spring boot app.

In addition to registering Exposed class type hints and resources, the implementation searches through an app's packages for any classes that inherit from Entity. This resolves DAO issues like kotlin.reflect.jvm.internal.KotlinReflectionInternalError: Could not compute caller for function: public constructor CustomerEntity, due to these fields in EntityClass. An alternative to this would have been to require the user to avoid reflection altogether by providing the explicit constructor in their entity definitions:

class CustomerEntity(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<CustomerEntity>(
        Customers,
        entityCtor = { CustomerEntity(it) }  // this explicit argument avoids reflection
    )
}

This feature was tested in 2 ways:

  1. Using a tester Spring Boot app with the new class and resource file defined directly in the project.
  2. Using the same tester app, but with the new class provided by a dependency on a local jar file.

Note: The sample app attempted to cover many use cases of both DSL and DAO approach, and all base classes were included in the type hints, as well as any that used reflection. There is still a chance that some use case might have been missed and users may encounter KotlinReflectionInternalErrors. For example, if the tester app was made to fail by purposefully excluding a necessary Exposed class, this could be resolved in the app by registering the hint in a class that extends RuntimeHintsRegistrar (as seen in the README section diff). At least until a fix would be merged to include the missing hint.


Many thanks to @joshlong for the valuable insight into the workings of Spring and the guidance overall with this feature!