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

Mockito fails with "cannot mock" exceptions in OpenJ9 11 and 17 #17454

Closed
yogregg opened this issue May 24, 2023 · 38 comments · Fixed by #17821
Closed

Mockito fails with "cannot mock" exceptions in OpenJ9 11 and 17 #17454

yogregg opened this issue May 24, 2023 · 38 comments · Fixed by #17821

Comments

@yogregg
Copy link

yogregg commented May 24, 2023

Java -version output

openjdk version "11.0.17" 2022-10-18
IBM Semeru Runtime Open Edition 11.0.17.0 (build 11.0.17+8)
Eclipse OpenJ9 VM 11.0.17.0 (build openj9-0.35.0, JRE 11 Windows 10 amd64-64-Bit Compressed References 20221031_487 (JIT enabled, AOT enabled)
OpenJ9 - e04a7f6
OMR - 85a21674f
JCL - a94c231303 based on jdk-11.0.17+8)

Summary of problem

The mockito Java mocking library frequently throws "cannot mock" exceptions when using OpenJ9 that I have not seen on other Java implementations. This problem happens with at least OpenJ9 11 and 17 and at least on both Windows and Linux. The Java version output above it just one of many failing versions I've tried. Here's an example exception:

Mockito cannot mock this class: class org.mockito.internal.creation.bytebuddy.AbstractByteBuddyMockMakerTest$SomeClass.

If you're not sure why you're getting this error, please open an issue on GitHub.


Java               : 11
JVM vendor name    : Eclipse OpenJ9
JVM vendor version : openj9-0.35.0
JVM name           : Eclipse OpenJ9 VM
JVM version        : 11.0.17+8
JVM info           : JRE 11 Windows 10 amd64-64-Bit Compressed References 20221031_487 (JIT enabled, AOT enabled)
OpenJ9   - e04a7f6c1
OMR      - 85a21674f
JCL      - a94c231303 based on jdk-11.0.17+8
OS name            : Windows 10
OS version         : 10.0


You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class java.lang.Object, class org.mockito.internal.creation.bytebuddy.AbstractByteBuddyMockMakerTest$SomeClass]
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.prettifyFailure(InlineDelegateByteBuddyMockMaker.java:441)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:404)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:355)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
	at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
	at app//org.mockito.internal.creation.AbstractMockMakerTest.should_reset_mock_and_set_new_handler(AbstractMockMakerTest.java:47)
	at java.base@11.0.17/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base@11.0.17/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base@11.0.17/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@11.0.17/java.lang.reflect.Method.invoke(Method.java:566)
	at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at app//org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at app//org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at app//org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at app//org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at app//org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at app//org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at app//org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:108)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:57)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:39)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
	at jdk.internal.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
	at java.base@11.0.17/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@11.0.17/java.lang.reflect.Method.invoke(Method.java:566)
	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.$Proxy4.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	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:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.mockito.exceptions.base.MockitoException: Could not modify all classes [class java.lang.Object, class org.mockito.internal.creation.bytebuddy.AbstractByteBuddyMockMakerTest$SomeClass]
	at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:298)
	at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:218)
	at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.lambda$mockClass$0(TypeCachingBytecodeGenerator.java:47)
	at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
	at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
	at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
	at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
	at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:40)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:396)
	... 46 more
Caused by: java.lang.instrument.UnmodifiableClassException
	at java.instrument@11.0.17/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
	at java.instrument@11.0.17/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
	at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:281)
	... 54 more

This is easy to reproduce from publicly available sources, because the mockito library's own unit tests have hundreds of failures of this sort when the tests are run with OpenJ9. You just have to make a minor modification to mockito's top-level build.gradle, adding lines like this (referring to your own Java location):

    tasks.withType(Test) {
        executable = new File("c:/apps/jdk-11.0.17+8-semeru", "bin/java.exe")
    }

You can see more details on this including a zip file of mockito's test result reports when it is run this way in mockito/mockito#2995

