Skip to content

Commit 983fdeb

Browse files
committed
Document how to register runtime hints for convention-based conversion
Closes gh-35178
1 parent e3445b1 commit 983fdeb

File tree

1 file changed

+55
-0
lines changed
  • framework-docs/modules/ROOT/pages/core

1 file changed

+55
-0
lines changed

framework-docs/modules/ROOT/pages/core/aot.adoc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,61 @@ This registers hints for constructors, fields, properties, and record components
665665
Hints are also registered for types transitively used on properties and record components.
666666
In other words, if `Order` exposes others types, hints are registered for those as well.
667667

668+
[[aot.hints.convention-based-conversion]]
669+
=== Runtime Hints for Convention-based Conversion
670+
671+
Although the core container provides built-in support for automatic conversion of many
672+
common types (see xref:core/validation/convert.adoc[Spring Type Conversion]), some
673+
conversions are supported via a convention-based algorithm that relies on reflection.
674+
675+
Specifically, if there is no explicit `Converter` registered with the `ConversionService`
676+
for a particular source → target type pair, the internal `ObjectToObjectConverter`
677+
will attempt to use conventions to convert a source object to a target type by delegating
678+
to a method on the source object or to a static factory method or constructor on the
679+
target type. Since this convention-based algorithm can be applied to arbitrary types at
680+
runtime, the core container is not able to infer the runtime hints necessary to support
681+
such reflection.
682+
683+
If you encounter convention-based conversion issues within a native image resulting from
684+
lacking runtime hints, you can register the necessary hints programmatically. For
685+
example, if your application requires a conversion from `java.time.Instant` to
686+
`java.sql.Timestamp` and relies on `ObjectToObjectConverter` to invoke
687+
`java.sql.Timestamp.from(Instant)` using reflection, you could implement a custom
688+
`RuntimeHintsRegitrar` to support this use case within a native image, as demonstrated in
689+
the following example.
690+
691+
[tabs]
692+
======
693+
Java::
694+
+
695+
[source,java,indent=0,subs="verbatim,quotes"]
696+
----
697+
public class TimestampConversionRuntimeHints implements RuntimeHintsRegistrar {
698+
699+
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
700+
ReflectionHints reflectionHints = hints.reflection();
701+
702+
reflectionHints.registerTypeIfPresent(classLoader, "java.sql.Timestamp", hint -> hint
703+
.withMethod("from", List.of(TypeReference.of(Instant.class)), ExecutableMode.INVOKE)
704+
.onReachableType(TypeReference.of("java.sql.Timestamp")));
705+
}
706+
}
707+
----
708+
======
709+
710+
`TimestampConversionRuntimeHints` can then be registered declaratively via
711+
<<aot.hints.import-runtime-hints>> or statically via a `META-INF/spring/aot.factories`
712+
configuration file.
713+
714+
[NOTE]
715+
====
716+
The above `TimestampConversionRuntimeHints` class is a simplified version of the
717+
`ObjectToObjectConverterRuntimeHints` class that is included in the framework and
718+
registered by default.
719+
720+
Thus, this specific `Instant`-to-`Timestamp` use case is already handled by the framework.
721+
====
722+
668723
[[aot.hints.testing]]
669724
=== Testing Runtime Hints
670725

0 commit comments

Comments
 (0)