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

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

Open
rgonciarz opened this issue Dec 10, 2022 · 11 comments

Comments

@rgonciarz
Copy link

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


@ecjante
Copy link

ecjante commented Feb 3, 2023

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?

@ygaller
Copy link
Contributor

ygaller commented Feb 12, 2023

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)

ygaller added a commit to ygaller/mockk that referenced this issue Feb 15, 2023
@ygaller
Copy link
Contributor

ygaller commented Feb 15, 2023

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

ygaller added a commit to ygaller/mockk that referenced this issue Feb 15, 2023
ygaller added a commit to ygaller/mockk that referenced this issue Feb 15, 2023
Raibaz added a commit that referenced this issue Feb 28, 2023
Issue #997 - Simulate garbage collected proxy
@orafaaraujo
Copy link

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

@Raibaz
Copy link
Collaborator

Raibaz commented Apr 12, 2023

Just released 1.13.5!

@rschattauer
Copy link

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.

@mabwah-arista
Copy link

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.

@Tautellini
Copy link

Tautellini commented Sep 21, 2023

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?

@JooHyukKim
Copy link

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.

@ygaller
Copy link
Contributor

ygaller commented Nov 29, 2023

@JooHyukKim Yes this is fixed in 1.13.5

@JooHyukKim
Copy link

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants