quarkus icon indicating copy to clipboard operation
quarkus copied to clipboard

QuarkusTest does not work with the kotlin PanacheRepositoryBase from quarkus-hibernate-orm-panache-kotlin

Open MartinX3 opened this issue 3 years ago • 8 comments

Describe the bug

Executing the junit tests results in Failed to initialize Arc

Expected behavior

Running junit tests with success (Possible if I remove @QuarkusTest)

Actual behavior

Using @QuarkusTest kills the junit test.

To Reproduce

quarkus-kotlin-java-11-panache-quarkustest-error.tar.gz

Steps to reproduce the behavior:

  1. ./gradlew test

Configuration

# Add your application.properties here, if applicable.
quarkus:
  datasource:
    db-kind: postgresql
    jdbc:
      url: jdbc:postgresql://localhost:9999/TestDB
    password: user
    username: user
  hibernate-orm:
    database:
      generation: update
  http:
    port: 8080
  log:
    min-level: DEBUG
    console:
      enable: true
      format: "%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n"
      color: true
      darken: 1
      json:
        pretty-print: true
"%test":
  quarkus:
    datasource:
      db-kind: h2
      jdbc:
        url: jdbc:h2:mem:test
      password: user
      username: user
    hibernate-orm:
      database:
        generation: drop-and-create
    http:
      test-port: 8805

Screenshots

N/A

Environment (please complete the following information):

Output of uname -a or ver

Linux martind-linuxiator 5.12.3-zen1-1-zen #1 ZEN SMP PREEMPT Wed, 12 May 2021 17:54:20 +0000 x86_64 GNU/Linux

Output of java -version

openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9)
OpenJDK 64-Bit Server VM (build 11.0.11+9, mixed mode)

GraalVM version (if different from Java)

N/A

Quarkus version or git rev

1.13.4.Final

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

------------------------------------------------------------
Gradle 7.0.2
------------------------------------------------------------

Build time:   2021-05-14 12:02:31 UTC
Revision:     1ef1b260d39daacbf9357f9d8594a8a743e2152e

Kotlin:       1.4.31
Groovy:       3.0.7
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          15.0.2 (Oracle Corporation 15.0.2+7)
OS:           Linux 5.12.3-zen1-1-zen amd64
> Task :test FAILED

JacksonResourceTest > list() FAILED
    java.lang.RuntimeException: java.lang.ExceptionInInitializerError
        at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:674)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:747)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.api.extension.InvocationInterceptor.interceptTestClassConstructor(InvocationInterceptor.java:72)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        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.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:77)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:342)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:289)
        at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:267)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:259)
        at java.base/java.util.Optional.orElseGet(Optional.java:362)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:258)
        at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:101)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:100)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:65)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:111)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:111)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:79)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
        at com.sun.proxy.$Proxy2.stop(Unknown Source)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:135)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
        at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
        at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.base/java.lang.Thread.run(Thread.java:832)

        Caused by:
        java.lang.ExceptionInInitializerError
            at java.base/java.lang.Class.forName0(Native Method)
            at java.base/java.lang.Class.forName(Class.java:468)
            at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:196)
            at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:331)
            at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:643)
            at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:689)
            at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$8(ClassBasedTestDescriptor.java:368)
            at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
            at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:368)
            at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:192)
            at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
            at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
            ... 56 more

            Caused by:
            java.lang.RuntimeException: Failed to start quarkus
                at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:304)
                ... 68 more

                Caused by:
                java.lang.RuntimeException: Failed to initialize Arc
                    at io.quarkus.arc.Arc.initialize(Arc.java:26)
                    at io.quarkus.arc.runtime.ArcRecorder.getContainer(ArcRecorder.java:40)
                    at io.quarkus.deployment.steps.ArcProcessor$generateResources-1025303321.deploy_0(ArcProcessor$generateResources-1025303321.zig:76)
                    at io.quarkus.deployment.steps.ArcProcessor$generateResources-1025303321.deploy(ArcProcessor$generateResources-1025303321.zig:40)
                    at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:251)
                    ... 68 more

                    Caused by:
                    java.lang.ClassFormatError: Illegal local variable table start_pc 42 in method 'org.acme.resteasyjackson.model.Quark org.acme.resteasyjackson.database.QuarkRepository.findById(java.util.UUID, javax.persistence.LockModeType)'
                        at java.base/java.lang.Class.forName0(Native Method)
                        at java.base/java.lang.Class.forName(Class.java:468)
                        at org.acme.resteasyjackson.database.QuarkRepository_Bean.<init>(QuarkRepository_Bean.zig:89)
                        at io.quarkus.arc.setup.Default_ComponentsProvider.addBeans1(Default_ComponentsProvider.zig:266)
                        at io.quarkus.arc.setup.Default_ComponentsProvider.getComponents(Default_ComponentsProvider.zig:38)
                        at io.quarkus.arc.impl.ArcContainerImpl.<init>(ArcContainerImpl.java:112)
                        at io.quarkus.arc.Arc.initialize(Arc.java:20)
                        ... 72 more

1 test completed, 1 failed
Finished generating test XML results (0.003 secs) into: /home/martin/Dokumente/Development/Projekte/Tests/Quarkus/quarkus-kotlin-java-11-db-error/build/test-results/test
Generating HTML test report...
Finished generating test html results (0.004 secs) into: /home/martin/Dokumente/Development/Projekte/Tests/Quarkus/quarkus-kotlin-java-11-db-error/build/reports/tests/test
Watching 132 directories to track changes
Watching 138 directories to track changes
Watching 139 directories to track changes
:test (Thread[Execution worker for ':',5,main]) completed. Took 3.547 secs.

FAILURE: Build failed with an exception.

MartinX3 avatar May 16 '21 16:05 MartinX3

/cc @FroMage, @Sanne, @evanchooly, @gsmet, @loicmathieu, @yrodiere

quarkus-bot[bot] avatar May 16 '21 16:05 quarkus-bot[bot]

This looks like the same issue in the comments on #4394. As I suspected, you're extending PanacheEntityBase and trying to use the repository pattern. Drop the extension from Quark and just use the repository pattern and you should be set.

evanchooly avatar May 17 '21 13:05 evanchooly

Thank you for your response @evanchooly I'm sorry for uploading a corrupted example project zip file.

I removed the PanacheEntityBase, but the issue is still preventing me from executing tests, until I remove the @QuarkusTest annotation.

MartinX3 avatar May 17 '21 14:05 MartinX3

The current reproducer doesn't seem to be mixing PanacheEntityBase and PanacheRepositoryBase. In the current version I only see PanacheRepositoryBase, yet the problem still persists

geoand avatar May 18 '21 09:05 geoand

@evanchooly @FroMage I tracked this down to being a Panache Mocking problem. It seems like the transformation that is applied when the source is a Kotlin file breaks the LocalVariableTable.

The same application works just fine if no transformation for mocking is made to the repository.

So I'll leave it to you to figure out what exactly is causing the problem :)

geoand avatar May 18 '21 12:05 geoand

Oh damnit, could you take a look @evanchooly ?

FroMage avatar May 26 '21 16:05 FroMage

Sounds like the problem is far more complicated since the last response is almost a year old.

MartinX3 avatar Feb 12 '22 11:02 MartinX3

Same issue here. It seems that the kotlin support is still not production ready in quarkus. In the repository pattern is also impossible to mock the PanacheEntity methods today, so both methods are bugged.

renatounai avatar Aug 05 '22 11:08 renatounai

I also discovered this problem today. When using Mockito with the Active record pattern, the same java.lang.ClassFormatError: Illegal local variable table start_pc 48 in method 'int MyEntity$Companion.update(java.lang.String, java.lang.Object[])' is thrown, mocking the Repository works just fine.

Such a shame I have to switch to the Repository pattern, since using the Active record patter is so much concise.

Ultranium avatar Aug 22 '22 17:08 Ultranium

Are you perchance importing the quarkus-mock extension in your build? Mocks are not currently supported in kotlin.

evanchooly avatar Aug 22 '22 23:08 evanchooly

@evanchooly

Are you perchance importing the quarkus-mock extension in your build?

I am importing the "quarkus-panache-mock" module.

Mocks are not currently supported in kotlin It's a pity.

Mocking a Repository works fine though.

Ultranium avatar Aug 23 '22 07:08 Ultranium

Curious. Maybe someday i'll have a chance to dig in to the differences. It's been pretty low priority so far.

evanchooly avatar Aug 24 '22 16:08 evanchooly

If this is still a problem, can someone upload a sample application we can take a look at?

geoand avatar Dec 23 '22 07:12 geoand

I'm using Quarkus version: 2.16.2.Final and I still get the Exception:

"Caused by: java.lang.ClassFormatError: Illegal local variable table start_pc 39 in method 'io.smallrye.mutiny.Uni de.ma.tw.app.persistence.account.model.AccountRepository.update(java.lang.String, java.util.Map)'"

import io.quarkus.hibernate.reactive.panache.kotlin.PanacheRepositoryBase
import java.util.UUID
import javax.enterprise.context.ApplicationScoped


@ApplicationScoped
class AccountRepository : PanacheRepositoryBase<AccountEntity, UUID> {
}
import io.quarkiverse.test.junit.mockk.InjectMock
@QuarkusTest
class AccountGatewayImplTest {

    @InjectMock
    private lateinit var accountRepository: AccountRepository

}

I added the dependency:

testImplementation("io.quarkus:quarkus-panache-mock")

oberstrike avatar Feb 25 '23 06:02 oberstrike

I switched to package 'io.quarkus:quarkus-junit5-mockito:3.0.0.Final' to mock the repositories and it works great. Maybe someone can confirm it.

ilyas-hallak avatar Apr 27 '23 07:04 ilyas-hallak

Thanks for checking.

I'll close this issue based on that comment and the fact that we never received a sample project that does not work.

geoand avatar Apr 27 '23 07:04 geoand