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

Java 11 compatibility with inline mocks #1483

Closed
GMillerVarian opened this issue Aug 22, 2018 · 32 comments
Closed

Java 11 compatibility with inline mocks #1483

GMillerVarian opened this issue Aug 22, 2018 · 32 comments
Labels

Comments

@GMillerVarian
Copy link

Java 11 compatibility was addressed under issue #1419, however with inline mocks (required to mock private/final classes) it is still not working. Please see comments under issue #1419.

@mockitoguy
Copy link
Member

@raphw, can you chime in? Thanks!

@raphw
Copy link
Member

raphw commented Aug 23, 2018

Run it with -Dnet.bytebuddy.experimental=true. Its necessary for now as this might break for any new EA release if last minute changes are applied. Use at own risk after any EA update.

@davinkevin
Copy link

I have the same problem on Java 10 (and not Java 8) with mocked class coming from Kotlin code.

Using the -Dnet.bytebuddy.experimental=true flag on maven build didn't change things.

The only solution I found was to add the byte buddy dependencies under a specific Java10 profile

<dependency>
                    <groupId>net.bytebuddy</groupId>
                    <artifactId>byte-buddy</artifactId>
                    <version>1.8.13</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>net.bytebuddy</groupId>
                    <artifactId>byte-buddy-agent</artifactId>
                    <version>1.8.13</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>org.objenesis</groupId>
                    <artifactId>objenesis</artifactId>
                    <version>2.6</version>
                    <scope>compile</scope>
                </dependency>

@raphw
Copy link
Member

raphw commented Sep 5, 2018

I just sent a PR for Byte Buddy that should fix Java 11 support.

@raphw
Copy link
Member

raphw commented Sep 5, 2018

But we probably need to update Objenesis, too.

@Stephan202
Copy link
Contributor

Just tested Mockito 2.22.0 and Byte Buddy 1.8.22 with inline mocks using build openjdk-11+28 on a rather large code base; fails without -Dnet.bytebuddy.experimental=true but passes with it 👍. Tnx @raphw :)

@raphw
Copy link
Member

raphw commented Sep 16, 2018

Good to hear. Still waiting for ASM to reach 7.0, then I am spinning up a release and patch Mockito upstream.

@PyvesB
Copy link

PyvesB commented Sep 26, 2018

Using the latest version of Mockito (2.22.0), simply adding the following as a test dependency to my pom.xml allowed the tests to run happily:

 <dependency>
  <groupId>net.bytebuddy</groupId>
  <artifactId>byte-buddy</artifactId>
  <version>1.8.22</version>
  <scope>test</scope>
</dependency>

@sormuras
Copy link

Still waiting for ASM to reach 7.0, then I am spinning up a release and patch Mockito upstream.

ASM 7.0 was released yesterday, @raphw

@raphw
Copy link
Member

raphw commented Oct 28, 2018

Byte Buddy already used the beta but I updated today. Thanks for the ping.

@unrelentingfox
Copy link

Any idea when we should expect this to work again without having to use -Dnet.bytebuddy.experimental=true? I tried compiling mockito-core 2.23.3 and the issue is still present.

@raphw
Copy link
Member

raphw commented Nov 14, 2018

Could you check your class path to see if there is an old version of Byte Buddy somewhere on it? Byte Buddy 1.9.0 which comes with Mockito should do just fine with Java 11.

@unrelentingfox
Copy link

You're right, I have older versions being used elsewhere in my project that must have been pulled in. I was able to get it to work by explicitly adding byte-buddy 1.9.0 to my pom.xml. Thanks!

@chanseokoh
Copy link

chanseokoh commented Jan 14, 2019

Trying to migrate a Gradle project from Java 8 to Java 11 (with the new module-info.java), I get the following error. My issue seems different from #1419, and having net.bytebuddy.experimental=true in gradle.properties has no effect. (FYI, I'm basically setting various module-related flags when compiling and running tests in the module path as described in the Gradle doc, since there is no working plugin properly supporting Jigsaw.)

com.google.cloud.tools.jib.event.EventHandlersTest > testAdd FAILED
    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
        at org.mockito@2.23.4/org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:74)
        at com.sun.proxy.$Proxy14.isTypeMockable(Unknown Source)
        at org.mockito@2.23.4/org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
        at org.mockito@2.23.4/org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
        at org.mockito@2.23.4/org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:238)
        at org.mockito@2.23.4/org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:226)
        at org.mockito@2.23.4/org.mockito.internal.MockitoCore.mock(MockitoCore.java:68)
        at org.mockito@2.23.4/org.mockito.Mockito.mock(Mockito.java:1896)
        at org.mockito@2.23.4/org.mockito.Mockito.mock(Mockito.java:1805)
        at com.google.cloud.tools.jib/com.google.cloud.tools.jib.event.EventHandlersTest.testAdd(EventHandlersTest.java:67)

        Caused by:
        java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.lang.CompoundEnumeration@49b0303e

            Caused by:
            org.mockito.exceptions.base.MockitoInitializationException:
            Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

            Java               : 11
            JVM vendor name    : Oracle Corporation
            JVM vendor version : 11.0.1+13
            JVM name           : OpenJDK 64-Bit Server VM
            JVM version        : 11.0.1+13
            JVM info           : mixed mode
            OS name            : Linux
            OS version         : 4.18.10-1rodete2-amd64

                Caused by:
                java.lang.IllegalStateException:
                Mockito failed to inject the MockMethodDispatcher class into the bootstrap class loader

                It seems like your current VM does not support the instrumentation API correctly.

                    Caused by:
                    java.lang.ClassNotFoundException: org.mockito.internal.creation.bytebuddy.MockMethodDispatcher

Isn't org.mockito.internal.creation.bytebuddy.MockMethodDispatcher in the same org.mockito module that is trying to load the class inside it? Can't figure out why the module cannot load it.

@raphw
Copy link
Member

raphw commented Jan 15, 2019

I worked a lot with supporting the module system recently and fixed a lot of issues in yesterday night's release. Could you try with this release?

The MockMethodDispatcher class is injected into the bootstrap class loader to be universally visible. There is a chance that I am missing something there. Does everthing work for you if you are not using Mockito as a named module?

@chanseokoh
Copy link

Thanks @raphw,

We are on the Java 8 world, and everything has been working fine. As I said, I am experimenting moving everything to Java 11.

I've compiled the repo locally, generated mockito-core-2.23.17.jar, and loaded it in my project. The log message shows that the module version is 2.23.17. Now it gives java.lang.ClassNotFoundException: net.bytebuddy.agent.ByteBuddyAgent, regardless of net.bytebuddy.experimental=true.

com.google.cloud.tools.jib.event.EventHandlersTest > testAdd FAILED
    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)
        at org.mockito@2.23.17/org.mockito.internal.configuration.plugins.PluginLoader$1.invoke(PluginLoader.java:74)
        at com.sun.proxy.$Proxy14.isTypeMockable(Unknown Source)
        at org.mockito@2.23.17/org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:29)
        at org.mockito@2.23.17/org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:22)
        at org.mockito@2.23.17/org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:238)
        at org.mockito@2.23.17/org.mockito.internal.creation.MockSettingsImpl.build(MockSettingsImpl.java:226)
        at org.mockito@2.23.17/org.mockito.internal.MockitoCore.mock(MockitoCore.java:61)
        at org.mockito@2.23.17/org.mockito.Mockito.mock(Mockito.java:1896)
        at org.mockito@2.23.17/org.mockito.Mockito.mock(Mockito.java:1805)
        at com.google.cloud.tools.jib/com.google.cloud.tools.jib.event.EventHandlersTest.testAdd(EventHandlersTest.java:67)

        Caused by:
        java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.lang.CompoundEnumeration@58a4a09d

            Caused by:
            org.mockito.exceptions.base.MockitoInitializationException: 
            Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

            Java               : 11
            JVM vendor name    : Oracle Corporation
            JVM vendor version : 11.0.1+13
            JVM name           : OpenJDK 64-Bit Server VM
            JVM version        : 11.0.1+13
            JVM info           : mixed mode
            OS name            : Linux
            OS version         : 4.18.10-1rodete2-amd64

                Caused by:
                java.lang.NoClassDefFoundError: net/bytebuddy/agent/ByteBuddyAgent

                    Caused by:
                    java.lang.ClassNotFoundException: net.bytebuddy.agent.ByteBuddyAgent

I then tried adding net.bytebuddy:byte-buddy-agent,

  testImplementation 'org.mockito:mockito-core:2.23.17'
  //testImplementation 'org.mockito:mockito-core:2.23.4'
  testImplementation 'net.bytebuddy:byte-buddy-agent:1.9.7'

Then this goes back to give me the exact same error as in #1483 (comment).

If you are interested, you can try this yourself with this branch of the repo, where I cut down build.gradle.

git clone https://github.com/GoogleContainerTools/jib.git && cd jib
git checkout snapshot-jib-core-java-11-test
cd jib-core
./gradlew build

@raphw
Copy link
Member

raphw commented Jan 16, 2019

Thanks, I will try this out some time soon. Did you however experience that this did not happen when you used Mockito as an unnamed module rather then an automatic one?

I wrote a unit test that loads Mockito and Byte Buddy as unnamed modules and those work, I really wonder why this causes a problem. Are you maybe missing the java.instrument module? Could you try adding it explicitly, maybe that is the problem.

I will also get back to you once I got to investigate your issue.

@chanseokoh
Copy link

java.instrument is there. I've put --list-modules in build.gradle to print out the modules.

Successfully started process 'Gradle Test Executor 3'
java.base@11.0.1
java.compiler@11.0.1
java.datatransfer@11.0.1
java.desktop@11.0.1
java.instrument@11.0.1   <-- it's there
java.logging@11.0.1
java.management@11.0.1
java.management.rmi@11.0.1

Anyway, I tried explicitly adding java.instrument to --module-path, but of no avail.

test {
  ...
  doFirst {
    jvmArgs = [
        '--module-path', classpath.asPath + ':java.instrument',

@chanseokoh
Copy link

chanseokoh commented Jan 16, 2019

Did you however experience that this did not happen when you used Mockito as an unnamed module rather then an automatic one?

Just tried it. It sort of works with 2.23.17, but I had to manually add Objenesis, byte-buddy, and byte-buddy-agent. (UPDATE: the additional libraries are probably due to #1483 (comment).) I did not need net.bytebuddy.experimental = true.

test {
  inputs.property("moduleName", moduleName)
  doFirst {
    jvmArgs = [
       // Take out org.mockito@2.23.17 from module path.
       // "mockito-libs/mockito-core-2.23.17.jar" is a JAR that I built locally from Mockito source repo.
       '--module-path', classpath.minus(files('mockito-libs/mockito-core-2.23.17.jar')).asPath,
       ...
   ]
   ...
   classpath = files(sourceSets.test.output.resourcesDir,
       // Add it to class path instead.
       'mockito-libs/mockito-core-2.23.17.jar')

Before starting, I just opened and exported every package temporarily just for my convenience. I'll need to figure out what to do ultimately.

open /* opens everything */ module com.google.cloud.tools.jib {
  exports com.google.cloud.tools.jib;
  exports com.google.cloud.tools.jib.api;
  exports ...
  ... (exports everything) ...

As above, I removed org.mockito@2.23.17 from the module path and added the JAR in the class path. It gave me

com.google.cloud.tools.jib.builder.steps.RetrieveRegistryCredentialsStepTest > classMethod FAILED
    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)

        Caused by:
        java.lang.NoClassDefFoundError: net/bytebuddy/TypeCache

            Caused by:
            java.lang.ClassNotFoundException: net.bytebuddy.TypeCache

I added

  testImplementation 'net.bytebuddy:byte-buddy:1.9.7'

Then it gave me

    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.MockMaker (alternate: null)

        Caused by:
        java.lang.IllegalStateException: Failed to load interface org.mockito.plugins.MockMaker implementation declared in java.lang.CompoundEnumeration@221bceb7

            Caused by:
            org.mockito.exceptions.base.MockitoInitializationException:
            Could not initialize inline Byte Buddy mock maker. (This mock maker is not supported on Android.)

            Java               : 11
            JVM vendor name    : Oracle Corporation
            JVM vendor version : 11.0.1+13
            JVM name           : OpenJDK 64-Bit Server VM
            JVM version        : 11.0.1+13
            JVM info           : mixed mode
            OS name            : Linux
            OS version         : 4.18.10-1rodete2-amd64

                Caused by:
                java.lang.NoClassDefFoundError: net/bytebuddy/agent/ByteBuddyAgent

                    Caused by:
                    java.lang.ClassNotFoundException: net.bytebuddy.agent.ByteBuddyAgent

I added

  testImplementation 'net.bytebuddy:byte-buddy-agent:1.9.7'

Then it gave me

    java.lang.IllegalStateException: Could not initialize plugin: interface org.mockito.plugins.InstantiatorProvider2 (alternate: interface org.mockito.plugins.InstantiatorProvider)

        Caused by:
        java.lang.NoClassDefFoundError: org/objenesis/ObjenesisStd

            Caused by:
            java.lang.ClassNotFoundException: org.objenesis.ObjenesisStd

I added

  testImplementation 'org.objenesis:objenesis:3.0.1'

Now it works.

> Task :test
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

BUILD SUCCESSFUL in 7s
7 actionable tasks: 7 executed

@raphw
Copy link
Member

raphw commented Jan 16, 2019

It is strange that Gradle does not detect those dependencies. They are published correctly in the POM.

As for your problem, I debug this and found a strange behavior of Class.forName:

If I call the simple version of the method, I cannot locate the class.
If I call the version of the method and specify the bootstrap class loader, I can locate the class and everything works as expected.

This is an easy fix but I do not understand the behavior at the moment and need to investigate a bit.

@chanseokoh
Copy link

chanseokoh commented Jan 16, 2019

Ah, thanks again for looking into it.

It is strange that Gradle does not detect those dependencies. They are published correctly in the POM.

Could this be because I added Mockito 2.23.17 from a file like below? (I'm quite new to Gradle.)

 repositories {
   flatDir {
     dirs 'mockito-libs' // to load Mockito 2.23.17 built locally from source
   }
   mavenCentral()
 }

(I put the JAR at <project root>/mockito-libs/mockito-core-2.23.17.jar.)

@raphw
Copy link
Member

raphw commented Jan 16, 2019

Probably, I assume this causes Mockito being added as a jar file direcly rather then it being resolved using a repository that would included this additional meta data.

@chanseokoh
Copy link

chanseokoh commented Jan 16, 2019

If I call the simple version of the method, I cannot locate the class.
If I call the version of the method and specify the bootstrap class loader, I can locate the class and everything works as expected.

Being on a module path, could this be related to module encapsulation? For example, I know Class.getResource() works differently on Java 9+ with the new resource encapsulation (e.g., cannot get resources in a non-root level if not opened by the module).

@raphw
Copy link
Member

raphw commented Jan 16, 2019

This was my first suspicion but the semantics of Class.forName should not have changed. I have a suspicion but I need to try a test case for this.

@raphw
Copy link
Member

raphw commented Jan 16, 2019

I realize now what the issue is. With Mockito being loaded as an automatic module, it is managed by the new BuiltIn class loader. The class loader does not consider packages outside of its own class loader if a package is already assigned to a module that this class loader owns. When injecting the class, the "bytebuddy" package already belongs to the class loader in question and the package in the bootloader is not checked. If I change the check, the class is found but no class injected into the bootstrap loader will be able to load it. The solution must therefore be to move the class into a dedicated package.

@chanseokoh chanseokoh mentioned this issue Jan 18, 2019
@chanseokoh
Copy link

Mockito 2.24.0 (which I believe has the fix #1592) resolved my issue! Thanks @raphw

@smac89
Copy link

smac89 commented Jul 5, 2019

Had to do the following:

testImplementation (group: 'org.mockito', name: 'mockito-core', version: '2.24.0') {
    exclude group: 'net.bytebuddy'
}
testImplementation ("net.bytebuddy:byte-buddy:1.9.13")

@dmitry-timofeev
Copy link
Contributor

Hi,
Bumped into a similar issue when ran our tests with Java 13 (inline mocks could not be created). However, they do work with the property -Dnet.bytebuddy.experimental=true. Is it a known issue — I haven't manage to find one?

@EricBuist
Copy link

Hi,

This doesn't work either. Mockito-core 2.23.4, byte buddy 1.9.16, tried -Dnet.bytebuddy.experimental=true that makes no difference, OpenJDK 11.0.6. The mockito-core version is obtained from Spring Boot parent POM. Tried to use a different version, seems not to work, maybe I need to get rid of the parent POM and declare all the versions of everything manually?

Without Jacoco, it works correctly, all tests passing. If Jacoco is used, I'm getting the error, cannot create any mocks. jacoco-maven-plugin 0.8.5.

@raphw
Copy link
Member

raphw commented Apr 18, 2020

It should work but maybe Jacoco breaks something. What error message are you getting?

@EricBuist
Copy link

EricBuist commented Apr 22, 2020 via email

@TimvdLippe
Copy link
Contributor

Closing this issue as fixed with our recent versions of Mockito (which supports up to JDK 17 at the time of writing).

rtyley added a commit to guardian/atom-maker that referenced this issue Dec 7, 2022
DevX has recommended that teams stop using Java 8 (see
https://docs.google.com/document/d/1ZR-YnaXCT5_gLVmTCeGs0mWd3KPaAozPjQK8uUzHZ9w/edit )
so it's good to get this project capable of running tests under Java 11!

The only blocker is the old version of Mockito, which would throw this error
when running tests under Java 11:

```
java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
```

It looks like Java 11 compatability was added to Mockito sometime around 2019
(see mockito/mockito#1483 and
https://github.com/mockito/mockito/blob/release/2.x/doc/release-notes/official.md)
so just upgrading to the latest version fixes the issue.

There's also a couple of changes to mocking-exceptions in the tests, as the later
version of Mockito is more strict - you can't say `thenThrow(classOf[Exception])`
if the exception is a checked-exception, and method you're mocking doesn't
actually throw that exception! So instead we just say `thenThrow(classOf[RuntimeException])`,
which is something any method can do at anytime, without having to declare it
in its signature.

```
[info] - should succeed with NO_CONTENT *** FAILED ***
[info]   org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.gu.atom.data.PreviewDataStore
[info]
[info] Mockito can only mock visible & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.
[info]
[info] Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
[info]   at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)
[info]   at org.scalatest.mockito.MockitoSugar$.mock(MockitoSugar.scala:155)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData(AtomSuite.scala:22)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData$(AtomSuite.scala:21)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.previewDataStoreMockWithTestData(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore$(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.initialPreviewDataStore(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite$AtomTestConf$.apply$default$1(AtomSuite.scala:73)
[info]   ...
[info]   Cause: java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.defineClass(ClassInjector.java:334)
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:187)
[info]   at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:205)
[info]   at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
[info]   at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4247)
[info]   at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:99)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:89)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:37)
[info]   at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
[info]   ...
```
rtyley added a commit to guardian/atom-maker that referenced this issue Dec 7, 2022
DevX has recommended that teams stop using Java 8 (see
https://docs.google.com/document/d/1ZR-YnaXCT5_gLVmTCeGs0mWd3KPaAozPjQK8uUzHZ9w/edit )
so it's good to get this project capable of running tests under Java 11!

The only blocker is the old version of Mockito, which would throw this error
when running tests under Java 11:

```
java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
```

It looks like Java 11 compatability was added to Mockito sometime around 2019
(see mockito/mockito#1483 and
https://github.com/mockito/mockito/blob/release/2.x/doc/release-notes/official.md)
so just upgrading to the latest version fixes the issue.

There's also a couple of changes to mocking-exceptions in the tests, as the later
version of Mockito is more strict - you can't say `thenThrow(classOf[Exception])`
if the exception is a checked-exception, and method you're mocking doesn't
actually throw that exception! So instead we just say `thenThrow(classOf[RuntimeException])`,
which is something any method can do at anytime, without having to declare it
in its signature.

```
[info] - should succeed with NO_CONTENT *** FAILED ***
[info]   org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.gu.atom.data.PreviewDataStore
[info]
[info] Mockito can only mock visible & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.
[info]
[info] Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
[info]   at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)
[info]   at org.scalatest.mockito.MockitoSugar$.mock(MockitoSugar.scala:155)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData(AtomSuite.scala:22)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData$(AtomSuite.scala:21)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.previewDataStoreMockWithTestData(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore$(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.initialPreviewDataStore(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite$AtomTestConf$.apply$default$1(AtomSuite.scala:73)
[info]   ...
[info]   Cause: java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.defineClass(ClassInjector.java:334)
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:187)
[info]   at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:205)
[info]   at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
[info]   at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4247)
[info]   at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:99)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:89)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:37)
[info]   at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
[info]   ...
```
rtyley added a commit to guardian/atom-maker that referenced this issue Dec 7, 2022
DevX has recommended that teams stop using Java 8 (see
https://docs.google.com/document/d/1ZR-YnaXCT5_gLVmTCeGs0mWd3KPaAozPjQK8uUzHZ9w/edit )
so it's good to get this project capable of running tests under Java 11!

The only blocker is the old version of Mockito, which would throw this error
when running tests under Java 11:

```
java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
```

It looks like Java 11 compatability was added to Mockito sometime around 2019
(see mockito/mockito#1483 and
https://github.com/mockito/mockito/blob/release/2.x/doc/release-notes/official.md)
so just upgrading to the latest version fixes the issue.

There's also a couple of changes to mocking-exceptions in the tests, as the later
version of Mockito is more strict - you can't say `thenThrow(classOf[Exception])`
if the exception is a checked-exception, and method you're mocking doesn't
actually throw that exception! So instead we just say `thenThrow(classOf[RuntimeException])`,
which is something any method can do at anytime, without having to declare it
in its signature.

```
[info] - should succeed with NO_CONTENT *** FAILED ***
[info]   org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.gu.atom.data.PreviewDataStore
[info]
[info] Mockito can only mock visible & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.
[info]
[info] Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
[info]   at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)
[info]   at org.scalatest.mockito.MockitoSugar$.mock(MockitoSugar.scala:155)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData(AtomSuite.scala:22)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData$(AtomSuite.scala:21)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.previewDataStoreMockWithTestData(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore$(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.initialPreviewDataStore(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite$AtomTestConf$.apply$default$1(AtomSuite.scala:73)
[info]   ...
[info]   Cause: java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.defineClass(ClassInjector.java:334)
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:187)
[info]   at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:205)
[info]   at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
[info]   at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4247)
[info]   at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:99)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:89)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:37)
[info]   at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
[info]   ...
```
rtyley added a commit to guardian/atom-maker that referenced this issue Dec 7, 2022
DevX has recommended that teams stop using Java 8 (see
https://docs.google.com/document/d/1ZR-YnaXCT5_gLVmTCeGs0mWd3KPaAozPjQK8uUzHZ9w/edit )
so it's good to get this project capable of running tests under Java 11!

The only blocker is the old version of Mockito, which would throw this error
when running tests under Java 11:

```
java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
```

It looks like Java 11 compatability was added to Mockito sometime around 2019
(see mockito/mockito#1483 and
https://github.com/mockito/mockito/blob/release/2.x/doc/release-notes/official.md)
so just upgrading to the latest version fixes the issue.

There's also a couple of changes to mocking-exceptions in the tests, as the later
version of Mockito is more strict - you can't say `thenThrow(classOf[Exception])`
if the exception is a checked-exception, and method you're mocking doesn't
actually throw that exception! So instead we just say `thenThrow(classOf[RuntimeException])`,
which is something any method can do at anytime, without having to declare it
in its signature.

```
[info] - should succeed with NO_CONTENT *** FAILED ***
[info]   org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.gu.atom.data.PreviewDataStore
[info]
[info] Mockito can only mock visible & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.
[info]
[info] Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
[info]   at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)
[info]   at org.scalatest.mockito.MockitoSugar$.mock(MockitoSugar.scala:155)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData(AtomSuite.scala:22)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData$(AtomSuite.scala:21)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.previewDataStoreMockWithTestData(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore$(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.initialPreviewDataStore(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite$AtomTestConf$.apply$default$1(AtomSuite.scala:73)
[info]   ...
[info]   Cause: java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.defineClass(ClassInjector.java:334)
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:187)
[info]   at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:205)
[info]   at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
[info]   at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4247)
[info]   at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:99)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:89)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:37)
[info]   at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
[info]   ...
```
rtyley added a commit to guardian/atom-maker that referenced this issue Dec 7, 2022
DevX has recommended that teams stop using Java 8 (see
https://docs.google.com/document/d/1ZR-YnaXCT5_gLVmTCeGs0mWd3KPaAozPjQK8uUzHZ9w/edit )
so it's good to get this project capable of running tests under Java 11!

The only blocker is the old version of Mockito, which would throw this error
when running tests under Java 11:

```
java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
```

It looks like Java 11 compatability was added to Mockito sometime around 2019
(see mockito/mockito#1483 and
https://github.com/mockito/mockito/blob/release/2.x/doc/release-notes/official.md)
so just upgrading to the latest version fixes the issue.

There's also a couple of changes to mocking-exceptions in the tests, as the later
version of Mockito is more strict - you can't say `thenThrow(classOf[Exception])`
if the exception is a checked-exception, and method you're mocking doesn't
actually throw that exception! So instead we just say `thenThrow(classOf[RuntimeException])`,
which is something any method can do at anytime, without having to declare it
in its signature.

```
[info] - should succeed with NO_CONTENT *** FAILED ***
[info]   org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.gu.atom.data.PreviewDataStore
[info]
[info] Mockito can only mock visible & non-final classes.
[info] If you're not sure why you're getting this error, please report to the mailing list.
[info]
[info] Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at org.scalatest.mockito.MockitoSugar.mock(MockitoSugar.scala:73)
[info]   at org.scalatest.mockito.MockitoSugar.mock$(MockitoSugar.scala:72)
[info]   at org.scalatest.mockito.MockitoSugar$.mock(MockitoSugar.scala:155)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData(AtomSuite.scala:22)
[info]   at com.gu.atom.play.test.AtomSuite.previewDataStoreMockWithTestData$(AtomSuite.scala:21)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.previewDataStoreMockWithTestData(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomSuite.initialPreviewDataStore$(AtomSuite.scala:53)
[info]   at com.gu.atom.play.test.AtomAPIActionsSpec.initialPreviewDataStore(AtomAPIActionsSpec.scala:15)
[info]   at com.gu.atom.play.test.AtomSuite$AtomTestConf$.apply$default$1(AtomSuite.scala:73)
[info]   ...
[info]   Cause: java.lang.UnsupportedOperationException: Cannot define class using reflection: Could not find sun.misc.Unsafe
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Initializable$Unavailable.defineClass(ClassInjector.java:334)
[info]   at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:187)
[info]   at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:205)
[info]   at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
[info]   at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4247)
[info]   at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:99)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:89)
[info]   at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:37)
[info]   at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
[info]   ...
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests