Hi,

Here is my configuration: Version 3.1.1 of Springboot (reactive), native generation, MacOS ARM-M1, OpenJDK Runtime Environment GraalVM 17.0.7+8.1

Everything works fine when compiled with gradle bootJar

When I compile using native mode (gradle nativeCompile), and run the app, I get the following stack trace.

Full source code is available here: https://github.com/operrin/native-hateoas

Thanks

2023-06-24T11:38:49.087+02:00 ERROR 36501 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [7d988f12-1]  500 Server Error for HTTP GET "/intervenants"

org.springframework.core.codec.EncodingException: JSON encoding error: Error creating bean with name 'org.springframework.hateoas.EntityModel$MapSuppressingUnwrappingSerializer': Failed to instantiate [org.springframework.hateoas.EntityModel$MapSuppressingUnwrappingSerializer]: No default constructor found
    at org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:259) ~[intervenant-service:6.0.10]
    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
    *__checkpoint ⇢ Handler org.miage.intervenantservice.boundary.IntervenantRouter$$Lambda$33f6ea66eb22970ddf524a223f0b6a228e9aeae3@2155835a [DispatcherHandler]
    *__checkpoint ⇢ HTTP GET "/intervenants" [ExceptionHandlingWebHandler]
Original Stack Trace:
        at org.springframework.http.codec.json.AbstractJackson2Encoder.encodeValue(AbstractJackson2Encoder.java:259) ~[intervenant-service:6.0.10]
        at org.springframework.http.codec.json.AbstractJackson2Encoder.lambda$encode$0(AbstractJackson2Encoder.java:158) ~[intervenant-service:6.0.10]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:113) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:245) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:305) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[na:na]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:291) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2071) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:118) ~[na:na]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:392) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:527) ~[na:na]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:384) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onComplete(FluxConcatMapNoPrefetch.java:240) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredComplete(FluxUsingWhen.java:392) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$CommitInner.onComplete(FluxUsingWhen.java:527) ~[na:na]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[na:na]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2205) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:209) ~[intervenant-service:3.5.7]
        at reactor.pool.SimpleDequePool.maybeRecycleAndDrain(SimpleDequePool.java:531) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerInner.onComplete(SimpleDequePool.java:761) ~[intervenant-service:1.0.0]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.pool.SimpleDequePool$QueuePoolRecyclerMono.subscribe(SimpleDequePool.java:873) ~[na:na]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260) ~[na:na]
        at reactor.core.publisher.Operators.complete(Operators.java:137) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:46) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[na:na]
        at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:223) ~[na:na]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[na:na]
        at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:159) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[na:na]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onError(MonoIgnoreElements.java:84) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134) ~[na:na]
        at reactor.core.publisher.FluxFilter$FilterSubscriber.onError(FluxFilter.java:157) ~[na:na]
        at reactor.core.publisher.FluxFilter$FilterConditionalSubscriber.onError(FluxFilter.java:291) ~[na:na]
        at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onError(FluxMap.java:265) ~[na:na]
        at reactor.core.publisher.Operators.error(Operators.java:198) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) ~[na:na]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onComplete(FluxUsingWhen.java:384) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:847) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:609) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:589) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onComplete(FluxFlatMap.java:466) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:152) ~[na:na]
        at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:357) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164) ~[na:na]
        at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[na:na]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[na:na]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8773) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:200) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFlatMap.subscribeOrReturn(FluxFlatMap.java:93) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8759) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onNext(FluxUsingWhen.java:195) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[na:na]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.FluxRetry$RetrySubscriber.onNext(FluxRetry.java:87) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:245) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:305) ~[intervenant-service:3.5.7]
        at io.r2dbc.pool.MonoDiscardOnCancel$MonoDiscardOnCancelSubscriber.onNext(MonoDiscardOnCancel.java:92) ~[na:na]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:236) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89) ~[na:na]
        at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:223) ~[na:na]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85) ~[na:na]
        at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:159) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at io.r2dbc.pool.MonoDiscardOnCancel.subscribe(MonoDiscardOnCancel.java:50) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:467) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool.lambda$drainLoop$8(SimpleDequePool.java:368) ~[intervenant-service:1.0.0]
        at reactor.core.scheduler.ImmediateScheduler.schedule(ImmediateScheduler.java:52) ~[na:na]
        at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:368) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:598) ~[intervenant-service:1.0.0]
        at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:294) ~[intervenant-service:1.0.0]
        at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430) ~[intervenant-service:1.0.0]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117) ~[intervenant-service:3.5.7]
        at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:716) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4480) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134) ~[na:na]
        at reactor.core.publisher.Operators.error(Operators.java:198) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoError.subscribe(MonoError.java:53) ~[na:na]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Flux.subscribe(Flux.java:8773) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:94) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxFromMonoOperator.subscribe(FluxFromMonoOperator.java:83) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxDeferContextual.subscribe(FluxDeferContextual.java:57) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[na:na]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) ~[na:na]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:291) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) ~[na:na]
        at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[na:na]
        at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) ~[na:na]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.innerNext(FluxConcatMapNoPrefetch.java:258) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:863) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[na:na]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) ~[na:na]
        at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2545) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.request(FluxConcatArray.java:276) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[na:na]
        at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164) ~[na:na]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.request(Operators.java:2305) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.request(FluxConcatMapNoPrefetch.java:338) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoNext$NextSubscriber.request(MonoNext.java:108) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2341) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2215) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoNext$NextSubscriber.onSubscribe(MonoNext.java:70) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxConcatMapNoPrefetch$FluxConcatMapNoPrefetchSubscriber.onSubscribe(FluxConcatMapNoPrefetch.java:164) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[na:na]
        at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[na:na]
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[na:na]
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[intervenant-service:3.5.7]
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[na:na]
        at reactor.netty.http.server.HttpServer$HttpServerHandle.onStateChange(HttpServer.java:1006) ~[na:na]
        at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:710) ~[na:na]
        at reactor.netty.transport.ServerTransport$ChildObserver.onStateChange(ServerTransport.java:481) ~[na:na]
        at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:621) ~[intervenant-service:1.1.8]
        at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:113) ~[intervenant-service:1.1.8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[intervenant-service:4.1.94.Final]
        at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:230) ~[intervenant-service:1.1.8]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[intervenant-service:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[intervenant-service:4.1.94.Final]
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[intervenant-service:4.1.94.Final]
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[na:na]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[na:na]
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[na:na]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[na:na]
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[na:na]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[na:na]
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[na:na]
        at java.base@17.0.7/java.lang.Thread.run(Thread.java:833) ~[intervenant-service:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:807) ~[intervenant-service:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:210) ~[na:na]

Comment From: wilkinsona

Your use of WebFlux.Fn means that no information is available in method signatures about the types that will be serialised to JSON. You can use [@RegisterReflectionForBinding](https://docs.spring.io/spring-framework/reference/core/aot.html#aot.hints.register-reflection-for-binding) to provide information about the types that need to be serialised to json. For example, adding@RegisterReflectionForBinding(EntityModel.class)togetIntervenantById` should fix the problem:

$ http :8082/intervenants 
HTTP/1.1 200 OK
Content-Length: 175
Content-Type: application/json

{
    "content": [
        {
            "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
            "links": [
                {}
            ],
            "nom": "Marchal"
        },
        {
            "id": "425e7701-02c6-4de3-9333-a2459eece1c8",
            "links": [
                {}
            ],
            "nom": "Dubois"
        }
    ],
    "links": [
        {}
    ]
}


$ http :8082/intervenants/de7d9052-4961-4b4f-938a-3cd12cbe1f82
HTTP/1.1 200 OK
Content-Length: 77
Content-Type: application/json

{
    "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
    "links": [
        {},
        {}
    ],
    "nom": "Marchal"
}

Comment From: odrotbohm

This will be fixed in Spring HATEOAS 2.0.5, 2.1.1 and 2.2 M1. I.e., it will be included in the next Spring Boot 3.x bug fix releases. Fix verified to make the original reproducer work.

Comment From: operrin

Thanks. To be fully correct, I had to add the following annotation: @RegisterReflectionForBinding({Link.class, EntityModel.class})

The EntityModel.classto avoid the MapSuppressingUnwrappingSerializer exception. And the Link.classto get the correct values for the links (otherwise, they are empty)

Comment From: odrotbohm

What request do I have to issue on your sample project to trigger the missing metadata for Link? HypermediaTypeAotProcessor should actually already add that metadata, and we have AOT smoke tests that show links being rendered properly in native images. 🤔

Comment From: operrin

When compiled with gradle bootJar, I issue the request http :8082/intervenants and I get:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 538

{
    "content": [
        {
            "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
            "nom": "Marchal",
            "prenom": "Thomas",
            "commune": "Nancy",
            "codepostal": "54000",
            "links": [
                {
                    "rel": "self",
                    "href": "http://localhost:8082/intervenants/de7d9052-4961-4b4f-938a-3cd12cbe1f82"
                }
            ]
        },
        {
            "id": "425e7701-02c6-4de3-9333-a2459eece1c8",
            "nom": "Dubois",
            "prenom": "Anne",
            "commune": "Grenoble",
            "codepostal": "38000",
            "links": [
                {
                    "rel": "self",
                    "href": "http://localhost:8082/intervenants/425e7701-02c6-4de3-9333-a2459eece1c8"
                }
            ]
        }
    ],
    "links": [
        {
            "rel": "collection",
            "href": "http://localhost:8082/intervenants"
        }
    ]
}

Links are correct.

Using @RegisterReflectionForBinding(EntityModel.class), when compiled with gradle nativeCompile, I get:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 290

{
    "content": [
        {
            "id": "de7d9052-4961-4b4f-938a-3cd12cbe1f82",
            "nom": "Marchal",
            "prenom": "Thomas",
            "commune": "Nancy",
            "codepostal": "54000",
            "links": [
                {}
            ]
        },
        {
            "id": "425e7701-02c6-4de3-9333-a2459eece1c8",
            "nom": "Dubois",
            "prenom": "Anne",
            "commune": "Grenoble",
            "codepostal": "38000",
            "links": [
                {}
            ]
        }
    ],
    "links": [
        {}
    ]
}

Links are empty.

Using @RegisterReflectionForBinding({Link.class,EntityModel.class}), when compiled with gradle nativeCompile, Links are correct.

Comment From: odrotbohm

Thanks, I'll have a look.

Comment From: odrotbohm

Ar you sure it's Link, not Links (trailing s)? It looks like the problem is a combination of Links not registered for reflection and your project not using a proper hypermedia media type but only application/json. That will cause EntityModel rendered as-is, and thus the custom Jackson directives we have in place for official hypermedia media types like HAL kick in. I can only recommend switching to one of those, as rendering anything but that is not supported officially.

I'll go ahead and augment the reflection registration for Links in the context of spring-projects/spring-hateoas#1981 (and corresponding back ports). But then again, you should see this work if you rather return application/hal+json or any other supported and properly specified hypermedia type.

Comment From: operrin

Thanks. It works with Link.class.

Regarding the MediaType, I just try the following modification:

    @RegisterReflectionForBinding(EntityModel.class)
    public Mono<ServerResponse> getIntervenantById(ServerRequest request) {
        var collectionLink = Link.of(deleteIdInUri(request.uri().toString(), request.pathVariable("id")))
                .withRel("collection");
        var selfLink = Link.of(request.uri().toString()).withSelfRel();
        return this.is.getIntervenant(request.pathVariable("id"))
                .flatMap(r -> Mono.just(EntityModel.of(r, selfLink, collectionLink)))
                .flatMap(r -> ServerResponse.ok().contentType(MediaTypes.HAL_JSON).bodyValue(r))
                .switchIfEmpty(ServerResponse.notFound().build());
    }

The result is empty links.

Comment From: operrin

Sorry, I carefully read your message, and I added a configuration class and used the @EnableHypermediaSupport annotation, and links are correctly rendered.

My apologies

Comment From: odrotbohm

No need to apologize. This is tremendously helpful. I just realized that the Spring HATEOAS auto-configuration is not activated in a Web.fn scenario. I wonder if that should be fixed by using a trigger type located in the WebFlux artifact? /cc @wilkinsona

Comment From: wilkinsona

https://github.com/spring-projects/spring-boot/issues/16020 is tracking some auto-configuration of HATEOAS with WebFlux. Perhaps we can get it moving again.

Comment From: odrotbohm

After re-reading the conversation in #16020, I think I'll go ahead and separate the AOT reflection hint generation for the fundamental Spring HATEOAS types from the one that covers the Jackson model types producing individual media types. That way, we get HATEOAS working on GraalVM out of the box, even if a user doesn't want to use a proper, supported hypermedia type. Even if we don't recommend that, I think it's better to reasonably work than partially fail.

I'll also mention the need to explicitly use @EnableHypermediaSupport with WebFlux / Web.fn setups in the reference docs.

Comment From: odrotbohm

To close this off for this ticket, I've updated the fix for spring-projects/spring-hateoas#1981 to make sure that all fundamental HATEOAS types are registered for reflection. That said, I still couldn't get proper HAL rendering working for your Web.fn setup. I'll have to investigate separately.