Skip to content

Can't instantiate proxy for class kotlin.Function2 - similar class definition #997

Open

Description

@rgonciarz

JDK 19
Quarkus 2.14.3.Final
Mockk 1.13.3
JUnit 5.9.1

I'm trying to replace an existing instance with mock:

typealias BroadcastSwitchActiveComputer = suspend (Computer) -> Either<BroadcastSwitchActiveComputerError, Unit>

kotlin.jvm.functions.Function2<? super Computer, ? super kotlin.coroutines.Continuation<? super arrow.core.Either<? extends BroadcastSwitchActiveComputerError, ? extends kotlin.Unit>>, ?>

I have several beans with similar Function2 class definition. However they have different Either's generic type.

val typeLiteral = object : TypeLiteral<BroadcastSwitchActiveComputer>() {}
private val mockInstance: BroadcastSwitchActiveComputer = mockk()
val beanInstance = CDI.current().select(typeLiteral, Named("BroadcastSwitchActiveComputer"))
QuarkusMock.installMockForInstance(mockInstance, beanInstance);

A full stack trace:

Failed to create test instance
org.junit.jupiter.api.extension.TestInstantiationException: Failed to create test instance
	at io.quarkus.test.junit.QuarkusTestExtension.initTestState(QuarkusTestExtension.java:773)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:737)
	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.api.extension.InvocationInterceptor.interceptTestClassConstructor(InvocationInterceptor.java:73)
	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:62)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:363)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:310)
	at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:286)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
	at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
	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.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	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:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	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 jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at io.quarkus.runner.bootstrap.RunningQuarkusApplicationImpl.instance(RunningQuarkusApplicationImpl.java:90)
	at io.quarkus.test.junit.QuarkusTestExtension.createActualTestInstance(QuarkusTestExtension.java:779)
	at io.quarkus.test.junit.QuarkusTestExtension.initTestState(QuarkusTestExtension.java:764)
	... 82 more
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: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.runner.bootstrap.RunningQuarkusApplicationImpl.instance(RunningQuarkusApplicationImpl.java:88)
	... 84 more
Caused by: io.mockk.MockKException: Can't instantiate proxy for class kotlin.Function2
	at io.mockk.impl.instantiation.JvmMockFactory.newProxy(JvmMockFactory.kt:64)
	at io.mockk.impl.instantiation.AbstractMockFactory.newProxy$default(AbstractMockFactory.kt:24)
	at io.mockk.impl.instantiation.AbstractMockFactory.mockk(AbstractMockFactory.kt:59)
	at rg.zerokvm.adapter.api.rest.BroadcastSwitchActiveComputerRestApiAdapterTest.<init>(BroadcastSwitchActiveComputerRestApiAdapterTest.kt:98)
	at rg.zerokvm.adapter.api.rest.BroadcastSwitchActiveComputerRestApiAdapterTest_Bean.create(Unknown Source)
	at rg.zerokvm.adapter.api.rest.BroadcastSwitchActiveComputerRestApiAdapterTest_Bean.get(Unknown Source)
	at rg.zerokvm.adapter.api.rest.BroadcastSwitchActiveComputerRestApiAdapterTest_Bean.get(Unknown Source)
	at io.quarkus.arc.impl.InstanceImpl.getBeanInstance(InstanceImpl.java:226)
	at io.quarkus.arc.impl.InstanceImpl.getInternal(InstanceImpl.java:212)
	at io.quarkus.arc.impl.InstanceImpl.get(InstanceImpl.java:97)
	... 89 more
Caused by: io.mockk.proxy.MockKAgentException: Failed to subclass interface kotlin.jvm.functions.Function2
	at io.mockk.proxy.jvm.ProxyMaker.proxy(ProxyMaker.kt:38)
	at io.mockk.impl.instantiation.JvmMockFactory.newProxy(JvmMockFactory.kt:34)
	... 98 more
Caused by: java.lang.IllegalArgumentException: Could not create type
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:170)
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
	at io.mockk.proxy.jvm.transformation.SubclassInstrumentation.subclass(SubclassInstrumentation.kt:51)
	at io.mockk.proxy.jvm.ProxyMaker.subclass(ProxyMaker.kt:119)
	at io.mockk.proxy.jvm.ProxyMaker.proxy(ProxyMaker.kt:35)
	... 99 more
Caused by: java.lang.LinkageError: loader 'app' attempted duplicate class definition for kotlin.jvm.functions.Function2$Subclass0. (kotlin.jvm.functions.Function2$Subclass0 is in unnamed module of loader 'app')
	at java.base/java.lang.ClassLoader.defineClass0(Native Method)
	at java.base/java.lang.System$2.defineClass(System.java:2307)
	at java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2439)
	at java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2416)
	at java.base/java.lang.invoke.MethodHandles$Lookup.defineClass(MethodHandles.java:1843)
	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 net.bytebuddy.utility.Invoker$Dispatcher.invoke(Unknown Source)
	at net.bytebuddy.utility.dispatcher.JavaDispatcher$Dispatcher$ForNonStaticMethod.invoke(JavaDispatcher.java:1032)
	at net.bytebuddy.utility.dispatcher.JavaDispatcher$ProxiedInvocationHandler.invoke(JavaDispatcher.java:1162)
	at jdk.proxy3/jdk.proxy3.$Proxy102.defineClass(Unknown Source)
	at net.bytebuddy.dynamic.loading.ClassInjector$UsingLookup.injectRaw(ClassInjector.java:1638)
	at net.bytebuddy.dynamic.loading.ClassInjector$AbstractBase.inject(ClassInjector.java:118)
	at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$UsingLookup.load(ClassLoadingStrategy.java:519)
	at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
	at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6317)
	at io.mockk.proxy.jvm.transformation.SubclassInstrumentation.doInterceptedSubclassing(SubclassInstrumentation.kt:98)
	at io.mockk.proxy.jvm.transformation.SubclassInstrumentation.subclass$lambda$0(SubclassInstrumentation.kt:54)
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
	... 103 more


Activity

  1. ecjante commented on Feb 3, 2023

    @ecjante

    I am receiving the same Can't instantiate proxy error inconsistently on our CircleCI workflows and has become one of our main "Flaky" test issues.

    This started happening after bumping to version 1.13.4. We have reverted back to 1.13.3 until we can figure out the root cause.

    For our use case, we are simply mocking a kotlin interface for a test.

    private var testDetails: Details? = null
    private val billingInventory: IBillingInventory = mockk {
        every { getDetails() } answers { testDetails }
    }

    which causes

    io.mockk.MockKException: Can't instantiate proxy for class IBillingInventory
    	at app//io.mockk.impl.instantiation.JvmMockFactory.newProxy(JvmMockFactory.kt:64)
    	at app//io.mockk.impl.instantiation.AbstractMockFactory.newProxy$default(AbstractMockFactory.kt:24)
    	at app//io.mockk.impl.instantiation.AbstractMockFactory.mockk(AbstractMockFactory.kt:59)
    

    Other instances involve mockking a java class that's provided via Dagger/Hilt which causes the same exception above.

    The main source I can find that could have possibly caused this was this recent change added in 1.13.4 #1025 where ProxyMaker was deduplicated, however, this may have been an issue before hand since the OP experienced this exception in 1.13.3 as well.

    Can anyone shed some light on why the exception is thrown?

  2. ygaller commented on Feb 12, 2023

    @ygaller
    Contributor

    We are seeing something similar. We upgraded from 1.12.2 to 1.13.4. We started seeing flakiness in tests due to the WeakReference. It's likely that there is a GC before the reference is attached to anything.

    package com.test
    
    import io.mockk.proxy.common.CancelableResult
    import org.junit.jupiter.api.Test
    
    class MockkTest {
    
      data class Payload(val something: String)
    
      @Test
      fun testing() {
        val result = CancelableResult(Payload("hello world"))
        System.gc()
        print(result.get())
      }
    }

    Result:

    io.mockk.proxy.MockKAgentException: Value for this result is not assigned
    
    	at io.mockk.proxy.common.CancelableResult.get(CancelableResult.kt:18)
    	at com.test.MockkTest.testing(MockkTest.kt:14)
    
  3. added a commit that references this issue on Feb 15, 2023
  4. ygaller commented on Feb 15, 2023

    @ygaller
    Contributor

    Created a PR with a fix for handling GCs but removing the WeakReference from ProxyMaker: #1052

  5. added 2 commits that reference this issue on Feb 15, 2023
  6. added a commit that references this issue on Feb 28, 2023
  7. orafaaraujo commented on Mar 2, 2023

    @orafaaraujo

    Hello

    I came here looking for some answers related to the MockKAgentException: Value for this result is not assigned that we're also facing after updating to version 1.13.4 and found a PR fixing it (many thanks, @ygaller 🙏).

    I noticed that the PR was merged two days ago. Do we have visibility of when the new release will come?

    Thank you in advance

  8. Raibaz commented on Apr 12, 2023

    @Raibaz
    Collaborator

    Just released 1.13.5!

  9. rschattauer commented on Jun 12, 2023

    @rschattauer

    I still get Caused by: io.mockk.proxy.MockKAgentException: Value for this result is not assigned on 1.13.5 (not on 1.13.3) when running all tests on random occasions. With jdk17 this problem increased drastically, while with jdk11 it is pretty rare.

  10. mabwah-arista commented on Jul 5, 2023

    @mabwah-arista

    This seems to have undid the fix from #1013, now I still have memory leaks since GC can't collect the spy objects when they're cleared.

  11. Tautellini commented on Sep 21, 2023

    @Tautellini

    We also have increased flakyness in our tests after updating to JDK17 and Mockk Android 1.13.4.
    We also downgraded for now.

    We got the following issues very frequently:
    MockKException: Can't instantiate proxy for class
    java.lang.InstantiationError
    MockKAgentException: Value for this result is not assigned

    Would like to add, that the only other change we have done is using the JVM parallel garbage collector as mentioned in an Android Documentation:
    https://developer.android.com/build/optimize-your-build#experiment-with-the-jvm-parallel-garbage-collector

    We also disabled that for now.

    Can this be related?

  12. JooHyukKim commented on Nov 28, 2023

    @JooHyukKim

    We are seeing something similar. We upgraded from 1.12.2 to 1.13.4. We started seeing flakiness in tests due to the WeakReference. It's likely that there is a GC before the reference is attached to anything.

    May I ask if this

    io.mockk.proxy.MockKAgentException: Value for this result is not assigned
    

    ... issue fixed in 1.13.5, @ygaller? I am experiencing same issue.

  13. ygaller commented on Nov 29, 2023

    @ygaller
    Contributor

    @JooHyukKim Yes this is fixed in 1.13.5

  14. JooHyukKim commented on Nov 29, 2023

    @JooHyukKim

    @ygaller Thank you for letting me know! 👍🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions