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

io.mockk:mockk:1.12.7 requires Java 11 all of a sudden #898

Closed
3 tasks done
TWiStErRob opened this issue Aug 24, 2022 · 10 comments · Fixed by #900 or #907
Closed
3 tasks done

io.mockk:mockk:1.12.7 requires Java 11 all of a sudden #898

TWiStErRob opened this issue Aug 24, 2022 · 10 comments · Fixed by #900 or #907

Comments

@TWiStErRob
Copy link

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Expected Behavior

Just works.

Current Behavior

Fails because of incorrect class files. Note this also breaks old Android versions, because API 21-24 are essentially JDK 8.

Failure Information (for bugs)

Potential fixes:

kotlin {
    jvmToolchain {
        languageVersion.set(JavaLanguageVersion.of("8"))
    }
}

or add jvmTarget = "1.8" to

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.apply {
freeCompilerArgs += listOf("-Xjsr305=strict")
apiVersion = "1.5"
languageVersion = "1.7"
}
}

Steps to Reproduce

  1. Update mockk
  2. Get failing tests
  3. Be surprised :)

on a serious note: just run any mockk test on Java 1.8. Up until 1.12.5 it was working, this is a major breaking change, not a patch.

Context

  • MockK version: 1.12.7 (1.12.5 works!)
  • OS: Windows 10
  • Kotlin version: 1.4.32
  • JDK version: 1.8
  • JUnit version: 4.13.2
  • Type of test: unit test OR android instrumented test

Related: #893

Stack trace

// -----------------------[ YOUR STACK STARTS HERE ] -----------------------
io/mockk/proxy/jvm/dispatcher/JvmMockKDispatcher has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
java.lang.UnsupportedClassVersionError: io/mockk/proxy/jvm/dispatcher/JvmMockKDispatcher has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
	at java.lang.ClassLoader.findBootstrapClass(Native Method)
	at java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:1015)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:413)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at io.mockk.proxy.jvm.dispatcher.BootJarLoader.loadBootJar(BootJarLoader.kt:32)
	at io.mockk.proxy.jvm.JvmMockKAgentFactory.initInstrumentation(JvmMockKAgentFactory.kt:139)
	at io.mockk.proxy.jvm.JvmMockKAgentFactory.init(JvmMockKAgentFactory.kt:33)
	at io.mockk.impl.JvmMockKGateway.<init>(JvmMockKGateway.kt:46)
	at io.mockk.impl.JvmMockKGateway.<clinit>(JvmMockKGateway.kt:186)
	at net.twisterrob.gradle.quality.report.html.XmlProducerTest$Robot.<init>(XmlProducerTest.kt:226)
	at net.twisterrob.gradle.quality.report.html.XmlProducerTest.produceXml writes xml(XmlProducerTest.kt:19)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	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.util.ArrayList.forEach(ArrayList.java:1249)
	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.util.ArrayList.forEach(ArrayList.java:1249)
	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 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	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$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)
// -----------------------[ YOUR STACK TRACE ENDS HERE ] -----------------------
@aSemy
Copy link
Contributor

aSemy commented Aug 24, 2022

v. quick note to say this suggestion won't work (but it should be added for consistency)

or add jvmTarget = "1.8" to

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions.apply {
freeCompilerArgs += listOf("-Xjsr305=strict")
apiVersion = "1.5"
languageVersion = "1.7"
}
}

because of this

// note: all subprojects are currently Kotlin Multiplatform, so this convention plugin is unused

It jvmTarget could be added here instead - but I don't know what effect that would have. There's been lots of problems with versions and compatibilities these last few releases...

targets.configureEach {
compilations.configureEach {
kotlinOptions {
apiVersion = "1.5"
languageVersion = "1.7"
}
}
}

@aSemy
Copy link
Contributor

aSemy commented Aug 24, 2022

Can you checkout the branch in #900, deploy it to Maven Local ./gradlew publishToMavenLocal, bump the MockK version in your project, and see if it fixes it for you?

@TWiStErRob
Copy link
Author

TWiStErRob commented Aug 25, 2022

first experience...

* What went wrong:
Execution failed for task ':buildSrc:compileKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
   > Not enough memory to run compilation. Try to increase it via 'gradle.properties':
     kotlin.daemon.jvmargs=-Xmx<size>

but it's my bad, I have JAVA_TOOL_OPTIONS=-Xms32M -Xmx256M -XX:+UseG1GC to restrict every single Java process that executes on my machine.
This is required because the default JVM setup is 1/4 of your overall memory. Now, if I have 96G RAM, that means I can run Gradle Daemon, Kotlin Daemon, and 2 unit tests in parallel by default... which sucks on a 28-core CPU.
I changed to below and it works fine, I recommend you add this explicitly to your repo.

diff --git a/gradle.properties b/gradle.properties
index ffe3f2b7..c519a31f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,8 @@ org.gradle.configureondemand=false
 org.gradle.parallel=true
 # disable annoying Gradle Welcome in CI/CD
 org.gradle.welcome=never
-org.gradle.jvmargs=-XX:MaxMetaspaceSize=768m
+org.gradle.jvmargs=-XX:MaxMetaspaceSize=768m -Xmx1G
+kotlin.daemon.jvmargs=-Xmx512M
 kotlin.mpp.stability.nowarn=true

re changes: no dice, local 1.12.8-SNAPSHOT from #900 also fails.
Tip: you can test it really fast if it works or not:
github-mockk\modules\mockk-agent\build\classes\java\main\io\mockk\proxy\jvm\dispatcher\JvmMockKDispatcher.class will be deployed to .m2\io\mockk\mockk-agent-jvm\1.12.8-SNAPSHOT\mockk-agent-jvm-1.12.8-SNAPSHOT.jar\io\mockk\proxy\jvm\dispatcher\JvmMockKDispatcher.class
which means you can just open the .class file (even with Notepad) in your build folder and see the version number at the first few bytes of the file (https://en.wikipedia.org/wiki/Java_class_file#General_layout):

  • bad: Êþº¾ 7 @ (Java SE 11 = 55 dec = 0x37 hex = ASCII character 7)
  • good: Êþº¾ 4 @ (Java SE 8 = 52 dec = 0x34 hex = ASCII character 4)

I tried this and it worked:

diff --git a/modules/mockk-agent/build.gradle.kts b/modules/mockk-agent/build.gradle.kts
index a660bc60..f61c460e 100644
--- a/modules/mockk-agent/build.gradle.kts
+++ b/modules/mockk-agent/build.gradle.kts
@@ -18,7 +18,9 @@ kotlin {
     jvm {
         withJava()
     }
-
+    jvmToolchain {
+        languageVersion.set(JavaLanguageVersion.of("8"))
+    }
     sourceSets {
         val commonMain by getting {
             dependencies {

@aSemy
Copy link
Contributor

aSemy commented Aug 25, 2022

Hmm strange. MockK has set up JVM Toolchains in a buildSrc convention plugin, though it's using JVM 11. You can change this in the root gradle.properties.

mockk/gradle.properties

Lines 13 to 16 in fe36b92

# version of Java that will be used to build the project
javaToolchainMainVersion=11
# the Java version tests will run against - this is overridden in the GitHub actions
javaToolchainTestVersion=11

kotlinOptions.jvmTarget is set to 1.8 though. I thought that should work: https://kotlinlang.org/docs/gradle.html#gradle-java-toolchains-support

@aSemy
Copy link
Contributor

aSemy commented Aug 26, 2022

Ah I see what's wrong - kotlin.jvmTarget works

image

but not all of MockK's source is Kotlin - there's still some Java code left.

image

Two options: try and figure out the Java jvmTarget equivalent, or migrate all .java code to .kt?

@TWiStErRob
Copy link
Author

TWiStErRob commented Aug 26, 2022

JavaCompile.targetCompatibility

@LikeTheSalad
Copy link

This still seems to be a problem with version 1.13.8, my project's tests cannot run unless I set my Java version to 11, which I cannot do since I'm working on a library so I wouldn't like to affect our users. Any ideas of whether this will get fixed at some point? Or is it now as expected?

@TWiStErRob
Copy link
Author

Related #1168? Very likely caused by #1056.

@Raibaz you could add CI to check Java 8 compatibility, even if it's just a sample project with hardcoded Java 8 that uses the library as an included build. I have done it recently for mockito-kotlin, see https://github.com/mockito/mockito-kotlin/tree/main/tests for the approach.

@TWiStErRob TWiStErRob changed the title io.mockk:mocck:1.12.7 requires Java 11 all of a sudden io.mockk:mockk:1.12.7 requires Java 11 all of a sudden Jan 5, 2024
@LikeTheSalad
Copy link

It seems like it was fixed in this PR: #1161

@TWiStErRob
Copy link
Author

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

Successfully merging a pull request may close this issue.

3 participants