I'm reporting this here as well because this problem sounds possibly related to #3410 That issue refers to a change made in gacholio@71bed50 that apparently resolved the problem for some, but I'm still seeing similar failures. The issue there was that java.lang.Object was not a modifiable class in OpenJ9 (classIsModifiable method in https://github.com/eclipse-openj9/openj9/blob/openj9-0.36.0/runtime/util/hshelp.c), which is consistent with the error stack. That version is the modified version that apparently helped some people, but it still mentions in its comments that Object can't be modified in "extended HCR mode" (I don't know what that is).

This is getting in the way of testing our product on OpenJ9, which makes it impossible to say to our customers with any confidence that it is safe for them to use OpenJ9.

What is the source of this problem? Am I right to suspect that it is related to an ongoing but narrower inability to modify Object? If so, what is "extended HCR mode" and is there some way to control whether we are using that or not, or is there some other fix or workaround for this?

@tajila
Copy link
Contributor

tajila commented May 29, 2023

@gacholio can you please take a look at this

@gacholio
Copy link
Contributor

The only classes that should be unmodifiable are ones annotated with @J9UnmodifiableClass of which there are exactly three: JITHelpers, VarHandleInternal and J9VMInternals.

@gacholio
Copy link
Contributor

Can you please try a more modern VM? The stated one is over a year old. The change to use the annotation claims to be 4 years old, so I'm not sure this will actually fix anything, but it's worth a try.

@yogregg
Copy link
Author

yogregg commented May 31, 2023

@gacholio I tried running the mockito test suite just now using the latest IBM Semeru Java 17 runtime available at . This one:

openjdk version "17.0.6" 2023-01-17
IBM Semeru Runtime Open Edition 17.0.6.0 (build 17.0.6+10)
Eclipse OpenJ9 VM 17.0.6.0 (build openj9-0.36.0, JRE 17 Windows 10 amd64-64-Bit Compressed References 20230117_367 (JIT enabled, AOT enabled)
OpenJ9   - e68fb241f
OMR      - f491bbf6f
JCL      - 927b34f84c8 based on jdk-17.0.6+10)

The mockito tests still fail in the same way. For example, here's one failure message.

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class org.mockito.internal.creation.bytebuddy.AbstractByteBuddyMockMakerTest$SomeClass.

If you're not sure why you're getting this error, please open an issue on GitHub.


Java               : 17
JVM vendor name    : Eclipse OpenJ9
JVM vendor version : openj9-0.36.0
JVM name           : Eclipse OpenJ9 VM
JVM version        : 17.0.6+10
JVM info           : JRE 17 Windows 10 amd64-64-Bit Compressed References 20230117_367 (JIT enabled, AOT enabled)
OpenJ9   - e68fb241f
OMR      - f491bbf6f
JCL      - 927b34f84c8 based on jdk-17.0.6+10
OS name            : Windows 10
OS version         : 10.0


You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class org.mockito.internal.creation.bytebuddy.AbstractByteBuddyMockMakerTest$SomeClass, class java.lang.Object]
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.prettifyFailure(InlineDelegateByteBuddyMockMaker.java:441)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:404)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:355)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
	at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
	at app//org.mockito.internal.creation.AbstractMockMakerTest.should_reset_mock_and_set_new_handler(AbstractMockMakerTest.java:47)
	at java.base@17.0.6/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base@17.0.6/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base@17.0.6/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@17.0.6/java.lang.reflect.Method.invoke(Method.java:568)
	at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at app//org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at app//org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at app//org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at app//org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at app//org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at app//org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at app//org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:108)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:57)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:39)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
	at jdk.internal.reflect.GeneratedMethodAccessor66.invoke(Unknown Source)
	at java.base@17.0.6/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base@17.0.6/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.proxy2/jdk.proxy2.$Proxy5.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	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:113)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.mockito.exceptions.base.MockitoException: Could not modify all classes [class org.mockito.internal.creation.bytebuddy.AbstractByteBuddyMockMakerTest$SomeClass, class java.lang.Object]
	at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:298)
	at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:218)
	at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.lambda$mockClass$0(TypeCachingBytecodeGenerator.java:47)
	at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
	at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
	at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
	at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
	at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:40)
	at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:396)
	... 46 more
Caused by: java.lang.instrument.UnmodifiableClassException
	at java.instrument@17.0.6/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:169)
	at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:281)
	... 54 more

Unfortunately the UnmodifiableClassException doesn't say which class was unmodifiable, and it is coming from a method (retransformClasses) that takes a list of classes to transform. But I strongly suspect it is java.lang.Object.

By the way, if the only unmodifiable classes really are just the three that you mention, then there's an error in the comment on the classIsModifiable method in openj9/runtime/util/hshelp.c, which says:

/*
 * Can't replace:
 * - primitive or array classes
 * - J9VMInternals
 * - sun.misc.Unsafe Anonymous classes
 * - Object (in extended HCR mode)
 */
jboolean
classIsModifiable(J9JavaVM * vm, J9Class * clazz)
{
	return !J9ROMCLASS_IS_UNMODIFIABLE(clazz->romClass);
}

@gacholio
Copy link
Contributor

gacholio commented Jun 1, 2023

The comment is outdated - you should be able to transform Object. I will make sure this is true.

@tajila
Copy link
Contributor

tajila commented Jun 2, 2023

@yogregg I've been able to reproduce this issue with ./gradlew build is there a way to run a single test?

@gacholio
Copy link
Contributor

gacholio commented Jun 3, 2023

If you can reproduce this, the next step is to modify a VM to print which class causes the problem. I'll produce a patch and build.

@yogregg
Copy link
Author

yogregg commented Jun 3, 2023

@tajila regarding your question about running a single tests, I've always been a maven user, and never used gradle until my attempts to illustrate this issue using mockito's own tests. But https://stackoverflow.com/questions/22505533/how-to-run-only-one-unit-test-class-using-gradle and other articles indicate that there's a --tests argument you can use to do that.

I've also learned that gradle does a lot of caching and dependency analysis on what it runs, and that if you rerun "gradlew build" or "gradlew test" when no relevant code has changed, it won't actually rerun the tests, even though it the test reports directory will still contain results. I've found that "gradlew test --rerun-tasks" forces the tests to rerun, which I found useful in repeatedly running them to try to debug, even when I hadn't changed code. I don't know if that's how an experienced gradle user would do it, but it seems to work for me.

@yogregg
Copy link
Author

yogregg commented Jun 13, 2023

@gacholio has anyone tried reproducing this with the instrumented internal build yet to verify the unmodifiable class, or made other progress on diagnosing the issue?

@gacholio
Copy link
Contributor

Apologies - Tobi has been away and I've been off sick the last couple of days. Hopefully we'll have an update by end of week.

@tajila
Copy link
Contributor

tajila commented Jun 15, 2023

@gacholio I tried it again, none of the unmodifiable: %.*s were printed

@gacholio
Copy link
Contributor

@yogregg Turns out we have not reproduced the reported failure locally. The runs we've done report lots of errors (and at least one VM crash which will be addressed seperately), but none of the failures are the unmodifiable class issue.

@yogregg
Copy link
Author

yogregg commented Jun 21, 2023

@gacholio When I was trying to reproduce this originally I was having trouble with getting gradle to actually rerun tests consistently. “gradlew test” didn’t actually rerun even though it appeared to. "gradlew test --rerun-tasks" seemed to do the trick for me. Is it possible that’s behind it appearing to be reproducible at first but not now?

Also so that I can more carefully compare your test results and mine would it be possible for you to attach the contents of mockito's top level build/reports/tests/test directory? And are you able to reproduce with the publicly available recent Semeru runtime I used?

I am on vacation now and can’t look more carefully at the moment at some way to run just one specific test that I’m seeing this problem on.

@tajila
Copy link
Contributor

tajila commented Jun 26, 2023

I ran on windows with

openjdk version "17.0.7" 2023-04-18
IBM Semeru Runtime Open Edition 17.0.7.0 (build 17.0.7+7)
Eclipse OpenJ9 VM 17.0.7.0 (build openj9-0.38.0, JRE 17 Windows 10 amd64-64-Bit Compressed References 20230418_439 (JIT enabled, AOT enabled)
OpenJ9   - d57d05932
OMR      - 855813495
JCL      - 9d7a231edbc based on jdk-17.0.7+7)

and the result was

org.concurrentmockito.ThreadsRunAllTestsHalfManualTest > shouldRunInMultipleThreads FAILED
    java.lang.AssertionError: Run in multiple thread failed for tests expected:<[]> but was:<[class org.mockitousage.verification.NoMoreInteractionsVerificationTest, class org.mockitousage.misuse.InvalidUsageTest, class org.mockitousage.stubbing.StubbingWithThrowablesTest, class org.mockitousage.examples.use.ExampleTest, class org.concurren
tmockito.VerificationInOrderFromMultipleThreadsTest, class org.mockito.internal.stubbing.defaultanswers.ReturnsGenericDeepStubsTest, class org.mockitousage.verification.VerificationOnMultipleMocksUsingMatchersTest, class org.mockitousage.basicapi.ReplacingObjectMethodsTest, class org.mockitousage.basicapi.UsingVarargsTest, class org.mockito
usage.puzzlers.OverloadingPuzzleTest]>
        at app//org.junit.Assert.fail(Assert.java:89)
        at app//org.junit.Assert.failNotEquals(Assert.java:835)
        at app//org.junit.Assert.assertEquals(Assert.java:120)
        at app//org.concurrentmockito.ThreadsRunAllTestsHalfManualTest.shouldRunInMultipleThreads(ThreadsRunAllTestsHalfManualTest.java:159)

org.concurrentmockito.VerificationInOrderFromMultipleThreadsTest > shouldVerifyInOrderWhenMultipleThreadsInteractWithMock FAILED
    java.lang.NoClassDefFoundError: org.concurrentmockito.VerificationInOrderFromMultipleThreadsTest$Foo$MockitoMock$QtZq1MFp (initialization failure)
        at java.base@17.0.7/java.lang.J9VMInternals.initializationAlreadyFailed(J9VMInternals.java:156)
        at java.base@17.0.7/jdk.internal.misc.Unsafe.allocateInstance(Native Method)
        at jdk.unsupported@17.0.7/sun.misc.Unsafe.allocateInstance(Unsafe.java:864)
        at app//org.objenesis.instantiator.sun.UnsafeFactoryInstantiator.newInstance(UnsafeFactoryInstantiator.java:47)
        at app//org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
        at app//org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:22)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:376)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
        at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
        at app//org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)
        at app//org.mockito.internal.MockitoCore.mock(MockitoCore.java:88)
        at app//org.mockito.Mockito.mock(Mockito.java:2101)
        at app//org.mockito.Mockito.mock(Mockito.java:2016)
        at app//org.concurrentmockito.VerificationInOrderFromMultipleThreadsTest.shouldVerifyInOrderWhenMultipleThreadsInteractWithMock(VerificationInOrderFromMultipleThreadsTest.java:18)

        Caused by:
        java.lang.NullPointerException
            at java.base@17.0.7/java.util.ArrayList.add(ArrayList.java:453)
            at java.base@17.0.7/java.util.ArrayList.add(ArrayList.java:467)
            at java.base@17.0.7/java.lang.invoke.MethodTypeHelper.parseIntoClass(MethodTypeHelper.java:237)
            at java.base@17.0.7/java.lang.invoke.MethodHandleResolver.fromFieldDescriptorString(MethodHandleResolver.java:306)
            at java.base@17.0.7/java.lang.invoke.MethodHandleResolver.resolveConstantDynamic(MethodHandleResolver.java:102)
            at app//org.concurrentmockito.VerificationInOrderFromMultipleThreadsTest$Foo$MockitoMock$QtZq1MFp.<clinit>(Unknown Source)
            at java.base@17.0.7/jdk.internal.misc.Unsafe.allocateInstance(Native Method)
            at java.base@17.0.7/java.lang.invoke.DirectMethodHandle.allocateInstance(DirectMethodHandle.java:520)
            at java.base@17.0.7/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
            at org.mockito.internal.util.reflection.InstrumentationMemberAccessor$Dispatcher$ByteBuddy$w6Y4Muoe.invokeWithArguments(Unknown Source)
            at app//org.mockito.internal.util.reflection.InstrumentationMemberAccessor.lambda$newInstance$0(InstrumentationMemberAccessor.java:199)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.lambda$newInstance$4(InlineDelegateByteBuddyMockMaker.java:636)
            at app//org.mockito.internal.util.reflection.InstrumentationMemberAccessor.newInstance(InstrumentationMemberAccessor.java:188)
            at app//org.mockito.internal.util.reflection.ModuleMemberAccessor.newInstance(ModuleMemberAccessor.java:49)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.newInstance(InlineDelegateByteBuddyMockMaker.java:631)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:369)
            ... 7 more

org.mockito.MockitoClearTest > can_clear_mock FAILED
    java.lang.NoClassDefFoundError: org.mockito.MockitoClearTest$Base$MockitoMock$0Shgha5m (initialization failure)
        at java.base@17.0.7/java.lang.J9VMInternals.initializationAlreadyFailed(J9VMInternals.java:156)
        at java.base@17.0.7/jdk.internal.misc.Unsafe.allocateInstance(Native Method)
        at jdk.unsupported@17.0.7/sun.misc.Unsafe.allocateInstance(Unsafe.java:864)
        at app//org.objenesis.instantiator.sun.UnsafeFactoryInstantiator.newInstance(UnsafeFactoryInstantiator.java:47)
        at app//org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
        at app//org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:22)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:376)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
        at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
        at app//org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)
        at app//org.mockito.internal.MockitoCore.mock(MockitoCore.java:88)
        at app//org.mockito.Mockito.mock(Mockito.java:2101)
        at app//org.mockito.Mockito.mock(Mockito.java:2016)
        at app//org.mockito.MockitoClearTest.can_clear_mock(MockitoClearTest.java:15)

        Caused by:
        java.lang.NullPointerException
            at java.base@17.0.7/java.util.ArrayList.add(ArrayList.java:453)
            at java.base@17.0.7/java.util.ArrayList.add(ArrayList.java:467)
            at java.base@17.0.7/java.lang.invoke.MethodTypeHelper.parseIntoClass(MethodTypeHelper.java:237)
            at java.base@17.0.7/java.lang.invoke.MethodHandleResolver.fromFieldDescriptorString(MethodHandleResolver.java:306)
            at java.base@17.0.7/java.lang.invoke.MethodHandleResolver.resolveConstantDynamic(MethodHandleResolver.java:102)
            at app//org.mockito.MockitoClearTest$Base$MockitoMock$0Shgha5m.<clinit>(Unknown Source)
            at java.base@17.0.7/jdk.internal.misc.Unsafe.allocateInstance(Native Method)
            at java.base@17.0.7/java.lang.invoke.DirectMethodHandle.allocateInstance(DirectMethodHandle.java:520)
            at java.base@17.0.7/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
            at org.mockito.internal.util.reflection.InstrumentationMemberAccessor$Dispatcher$ByteBuddy$w6Y4Muoe.invokeWithArguments(Unknown Source)
            at app//org.mockito.internal.util.reflection.InstrumentationMemberAccessor.lambda$newInstance$0(InstrumentationMemberAccessor.java:199)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.lambda$newInstance$4(InlineDelegateByteBuddyMockMaker.java:636)
            at app//org.mockito.internal.util.reflection.InstrumentationMemberAccessor.newInstance(InstrumentationMemberAccessor.java:188)
            at app//org.mockito.internal.util.reflection.ModuleMemberAccessor.newInstance(ModuleMemberAccessor.java:49)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.newInstance(InlineDelegateByteBuddyMockMaker.java:631)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:369)
            ... 7 more

a few others

@tajila
Copy link
Contributor

tajila commented Jun 26, 2023

org.mockito.internal.creation.InterfaceOverrideTest > inherit_public_method_from_interface FAILED
    java.lang.NoClassDefFoundError: org.mockito.internal.creation.InterfaceOverrideTest$CloneableInterface$MockitoMock$e0kkSYY8 (initialization failure)
        at java.base@17.0.7/java.lang.J9VMInternals.initializationAlreadyFailed(J9VMInternals.java:156)
        at java.base@17.0.7/jdk.internal.misc.Unsafe.allocateInstance(Native Method)
        at jdk.unsupported@17.0.7/sun.misc.Unsafe.allocateInstance(Unsafe.java:864)
        at app//org.objenesis.instantiator.sun.UnsafeFactoryInstantiator.newInstance(UnsafeFactoryInstantiator.java:47)
        at app//org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
        at app//org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:22)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:376)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
        at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
        at app//org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)
        at app//org.mockito.internal.MockitoCore.mock(MockitoCore.java:88)
        at app//org.mockito.Mockito.mock(Mockito.java:2101)
        at app//org.mockito.Mockito.mock(Mockito.java:2016)
        at app//org.mockito.internal.creation.InterfaceOverrideTest.inherit_public_method_from_interface(InterfaceOverrideTest.java:21)

        Caused by:
        java.lang.NullPointerException
            at java.base@17.0.7/java.util.ArrayList.add(ArrayList.java:453)
            at java.base@17.0.7/java.util.ArrayList.add(ArrayList.java:467)
            at java.base@17.0.7/java.lang.invoke.MethodTypeHelper.parseIntoClass(MethodTypeHelper.java:237)
            at java.base@17.0.7/java.lang.invoke.MethodHandleResolver.fromFieldDescriptorString(MethodHandleResolver.java:306)
            at java.base@17.0.7/java.lang.invoke.MethodHandleResolver.resolveConstantDynamic(MethodHandleResolver.java:102)
            at app//org.mockito.internal.creation.InterfaceOverrideTest$CloneableInterface$MockitoMock$e0kkSYY8.<clinit>(Unknown Source)
            at java.base@17.0.7/jdk.internal.misc.Unsafe.allocateInstance(Native Method)
            at java.base@17.0.7/java.lang.invoke.DirectMethodHandle.allocateInstance(DirectMethodHandle.java:520)
            at java.base@17.0.7/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
            at org.mockito.internal.util.reflection.InstrumentationMemberAccessor$Dispatcher$ByteBuddy$w6Y4Muoe.invokeWithArguments(Unknown Source)
            at app//org.mockito.internal.util.reflection.InstrumentationMemberAccessor.lambda$newInstance$0(InstrumentationMemberAccessor.java:199)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.lambda$newInstance$4(InlineDelegateByteBuddyMockMaker.java:636)
            at app//org.mockito.internal.util.reflection.InstrumentationMemberAccessor.newInstance(InstrumentationMemberAccessor.java:188)
            at app//org.mockito.internal.util.reflection.ModuleMemberAccessor.newInstance(ModuleMemberAccessor.java:49)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.newInstance(InlineDelegateByteBuddyMockMaker.java:631)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:369)
            ... 7 more

@tajila
Copy link
Contributor

tajila commented Jun 26, 2023

The test above was run with ./gradlew test --rerun-tasks so it looks like we still havent reproduced the retransformation issue

@yogregg
Copy link
Author

yogregg commented Jun 26, 2023

@tajila I tried running the mockito tests today with the same Windows Semeru 17.0.7+7 version that you used, and I am now seeing results more like yours: some JVM crashes, plus many NullPointerExceptions in ArrayList. On quite a few tries, the test runs never finished at all (maybe related to the JVM crashes), and even when I did get lucky and have it finish, I didn't get any test results populated into the build/reports/tests/test directory, so I could only see the results from the last few tests that I could still see in my shell window. So I don't know whether anything is still failing with the UnmodifiableClassException. I tried again on the same sources (up to date mockito head as of today) with an Oracle Java 17 and only got two test failures, both very different, and I suspect that's just a real failure in the current unreleased mockito sources.

So, while the behavior seems to have changed in newer versions, mockito is still very broken on Semeru Java, and I hope that you can get to the bottom of it. I gather that the new failure symptoms that you and I are both now seeing are something that you can reproduce.

@gacholio
Copy link
Contributor

It might be worth taking the JIT out of the equation with:

set OPENJ9_JAVA_OPTIONS=-Xint

(or the equivalent on non-windows) before running.

@gacholio
Copy link
Contributor

Or not - I still see loads of the same failures running without the JIT.

@tajila
Copy link
Contributor

tajila commented Jul 6, 2023

I was able to reproduce the original failures

    Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class org.mockito.AnnotationsAreCopiedFromMockedTypeTest$OnMethod, class java.lang.Object]
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.prettifyFailure(InlineDelegateByteBuddyMockMaker.java:441)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:404)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:355)
        at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
        at app//org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
        at app//org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)
        at app//org.mockito.internal.MockitoCore.mock(MockitoCore.java:88)
        at app//org.mockito.Mockito.mock(Mockito.java:2102)
        at app//org.mockito.Mockito.mock(Mockito.java:2017)
        at app//org.mockito.AnnotationsAreCopiedFromMockedTypeTest.mock_should_have_annotations_copied_from_mocked_type_on_method_parameters(AnnotationsAreCopiedFromMockedTypeTest.java:56)

        Caused by:
        org.mockito.exceptions.base.MockitoException: Could not modify all classes [class org.mockito.AnnotationsAreCopiedFromMockedTypeTest$OnMethod, class java.lang.Object]
            at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:307)
            at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:224)
            at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.lambda$mockClass$0(TypeCachingBytecodeGenerator.java:47)
            at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
            at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
            at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
            at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
            at app//org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:40)
            at app//org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:396)
            ... 8 more

            Caused by:
            java.lang.instrument.UnmodifiableClassException
                at java.instrument@17.0.8-internal/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
                at java.instrument@17.0.8-internal/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:169)
                at app//org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:290)
                ... 16 more

In every case it was *** retrans - unmodifiable: java/lang/Object *** that cause the issues

@tajila
Copy link
Contributor

tajila commented Jul 6, 2023

I've tracked the code to https://github.com/mockito/mockito/blob/222c14c97bc2ec59ec5e486ddaa6438edded0e5c/src/main/java/org/mockito/internal/creation/bytebuddy/InlineBytecodeGenerator.java#L266 which adds the super class to the list of classes that are retransformed

@tajila
Copy link
Contributor

tajila commented Jul 6, 2023

Looking at j/l/Object

> !j9romclass 0x00007F7F6CFC0878
J9ROMClass at 0x7f7f6cfc0878 {
  Fields for J9ROMClass:
	0x0: U32 romSize = 0x00000498 (1176)
	0x4: U32 singleScalarStaticCount = 0x00000000 (0)
	0x8: J9SRP(J9UTF8) className = !j9utf8 0x00007F7F6C936498
	0xc: J9SRP(J9UTF8) superclassName = !j9utf8 0x0000000000000000
	0x10: U32 modifiers = 0x00000021 (33)
	0x14: U32 extraModifiers = 0x08E00000 (148897792) //Unmodifiable is set

@tajila
Copy link
Contributor

tajila commented Jul 6, 2023

@gacholio
Copy link
Contributor

gacholio commented Jul 7, 2023

The code you quote is for base type and array ROM classes - Object is created from a class file.

@gacholio
Copy link
Contributor

gacholio commented Jul 7, 2023

The only place that sets the bit for created classes is:

if ( classFileOracle->isClassUnmodifiable() ) {
modifiers |= J9AccClassIsUnmodifiable;
}

which is set in two possible places:
if (containsKnownAnnotation(foundAnnotations, UNMODIFIABLE_ANNOTATION)) {
_isClassUnmodifiable = true;
}

_isClassUnmodifiable(context->isClassUnmodifiable()),

The constructor one (which I had previously missed) comes from:
bool isClassUnmodifiable() const {
bool unmodifiable = false;
if (NULL != _javaVM) {
if ((J2SE_VERSION(_javaVM) >= J2SE_V11)
&& (isClassAnon() || isClassHidden())
) {
unmodifiable = true;
} else if (NULL == J9VMJAVALANGOBJECT_OR_NULL(_javaVM)) {
/* Object is currently only allowed to be redefined in fast HCR */
if (areExtensionsEnabled(_javaVM)) {
unmodifiable = true;
}
}
}
return unmodifiable;
}

Object is unmodifiable if extensions are being used, which I expect is not the case here. I believe the NULL check is basically checking that this is the first class being loaded, though it's a pretty hacky way of doing so.

@gacholio
Copy link
Contributor

gacholio commented Jul 7, 2023

I'll do some startup debug and see what's happening.

@gacholio
Copy link
Contributor

gacholio commented Jul 7, 2023

The code appears to be doing what it intends. One side-effect: running -Xint is considered to have extensions enabled, so Object is unmodifiable interpreter-only, but should be modifiable if the JIT is enabled (and no debug capabilities have been acquired).

@gacholio
Copy link
Contributor

gacholio commented Jul 7, 2023

Without -Xint

Breakpoint 2, ROMClassCreationContext::isClassUnmodifiable (this=0x7f4cd471f4a0)
    at ROMClassCreationContext.hpp:244
244			bool unmodifiable = false;
(gdb) next
245			if (NULL != _javaVM) {
(gdb) 
246				if ((J2SE_VERSION(_javaVM) >= J2SE_V11) 
(gdb) 
247					&& (isClassAnon() || isClassHidden())
(gdb) 
246				if ((J2SE_VERSION(_javaVM) >= J2SE_V11) 
(gdb) 
250				} else if (NULL == J9VMJAVALANGOBJECT_OR_NULL(_javaVM)) {
(gdb) 
252					if (areExtensionsEnabled(_javaVM)) {
(gdb) 
257			return unmodifiable;
(gdb) p unmodifiable
$1 = false

with -Xint

Breakpoint 1, ROMClassCreationContext::isClassUnmodifiable (this=0x7f1334e834a0)
    at ROMClassCreationContext.hpp:244
244			bool unmodifiable = false;
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.212.el6_10.3.x86_64
(gdb) next
245			if (NULL != _javaVM) {
(gdb) 
246				if ((J2SE_VERSION(_javaVM) >= J2SE_V11) 
(gdb) 
247					&& (isClassAnon() || isClassHidden())
(gdb) 
246				if ((J2SE_VERSION(_javaVM) >= J2SE_V11) 
(gdb) 
250				} else if (NULL == J9VMJAVALANGOBJECT_OR_NULL(_javaVM)) {
(gdb) 
252					if (areExtensionsEnabled(_javaVM)) {
(gdb) 
253						unmodifiable = true;
(gdb) 
257			return unmodifiable;

@gacholio
Copy link
Contributor

gacholio commented Jul 7, 2023

Extensions enabled if -Xfuture is not specified and we are running either in -Xint mode or JIT in FSD mode.

UDATA
areExtensionsEnabled(J9JavaVM * vm)
{
/* If -Xfuture is specified, adhere strictly to the specification */
if (vm->runtimeFlags & J9_RUNTIME_XFUTURE) {
return FALSE;
}
#ifdef J9VM_INTERP_NATIVE_SUPPORT
#ifdef J9VM_JIT_FULL_SPEED_DEBUG
/* Enable RedefineClass and RetransformClass extensions only if we are in full speed debug.
* Currently this is always true since acquiring the redefine capability forces us into FSD.
*/
if (vm->jitConfig) {
/* JIT is available and initialized for this platform */
if (J9_FSD_ENABLED(vm)) {
return TRUE;
} else {
/* but FSD is not enabled */
return FALSE;
}
} else {
/* JIT is not available, since we run in interpreted mode, no JIT fixups are necessary
* and we can allow extensions */
return TRUE;
}
#else
/* We have JIT but no FSD, do not allow extensions */
if (vm->jitConfig) {
return FALSE;
}
#endif /* J9VM_JIT_FULL_SPEED_DEBUG */
#else
/* No JIT, extensions are always allowed */
#endif /* J9VM_INTERP_NATIVE_SUPPORT */
return TRUE;
}

@gacholio
Copy link
Contributor

It would be better to always mark Object as modifiable, but reject extended changes at HCR time (the extensions enabled but not used case). I'm not immediately sure how difficult this would be in the current framework).

@gacholio
Copy link
Contributor

@tajila You've looked into cores - why are we in extended mode (if we are)?

@tajila
Copy link
Contributor

tajila commented Jul 17, 2023

We are not in extended HCR mode

0xc8: U32 runtimeFlags = 0x0020008E

@gacholio
Copy link
Contributor

#define J9_RUNTIME_JIT_ACTIVE 0x20

is not set, which implies -Xint (though the flag is never read, only set by the JIT). Is there a jitConfig in the VM?

@gacholio
Copy link
Contributor

There is also

#define J9_EXTENDED_RUNTIME_ENABLE_HCR 0x400

@tajila
Copy link
Contributor

tajila commented Jul 18, 2023

That core was running with -Xint

@gacholio
Copy link
Contributor

gacholio commented Jul 18, 2023

I'll prototype the change to disallow extended changes to Object while leaving it generally modifiable.

@gacholio
Copy link
Contributor

https://github.com/gacholio/openj9/tree/objectmod

Passes internal testing, but it's worth noting that we do not test the Object modification case locally at all.

gacholio added a commit to gacholio/openj9 that referenced this issue Jul 24, 2023
Currently, Object is marked unmodifiable if extended HCR is enabled.
This change allows Object to be modified, but disallows use of the
extensions on Object.

Fixes: eclipse-openj9#17454

Signed-off-by: Graham Chapman <graham_chapman@ca.ibm.com>
yathamravali pushed a commit to ibmruntimes/semeru-openj9 that referenced this issue Sep 6, 2023
Currently, Object is marked unmodifiable if extended HCR is enabled.
This change allows Object to be modified, but disallows use of the
extensions on Object.

Fixes: eclipse-openj9#17454

Signed-off-by: Graham Chapman <graham_chapman@ca.ibm.com>
yathamravali pushed a commit to ibmruntimes/semeru-openj9 that referenced this issue Sep 6, 2023
Currently, Object is marked unmodifiable if extended HCR is enabled.
This change allows Object to be modified, but disallows use of the
extensions on Object.

Fixes: eclipse-openj9#17454

Signed-off-by: Graham Chapman <graham_chapman@ca.ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants