kubernetes-client
kubernetes-client copied to clipboard
Add graalvm-reachability-metadata for kubernetes client
Is your enhancement related to a problem? Please describe
Usage of kubernetes client in a graalvm native application.
Describe the solution you'd like
Availability of the meta data to use kubernetes client in the https://github.com/oracle/graalvm-reachability-metadata repository
Describe alternatives you've considered
No response
Additional context
No response
Related to #2004
For one of my projects I retro fitted the reflection data in a Spring Boot v3 project:
@Compontent
@ImportRuntimeHints(KubernetesClientRuntimeHintsRegistrar::class)
class Test
object KubernetesClientRuntimeHintsRegistrar : RuntimeHintsRegistrar {
private val logger = KotlinLogging.logger { }
override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) {
hints.resources().registerPattern("META-INF/services/io.fabric8.kubernetes.api.model.KubernetesResource")
hints.resources().registerPattern("META-INF/services/io.fabric8.kubernetes.client.http.HttpClient\$Factory")
hints.reflection().registerType<VersionInfo>(*MemberCategory.values())
registerClients(hints)
registerJacksonKubernetesModels(hints)
}
private fun registerClients(hints: RuntimeHints) {
val clazz = Client::class.java
val reflections = Reflections(clazz.packageName, clazz)
val clients = reflections.getSubTypesOf(Client::class.java) + Client::class.java
for (client in clients) {
hints.reflection().registerType(client, *MemberCategory.values())
logger.info { "registering ${client.name} for reflection" }
}
}
private fun registerJacksonKubernetesModels(hints: RuntimeHints) {
val clazz = KubernetesResource::class.java
val reflections = Reflections(clazz.packageName, clazz)
val kubernetesModels = reflections.getSubTypesOf(KubernetesResource::class.java)
val combined = buildSet {
addAll(kubernetesModels)
addAll(resolveSerializationClasses<JsonSerialize>(reflections))
addAll(resolveSerializationClasses<JsonDeserialize>(reflections))
}
for (model in combined) {
hints.reflection().registerType(model, *MemberCategory.values())
logger.info { "registering ${model.name} for reflection" }
}
}
/**
* Extracts Jacksons Deserializer / Serializers specified in the classes annotations
*/
private inline fun <reified R : Annotation> resolveSerializationClasses(reflections: Reflections): List<Class<*>> {
val clazz = R::class.java
val method = clazz.getMethod("using")
val classes = reflections.getTypesAnnotatedWith(clazz)
return classes.mapNotNull { clazzWithAnnotation ->
val annotation = clazzWithAnnotation.getAnnotation(clazz)
if (annotation != null) method.invoke(annotation) as Class<*> else null
}
}
}
Its not the best solution, as its tied to Spring Boot. But the approach in general works that way. It is highly inspired by josh long.
There also is a project which might be interesting here: https://github.com/GoodforGod/graalvm-hint
It uses an annotation processor to dynamically create a reflect config file
This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!
This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!
This issue has been automatically marked as stale because it has not had any activity since 90 days. It will be closed if no further activity occurs within 7 days. Thank you for your contributions!