Skip to content

Commit

Permalink
Automatically register nested Kotlin classes for reflection
Browse files Browse the repository at this point in the history
Users have come to expect that @RegisterForReflection fixes
a lot of native image issues and use it a lot.
For Kotlin classes however, registering a class is often not
enough - the companion classes are need to be registered.
These companion classes are nested classes, so we automatically
set the property to true for Kotlin classes

Closes: quarkusio#28167
  • Loading branch information
geoand authored and iocanel committed Nov 7, 2022
1 parent b98cd04 commit b9ae03f
Showing 1 changed file with 15 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.jboss.jandex.Type.Kind;
import org.jboss.logging.Logger;

import io.quarkus.deployment.Capabilities;
import io.quarkus.deployment.Capability;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
Expand All @@ -32,8 +34,10 @@ public class RegisterForReflectionBuildStep {

private static final Logger log = Logger.getLogger(RegisterForReflectionBuildStep.class);

private static final DotName KOTLIN_METADATA_ANNOTATION = DotName.createSimple("kotlin.Metadata");

@BuildStep
public void build(CombinedIndexBuildItem combinedIndexBuildItem,
public void build(CombinedIndexBuildItem combinedIndexBuildItem, Capabilities capabilities,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<ReflectiveHierarchyBuildItem> reflectiveClassHierarchy,
BuildProducer<LambdaCapturingTypeBuildItem> lambdaCapturingTypeProducer) {
Expand Down Expand Up @@ -63,6 +67,12 @@ public void build(CombinedIndexBuildItem combinedIndexBuildItem,
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (targetsValue == null && classNamesValue == null) {
ClassInfo classInfo = i.target().asClass();
if (capabilities.isPresent(Capability.KOTLIN) && ignoreNested) {
// for Kotlin classes, we need to register the nested classes as well because companion classes are very often necessary at runtime
if (isKotlinClass(classInfo)) {
ignoreNested = false;
}
}
registerClass(classLoader, classInfo.name().toString(), methods, fields, ignoreNested, serialization,
reflectiveClass, reflectiveClassHierarchy, processedReflectiveHierarchies, registerFullHierarchyValue,
builder);
Expand All @@ -88,6 +98,10 @@ public void build(CombinedIndexBuildItem combinedIndexBuildItem,
}
}

private static boolean isKotlinClass(ClassInfo classInfo) {
return classInfo.hasDeclaredAnnotation(KOTLIN_METADATA_ANNOTATION);
}

/**
* BFS Recursive Method to register a class and it's inner classes for Reflection.
*
Expand Down

0 comments on commit b9ae03f

Please sign in to comment.