Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quarkus Superheroes Quarkus 2 -> 3 upgrade issues #31400

Closed
edeandrea opened this issue Feb 24, 2023 · 68 comments
Closed

Quarkus Superheroes Quarkus 2 -> 3 upgrade issues #31400

edeandrea opened this issue Feb 24, 2023 · 68 comments
Labels
env/m1 Impacts Apple M1 machines kind/bug Something isn't working

Comments

@edeandrea
Copy link
Contributor

edeandrea commented Feb 24, 2023

Describe the bug

I'm in process of upgrading the Quarkus Superheroes to use Quarkus 3. I'm working on my own personal fork for the moment (https://github.com/edeandrea/quarkus-super-heroes on the quarkus3 branch - https://github.com/edeandrea/quarkus-super-heroes/tree/quarkus3).

I've run into a few things that I can't seem to figure out how to solve and could use some help/guidance

  1. Using the io.quarkus.test.TestReactiveTransaction annotation at the class level causes lots of errors
  2. Hibernate reactive not finding Vertx context
  3. No current Mutiny.Session found
  4. Mocking/stubbing/spying not working right

Using the io.quarkus.test.TestReactiveTransaction annotation at the class level causes lots of errors

Removing the annotation from the class and instead placing it on each & every test method in the class removes the errors. I would still call it a bug, though, but at least I can get past it.

This is the error I was seeing when @TestReactiveTransaction was placed at the class level:

java.lang.AssertionError: Reflective call to UniAsserter parameter failed, please file a bug report

    at io.quarkus.hibernate.reactive.panache.common.runtime.TestReactiveTransactionalInterceptor.handleSpecialTestMethod(TestReactiveTransactionalInterceptor.java:79)
    at io.quarkus.hibernate.reactive.panache.common.runtime.TestReactiveTransactionalInterceptor.intercept(TestReactiveTransactionalInterceptor.java:23)
    at io.quarkus.hibernate.reactive.panache.common.runtime.TestReactiveTransactionalInterceptorGenerated_Bean.intercept(Unknown Source)
    at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:38)
    at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:26)
    at io.quarkus.sample.superheroes.hero.repository.HeroRepositoryTests_Subclass.findAllWhereNameLikeNotFound(Unknown Source)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.test.vertx.RunOnVertxContextTestMethodInvoker$RunTestMethodOnContextHandler.doRun(RunOnVertxContextTestMethodInvoker.java:148)
    at io.quarkus.test.vertx.RunOnVertxContextTestMethodInvoker$RunTestMethodOnContextHandler.handle(RunOnVertxContextTestMethodInvoker.java:137)
    at io.quarkus.test.vertx.RunOnVertxContextTestMethodInvoker$RunTestMethodOnContextHandler.handle(RunOnVertxContextTestMethodInvoker.java:108)
    at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
    at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:246)
    at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:43)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at io.quarkus.hibernate.reactive.panache.common.runtime.TestReactiveTransactionalInterceptor.handleSpecialTestMethod(TestReactiveTransactionalInterceptor.java:66)
    ... 24 more
Caused by: java.lang.IllegalStateException: Can't get the context safety flag: the current context is not a duplicated context
    at io.quarkus.vertx.core.runtime.context.VertxContextSafetyToggle.checkIsSafe(VertxContextSafetyToggle.java:78)
    at io.quarkus.vertx.core.runtime.context.VertxContextSafetyToggle.validateContextIfExists(VertxContextSafetyToggle.java:72)
    at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.vertxContext(SessionOperations.java:183)
    at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.withSession(SessionOperations.java:112)
    at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.withTransaction(SessionOperations.java:99)
    at io.quarkus.hibernate.reactive.panache.common.runtime.TestReactiveTransactionalInterceptor$1.apply(TestReactiveTransactionalInterceptor.java:69)
    at io.quarkus.hibernate.reactive.panache.common.runtime.TestReactiveTransactionalInterceptor$1.apply(TestReactiveTransactionalInterceptor.java:66)
    at io.quarkus.test.vertx.DefaultUniAsserter.surroundWith(DefaultUniAsserter.java:129)
    ... 29 more

Hibernate reactive not finding Vertx context

In the rest-heroes application there's some issue with hibernate reactive where its not finding a Vertx context (see https://github.com/edeandrea/quarkus-super-heroes/actions/runs/4257167883/jobs/7406959691 the full test execution, failures, and errors). It seems to be the same problem causing all the failures.

What's somewhat interesting is that the tests that fail are tests that mutate data. Tests which only read data all run fine.

I did replace all instances of @ReactiveTransactional with @WithTransaction because @ReactiveTransactional is deprecated. Changing back to @ReactiveTransactional doesn't change anything. I still see the same failures.

Here's an excerpt of one of them:

Error:  io.quarkus.sample.superheroes.hero.service.HeroServiceTests.persistInvalidHero  Time elapsed: 0.002 s  <<< ERROR!
java.lang.IllegalStateException: No current Vertx context found
	at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.vertxContext(SessionOperations.java:186)
	at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.withSession(SessionOperations.java:112)
	at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.withTransaction(SessionOperations.java:86)
	at io.quarkus.hibernate.reactive.panache.common.runtime.WithTransactionInterceptor.intercept(WithTransactionInterceptor.java:19)
	at io.quarkus.hibernate.reactive.panache.common.runtime.WithTransactionInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:71)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:63)
	at io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor.span(WithSpanInterceptor.java:66)
	at io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:38)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:26)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass.persistHero(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService_ClientProxy.persistHero(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroServiceTests.persistInvalidHero(HeroServiceTests.java:308)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:1002)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:816)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.execute(LazyLauncher.java:55)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:223)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:175)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:139)
	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)

Error:    HeroServiceTests.deleteAllHeroes:650 » IllegalState No current Vertx context found
Error:    HeroServiceTests.deleteHero:632 » IllegalState No current Vertx context found
Error:    HeroServiceTests.fullyUpdateHero:469 » IllegalState No current Vertx context found
Error:    HeroServiceTests.fullyUpdateInvalidHero:415 » IllegalState No current Vertx context found
Error:    HeroServiceTests.fullyUpdateNotFoundHero:451 » IllegalState No current Vertx context found
Error:    HeroServiceTests.fullyUpdateNullHero:378 » IllegalState No current Vertx context found
Error:    HeroServiceTests.partiallyUpdateHero:597 » IllegalState No current Vertx context found
Error:    HeroServiceTests.partiallyUpdateInvalidHero:540 » IllegalState No current Vertx context found
Error:    HeroServiceTests.partiallyUpdateNotFoundHero:579 » IllegalState No current Vertx context found
Error:    HeroServiceTests.partiallyUpdateNullHero:502 » IllegalState No current Vertx context found
Error:    HeroServiceTests.persistHero:347 » IllegalState No current Vertx context found
Error:    HeroServiceTests.persistInvalidHero:308 » IllegalState No current Vertx context found
Error:    HeroServiceTests.persistNullHero:271 » IllegalState No current Vertx context found
Error:    HeroServiceTests.replaceAllHeroes:675 » IllegalState No current Vertx context found

No current Mutiny.Session found

What's a little more interesting is if I run the rest-heroes app in dev mode and then try to hit the /api/heroes/random endpoint (or any other endpoint) I get the following error, even though the tests which call these same operations pass.

If I add the @WithSession or @WithSessionOnDemand annotation to the HeroService class, then this error goes away. but then ALL the tests in HeroServiceTests fail (not just the ones that mutate data) with the No current Vertx context found error mentioned above.

10:23:50 ERROR [io.qu.ve.ht.ru.QuarkusErrorHandler] (vert.x-eventloop-thread-2) HTTP Request to /api/heroes/random failed, error id: e4ec7875-f766-411f-a9a3-62d7f3c32f69-1: java.lang.IllegalStateException: No current Mutiny.Session found
	- no reactive session was found in the context and the context was not marked to open a new session lazily
	- you might need to annotate the business method with @WithSession
	at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.getSession(SessionOperations.java:155)
	at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.getSession(AbstractJpaOperations.java:351)
	at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.findAll(AbstractJpaOperations.java:179)
	at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.listAll(AbstractJpaOperations.java:190)
	at io.quarkus.sample.superheroes.hero.repository.HeroRepository.listAll(HeroRepository.java)
	at io.quarkus.sample.superheroes.hero.repository.HeroRepository_ClientProxy.listAll(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService.findAllHeroes(HeroService.java:43)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass.findAllHeroes$$superforward1(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass$$function$$9.apply(Unknown Source)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:74)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:63)
	at io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor.span(WithSpanInterceptor.java:66)
	at io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:38)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:26)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass.findAllHeroes(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService_ClientProxy.findAllHeroes(Unknown Source)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at io.quarkus.sample.superheroes.hero.rest.HeroResource.getAllHeroes(HeroResource.java:94)
	at io.quarkus.sample.superheroes.hero.rest.HeroResource$quarkusrestinvoker$getAllHeroes_1c553b14073777e9b0f596eae9928c0c15d745dd.invoke(Unknown Source)
	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
	at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:114)
	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
	at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:48)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:23)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:10)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:101)
	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:87)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:140)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
	at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$1(StaticHandlerImpl.java:290)
	at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
	at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:833)


10:23:50 ERROR [or.jb.re.re.co.co.AbstractResteasyReactiveContext] (vert.x-eventloop-thread-2) Request failed: java.lang.IllegalStateException: No current Mutiny.Session found
	- no reactive session was found in the context and the context was not marked to open a new session lazily
	- you might need to annotate the business method with @WithSession
	at io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations.getSession(SessionOperations.java:155)
	at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.getSession(AbstractJpaOperations.java:351)
	at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.findAll(AbstractJpaOperations.java:179)
	at io.quarkus.hibernate.reactive.panache.common.runtime.AbstractJpaOperations.listAll(AbstractJpaOperations.java:190)
	at io.quarkus.sample.superheroes.hero.repository.HeroRepository.listAll(HeroRepository.java)
	at io.quarkus.sample.superheroes.hero.repository.HeroRepository_ClientProxy.listAll(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService.findAllHeroes(HeroService.java:43)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass.findAllHeroes$$superforward1(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass$$function$$9.apply(Unknown Source)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:74)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:63)
	at io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor.span(WithSpanInterceptor.java:66)
	at io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:38)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:26)
	at io.quarkus.sample.superheroes.hero.service.HeroService_Subclass.findAllHeroes(Unknown Source)
	at io.quarkus.sample.superheroes.hero.service.HeroService_ClientProxy.findAllHeroes(Unknown Source)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at io.quarkus.sample.superheroes.hero.rest.HeroResource.getAllHeroes(HeroResource.java:94)
	at io.quarkus.sample.superheroes.hero.rest.HeroResource$quarkusrestinvoker$getAllHeroes_1c553b14073777e9b0f596eae9928c0c15d745dd.invoke(Unknown Source)
	at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
	at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:114)
	at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
	at org.jboss.resteasy.reactive.server.handlers.RestInitialHandler.beginProcessing(RestInitialHandler.java:48)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:23)
	at org.jboss.resteasy.reactive.server.vertx.ResteasyReactiveVertxHandler.handle(ResteasyReactiveVertxHandler.java:10)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:177)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:101)
	at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:87)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:140)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
	at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendStatic$1(StaticHandlerImpl.java:290)
	at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
	at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:833)

As an additional troubleshooting step, I added @WithSession to the HeroService class, then added @RunOnVertxContext to the HeroServiceTests class and got lots of these errors:

16:30:34 WARN  [io.ve.co.im.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-3,5,main] has been blocked for 2365 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked

Mocking/stubbing/spying not working right

In the rest-fights application there's some issue with mocking/stubbing/spying within tests. See https://github.com/edeandrea/quarkus-super-heroes/actions/runs/4257167883/jobs/7406959585 for full the full test execution, failures, and errors.

For example, if you look at the test failure for io.quarkus.sample.superheroes.fight.service.FightServiceTests.findRandomFightersNoneFound it says

Wanted but not invoked:
fightService_Subclass.findRandomHero();
-> at io.quarkus.sample.superheroes.fight.service.FightService_Subclass.findRandomHero(Unknown Source)

However, there was exactly 1 interaction with this mock:
fightService_Subclass.findRandomFighters();

which isn't at all true. If you look at the code in io.quarkus.sample.superheroes.fight.service.FightService:

@Timeout(value = 4, unit = ChronoUnit.SECONDS)
@Fallback(fallbackMethod = "fallbackRandomFighters")
@WithSpan("FightService.findRandomFighters")
public Uni<Fighters> findRandomFighters() {
  Log.debug("Finding random fighters");

  var villain = findRandomVillain()
    .onItem().ifNull().continueWith(this::createFallbackVillain);

  var hero = findRandomHero()
    .onItem().ifNull().continueWith(this::createFallbackHero);

  return addDelay(Uni.combine()
    .all()
    .unis(hero, villain)
    .combinedWith(Fighters::new)
  );
}

@Timeout(value = 2, unit = ChronoUnit.SECONDS)
@Fallback(fallbackMethod = "fallbackRandomHero")
Uni<Hero> findRandomHero() {
  Log.debug("Finding a random hero");
  return this.heroClient.findRandomHero()
    .invoke(hero -> Log.debugf("Got random hero: %s", hero));
}

@Timeout(value = 2, unit = ChronoUnit.SECONDS)
@Fallback(fallbackMethod = "fallbackRandomVillain")
Uni<Villain> findRandomVillain() {
  Log.debug("Finding a random villain");
  return this.villainClient.findRandomVillain()
    .invoke(villain -> Log.debugf("Got random villain: %s", villain));
}

You can see that findRandomFighters definitely calls findRandomHero and findRandomVillain. You can even see this in the test log output:

21:55:54 DEBUG [io.quarkus.sample.superheroes.fight.service.FightService.findRandomFighters(FightService.java:88)] (main) Finding random fighters
21:55:54 DEBUG [io.quarkus.sample.superheroes.fight.service.FightService.findRandomHero(FightService.java:106)] (main) Finding a random hero
21:55:54 DEBUG [io.quarkus.sample.superheroes.fight.service.FightService.lambda$findRandomHero$1(FightService.java:108)] (main) Got random hero: null
21:55:54 DEBUG [io.quarkus.sample.superheroes.fight.service.FightService.findRandomVillain(FightService.java:114)] (main) Finding a random villain
21:55:54 DEBUG [io.quarkus.sample.superheroes.fight.service.FightService.lambda$findRandomVillain$2(FightService.java:116)] (main) Got random villain: null

In the test in io.quarkus.sample.superheroes.fight.service.FIghtServiceTests.findRandomFightersNoneFound:

@InjectSpy
FightService fightService;

@InjectMock
HeroClient heroClient;

@InjectMock
VillainClient villainClient;

@Test
public void findRandomFightersNoneFound() {
  PanacheMock.mock(Fight.class);
  when(this.heroClient.findRandomHero())
    .thenReturn(Uni.createFrom().nullItem());

  when(this.villainClient.findRandomVillain())
    .thenReturn(Uni.createFrom().nullItem());

  var fighters = this.fightService.findRandomFighters()
    .subscribe().withSubscriber(UniAssertSubscriber.create())
    .assertSubscribed()
    .awaitItem(Duration.ofSeconds(5))
    .getItem();

  assertThat(fighters)
    .isNotNull()
    .usingRecursiveComparison()
    .isEqualTo(new Fighters(createFallbackHero(), createFallbackVillain()));

  verify(this.heroClient).findRandomHero();
  verify(this.villainClient).findRandomVillain();
  verify(this.fightService).findRandomHero();
  verify(this.fightService).findRandomVillain();
  verify(this.fightService).addDelay(any(Uni.class));
  verify(this.fightService, never()).fallbackRandomHero();
  verify(this.fightService, never()).fallbackRandomVillain();
  PanacheMock.verifyNoInteractions(Fight.class);
}

you can see that it is verifying that the findRandomHero and findRandomVillain methods should have been called once, which the logs clearly show they did, but yet the mocking/spying doesn't see that they did.

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

Reproducer: https://github.com/edeandrea/quarkus-super-heroes/tree/quarkus3 (quarkus3 branch from https://github.com/edeandrea/quarkus-super-heroes)

For seeing the issues in rest-heroes:

  1. cd into rest-heroes
  2. Run ./mvnw clean verify

For seeing the issues in rest-fights:

  1. cd into rest-fights
  2. Run ./mvnw clean verify

Output of uname -a or ver

Doesn't really matter. My local machine is a mac m1, but the GH action (https://github.com/edeandrea/quarkus-super-heroes/actions/runs/4257167883) uses ubuntu.

Output of java -version

Temurin 11 or 17. The GH action (https://github.com/edeandrea/quarkus-super-heroes/actions/runs/4257167883) tests using both.

GraalVM version (if different from Java)

22.3.1

Quarkus version or git rev

3.0.0.Alpha4

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

@edeandrea edeandrea added the kind/bug Something isn't working label Feb 24, 2023
@quarkus-bot quarkus-bot bot added the env/m1 Impacts Apple M1 machines label Feb 24, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Feb 24, 2023

/cc @gastaldi (m1)

@edeandrea
Copy link
Contributor Author

edeandrea commented Feb 24, 2023

https://github.com/quarkiverse/quarkiverse/wiki/Migrating-to-Quarkus-3.x#its-all-gone-wrong-help says to mention @maxandersen and @holly-cummins, so there, I did it :)

Although maybe that was only for extension authors. Sorry If I pinged you and shouldn't have.

@gsmet
Copy link
Member

gsmet commented Feb 24, 2023

@mkouba could you have a look at this one? It looks related to Hibernate Reactive and Vert.x. Not exactly sure how the Jakarta changes could have broken it tbh.

@mkouba
Copy link
Contributor

mkouba commented Feb 24, 2023

@mkouba could you have a look at this one? It looks related to Hibernate Reactive and Vert.x. Not exactly sure how the Jakarta changes could have broken it tbh.

I'll take a look next Monday. I don't think it's related to the Jakarta changes. We did some breaking changes in Hibernate Reactive Panache... It's documented in the migration guide by the way.

@edeandrea
Copy link
Contributor Author

edeandrea commented Feb 24, 2023

It's documented in the migration guide by the way.

Yes I read the guide and attempted to follow it. If you see from my original note

What's a little more interesting is if I run the rest-heroes app in dev mode and then try to hit the /api/heroes/random endpoint (or any other endpoint) I get the following error, even though the tests which call these same operations pass.

If I add the @WithSession or @WithSessionOnDemand annotation to the HeroService class (or onto all of the methods), then this error goes away. but then ALL the tests in HeroServiceTests fail (not just the ones that mutate data) with the No current Vertx context found error mentioned above.

As an additional troubleshooting step, I added @WithSession to the HeroService class, then added @RunOnVertxContext to the HeroServiceTests class and got lots of these errors

16:30:34 WARN  [io.ve.co.im.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-3,5,main] has been blocked for 2365 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked

so I'm not quite sure where to go for from there. Issues 2 & 3 are most likely related. I think once one is solved the other will be solved too. Issues 1 & 4 aren't related I don't think. Maybe issue 1 is related too, but I'm not sure.

Also, I'm curious about this statement in the migration guide:

In some cases, the session is opened automatically on demand. For example, if a Panache entity method is invoked in a JAX-RS resource method in an application that includes the quarkus-resteasy-reactive extension.

In the case of these apps (as I would presume would be the case for MANY apps out there in the wild), the panache methods (using a Panache repository class in this particular instance) is NOT invoked directly from the JAX-RS methods. Instead, they are accessed from the "business tier", which is its own CDI bean. We could debate whether or not a JAX-RS layer even belongs talking directly to a persistence layer in an application, but regardless of what side of that debate you're on, there will be lots and lots of apps that don't, so this is going to come and bite them.

Is there a particular reason for this change in behavior? It just seems like lots of unnecessary boilerplate stuff that a user has to go through just to write a method that accesses data.

@mkouba
Copy link
Contributor

mkouba commented Feb 27, 2023

  • Using the io.quarkus.test.TestReactiveTransaction annotation at the class level causes lots of errors

Hm, I think that this should work because the io.quarkus.test.vertx.RunOnVertxContextTestMethodInvoker should be used if a test class is annotated with @TestReactiveTransaction. I'm not sure why it doesn't. @geoand do you have an idea?

  • Hibernate reactive not finding Vertx context

HeroServiceTests.persistInvalidHero() is not a valid test case anymore, i.e. you can't call a HR Panache entity from a blocking thread. As explained in https://quarkus.io/version/main/guides/hibernate-reactive-panache#testing you'll need to use the @RunOnVertxContext annotation and UniAsserter, maybe also the convenient TransactionalUniAsserterInterceptor.

  • No current Mutiny.Session found

@WithSession or @WithTransaction is the way to go for HeroResource.getRandomHero(). I'm not so sure about the but then ALL the tests in HeroServiceTests fail (not just the ones that mutate data) problem. But as I mentioned above the HeroServiceTests tests need to be rewritten anyway.

  • Mocking/stubbing/spying not working right

This will need more investigation but Uni.combine().all().unis(hero, villain) is not legal within the context of a single Hibernate Reactive session.

As an additional troubleshooting step, I added @WithSession to the HeroService class, then added @RunOnVertxContext to the HeroServiceTests class and got lots of these errors

Well, you can't call any Uni.await() on the event loop thread. That's why I say the test should be rewritten using the UniAsserter.

In the case of these apps (as I would presume would be the case for MANY apps out there in the wild), the panache methods (using a Panache repository class in this particular instance) is NOT invoked directly from the JAX-RS methods. Instead, they are accessed from the "business tier", which is its own CDI bean. We could debate whether or not a JAX-RS layer even belongs talking directly to a persistence layer in an application, but regardless of what side of that debate you're on, there will be lots and lots of apps that don't, so this is going to come and bite them.

You're right - for these apps an explicit session/transaction demarcation is required ATM.

We could in theory add @WithSessionOnDemand on any method of a CDI bean that returns Uni and makes use of a HR Panache entity/repository, i.e. use the similar approach as we do for JAX-RS resources...

Is there a particular reason for this change in behavior? It just seems like lots of unnecessary boilerplate stuff that a user has to go through just to write a method that accesses data.

Well, the main reason was consistency and alignment with Hibernate Reactive (and reactive in general). We don't store the current Mutiny.Session in the CDI context (the lifecycle of a reactive session does not fit the lifecycle of the CDI request context; note that we even removed the @RequestScoped Mutiny.Session bean!) and an execution of a HR panache entity is never offloaded on the current Vert.x context.

I'm all for improving the docs, migration guide and helping the users to overcome those limitations.

@geoand
Copy link
Contributor

geoand commented Feb 27, 2023

@mkouba I'll have a look at that this week and see what the problem is

@edeandrea
Copy link
Contributor Author

Thank you for taking a look @mkouba . Two questions on the HeroService and it's tests...

  1. The HeroServiceTests class completely mocks the HeroRepository via @InjectMock. In that case, why would the need for a session in the tests even matter?
  1. Why is Uni.combine().all().unis(hero, villain) not legal? How would someone make 2 simultaneous calls? These aren't calls to a database. These are calls using a jaxrs client.

@mkouba
Copy link
Contributor

mkouba commented Feb 27, 2023

Thank you for taking a look @mkouba . Two questions on the HeroService and it's tests...

1. The `HeroServiceTests` class completely mocks the `HeroRepository` via `@InjectMock`. In that case, why would the need for a session in the tests even matter?

Hm, you're right, the @InjectMock HeroRepository should not require a reactive session at all unless a method that is not mocked is called. I'll need to take a look at your branch.

2. Why is `Uni.combine().all().unis(hero, villain)` not legal? How would someone make 2 simultaneous calls? These aren't calls to a database. These are calls using a jaxrs client.

Sorry, I meant - it's not legal to use a reactive session concurrently. So in this case, it should be ok.

@geoand
Copy link
Contributor

geoand commented Feb 28, 2023

@mkouba I'll have a look at that this week and see what the problem is

@edeandrea Hibernate Reactive does yet work with Quarkus 3, we are working on it.

@mkouba
Copy link
Contributor

mkouba commented Feb 28, 2023

@mkouba I'll have a look at that this week and see what the problem is

@edeandrea Hibernate Reactive does yet work with Quarkus 3, we are working on it.

@geoand What do you mean? Which version of HR? I do use quarkus 3.0.0.Alpha4 and HR Panache (based on hibernate-reactive-core-jakarta:hibernate-reactive-core-jakarta) in my test app and it works just fine.

@geoand
Copy link
Contributor

geoand commented Feb 28, 2023

I am talking about main. There is no point in trying to figure out what is going on with HR in the Alpha versions, as there are too many changes being made to support the move to ORM 6

@edeandrea
Copy link
Contributor Author

So @geoand guess that means I just leave it for now?

The 1st 3 issues are probably related to hibernate reactive.

The last one (mocking/spying/etc) is not. The fights service is reactive but uses panache with mongodb. Not HR.

@geoand
Copy link
Contributor

geoand commented Feb 28, 2023

Yes, hopefully we can pick it up next week

@edeandrea
Copy link
Contributor Author

Got it. Thank you both for looking into things!

@geoand
Copy link
Contributor

geoand commented Feb 28, 2023

Thanks for reporting the issue :)

Let's circle back next week and see if we can address it

@edeandrea
Copy link
Contributor Author

edeandrea commented Mar 8, 2023

Hi folks. FYI I upgraded things to Alpha5. As expected, the things involving hibernate reactive I can't even take the alpha5 upgrade because of https://quarkus.io/blog/quarkus-3-0-0-alpha5-released/#hibernate-reactive-temporarily-disabled

But the last issue (# 4 in my original list) (Mocking/stubbing/spying not working right) is still broken.

@geoand
Copy link
Contributor

geoand commented Mar 9, 2023

Any chance you can provide a standalone simplified sample that shows the mocking/spying problem?

@edeandrea
Copy link
Contributor Author

I can try to take this app and strip it down as bare as it can get while still showing the problem.

@geoand
Copy link
Contributor

geoand commented Mar 9, 2023

Thanks a lot

@edeandrea
Copy link
Contributor Author

edeandrea commented Mar 9, 2023

@geoand I created https://github.com/edeandrea/quarkus3-supes-mocking which is as stripped down as I can get it (no Kafka/stork/rest client/rest endpoints/mapstruct/removing timeout fault tolerance/etc) to still show the problem. The repo has 2 identical versions of the stripped down app, 1 with Quarkus 2 & 1 with Quarkus 3. All tests pass in the quarkus 2 version yet there are failures in the Quarkus 3 version.

The README file has specific details.

@geoand
Copy link
Contributor

geoand commented Mar 9, 2023 via email

@edeandrea
Copy link
Contributor Author

Let me know if you need anything else

@geoand
Copy link
Contributor

geoand commented Mar 9, 2023

There seems to be something funky going on with the Bean subclasses. @mkouba @Ladicek could this be due to the changes in handling synthetic methods we were talking about earlier?

@edeandrea reproducer is super useful here as it has both a Quarkus 2 version that works as expected and a failing Quarkus 3 version.

@edeandrea
Copy link
Contributor Author

I don't ever want to hear "you write too many tests" 😸

@edeandrea
Copy link
Contributor Author

@geoand I'll update the superheroes and the mock reproducer I built to 3.0.0.Beta1 tomorrow and report back of anything gets fixed (or gets broken further :) )

@edeandrea
Copy link
Contributor Author

ok so I couldn't wait :)

The mocking issue still exists in 3.0.0.Beta1. I updated https://github.com/edeandrea/quarkus3-supes-mocking to 2.16.5.Final & 3.0.0.Beta1. 3.0.0.Beta is still broken.

The other stuff with Hibernate reactive (no Vertx context found, etc) is still broken, even after adding all the aforementioned session controls to the methods.

I updated https://github.com/edeandrea/quarkus-super-heroes/tree/quarkus3 to 3.0.0.Beta1. You can see the latest build result at https://github.com/edeandrea/quarkus-super-heroes/actions/runs/4506826311

@geoand
Copy link
Contributor

geoand commented Mar 24, 2023

Thanks

@yrodiere
Copy link
Member

something else completely unrelated to the exception propagation question. I notice when I start the app its running importing the import.sql twice...

#31519

@edeandrea
Copy link
Contributor Author

#31519

Thanks @yrodiere !

@mkouba
Copy link
Contributor

mkouba commented Mar 24, 2023

I would think that any failure at any point in the pipeline should propagate within the pipeline and not break it?

The problem is that here the exception is thrown "outside" the pipeline.

In theory, HV could return Uni.createFrom().failure(new ConstraintViolationException(...)) instead of throw new ConstraintViolationException(...) in case of the method returns Uni...

@cescoffier
Copy link
Member

yes, it should returned a failed Uni in this case. I'm wondering how it worked before.

@geoand
Copy link
Contributor

geoand commented Mar 27, 2023

I remember @geoand giving it a try but I thought there was a blocker. I can't find the PR anymore...

Yup, I had tried something (I think I had only posted it in a comment of an issue) and you had mentioned that it was more complex

@yrodiere
Copy link
Member

I remember @geoand giving it a try but I thought there was a blocker. I can't find the PR anymore...

Yup, I had tried something (I think I had only posted it in a comment of an issue) and you had mentioned that it was more complex

Right, now I found your proposal and my answer explaining some problems and edge cases.

Interestingly, Clément supposedly implemented validation for Reactive Routes, except for Multi: #11864. I'm guessing there must be some limitations there, though, since some things don't seem possible unless we introduce some way for Hibernate Validator to understand @Min(0) Uni<Integer> as @Min(0) Integer, for example.

Back to our topic... no, it doesn't seem like validation of reactive methods ever worked in RestEasy Reactive.

@geoand
Copy link
Contributor

geoand commented Mar 27, 2023

it doesn't seem like validation of reactive methods ever worked in RestEasy Reactive.

I certainly never did anything to make it work :)

@edeandrea
Copy link
Contributor Author

I certainly never did anything to make it work :)

So is it a bug or a feature that it works in 2.x 😁

@geoand
Copy link
Contributor

geoand commented Mar 27, 2023

An accident :)

@edeandrea
Copy link
Contributor Author

Maybe one thing I should mention. The methods in question here are NOT on a rest resource method. They're in another class entirely (business method on another bean).

Validation of a request body in a jax-rs method works as it should.

@edeandrea
Copy link
Contributor Author

@geoand FYI the mocking issue still exists in 3.0.0.CR1. I updated https://github.com/edeandrea/quarkus3-supes-mocking to 3.0.0.CR1.

@geoand
Copy link
Contributor

geoand commented Mar 31, 2023

Thanks for the update

@geoand
Copy link
Contributor

geoand commented Mar 31, 2023

Did we have a dedicated issues for that?

@edeandrea
Copy link
Contributor Author

No, it was part of this thread. I can create one though if you'd like.

@geoand
Copy link
Contributor

geoand commented Mar 31, 2023

Let's do that as this thread has too many discussions.

@edeandrea
Copy link
Contributor Author

@geoand I opened #32300 for the mocking/stubbing issue

@edeandrea
Copy link
Contributor Author

Thank you everyone that has helped out so far!

I took CR2 and the mocking issue (from #32300) is now resolved.

I'm now stuck on 2 things

  1. Constraint validation failures in a reactive pipeline is breaking the pipeline. @cescoffier mentioned that it shouldn't, so should someone look at what changed between Quarkus 2 & 3? Should I create a separate GH issue for that?

  2. Another instance of being "bitten" by the Hibernate Reactive CDI changes @mkouba (also tagging @holly-cummins for Pact visibility)

    I have a test class and in my @BeforeEach method that mocks a hibernate reactive repository class. It now breaks with No current Vertx context found. I can not use UniAsserter in this method because it integrates with the Pact testing framework and a Pact-specific object is injected. The class in question is https://github.com/edeandrea/quarkus-super-heroes/blob/main/rest-heroes/src/test/java/io/quarkus/sample/superheroes/hero/ContractVerificationTests.java

    The class itself mocks the repository class but again I can't seem to successfully run the test because even though I am mocking the interaction it still thinks that it needs a session.

    I also can't use @RunOnVertxContext because the tests use JUnit test templates. My entire pact contract verification test class is now broken and I'm not sure how to solve it. This seems like its going to be a recurring problem anytime a test class uses a hibernate reactive class, even if the hibernate reactive "stuff" is completely mocked and the test doesn't care about it.

@mkouba
Copy link
Contributor

mkouba commented Apr 6, 2023

I have a test class and in my @BeforeEach method that mocks a hibernate reactive repository class.

@edeandrea Hm, it's not a mock but a spy, i.e. you only mock the findRandom() method and all other methods are delegated to the original repository bean. Could it be that some other method is called in a test?

@edeandrea
Copy link
Contributor Author

Nope no other method on the repository is called in that flow. The repository class itself is also annotated with @WithTransaction

@edeandrea
Copy link
Contributor Author

Should I open a separate issue on the constraint validation issue mentioned in #31400 (comment)? Seems like a regression between Quarkus 2 & 3. @cescoffier mentioned that the exception should not bubble up outside of the reactive pipeline.

@geoand
Copy link
Contributor

geoand commented Apr 12, 2023

Yes, it's very hard to use a single issue to track all different problems. I would also close this one to TBH as some things have been fixed and as such the issue has outlived its usefulness.

@edeandrea
Copy link
Contributor Author

Will do that later today.

@edeandrea
Copy link
Contributor Author

I'll even build as small a reproducer as possible :)

@geoand
Copy link
Contributor

geoand commented Apr 12, 2023

💪🏼

@edeandrea
Copy link
Contributor Author

@geoand I opened #32578 for this issue and I am closing this issue.

@geoand
Copy link
Contributor

geoand commented Apr 12, 2023

Thanks

@edeandrea
Copy link
Contributor Author

edeandrea commented Apr 13, 2023

Thought I'd let folks know I got the 1st successful build of the superheroes with Quarkus 3 today! https://github.com/edeandrea/quarkus-super-heroes/actions/runs/4692776058

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
env/m1 Impacts Apple M1 machines kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants