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

SystemEnvironmentTestListener - Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: #3035

Closed
Marek00Malik opened this issue Jun 5, 2022 · 18 comments

Comments

@Marek00Malik
Copy link

Which version of Kotest are you using
KoTest - 5.3

Kotlin - 1.6.20

I'm getting the following error when trying to run this code line in a WordSpec test.

class PublisherServiceTest : WordSpec() {

    private val pubSubService = install(TestContainerExtension(pubSubContainer)) {
        addExposedPort(8085)
    }
    private val address: String = "${pubSubService.host}:${pubSubService.firstMappedPort}"

    override fun listeners() = listOf(SystemEnvironmentTestListener("PUBSUB_TARGET", address)) //<<< FAILING HERE
    init {
        ...
    }
}

Error Message:
Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @309e345f

This is directly thrown when in SystemEnviromentExtensions.kt line 99 is called:

classOfMap.getDeclaredField("m").asAccessible().get(systemEnv) as MutableMap<String, String>

method: getEditableMapOfVariables

@Suppress("UNCHECKED_CAST")
private fun getEditableMapOfVariables(): MutableMap<String, String> {
   val systemEnv = System.getenv()
   val classOfMap = systemEnv::class.java

   return classOfMap.getDeclaredField("m").asAccessible().get(systemEnv) as MutableMap<String, String>
}

Is there something I'm doing wrong?

@sksamuel
Copy link
Member

sksamuel commented Jun 5, 2022 via email

@Marek00Malik
Copy link
Author

java 17

@sksamuel
Copy link
Member

sksamuel commented Jun 6, 2022

Looks like this stopped working in Java16 and there's no way to set the map anymore.

@Marek00Malik
Copy link
Author

Can someone fix this?

@sksamuel
Copy link
Member

sksamuel commented Jun 7, 2022 via email

@Marek00Malik
Copy link
Author

this is bad/sad news... :( How can we configure Ktor then after it already started with a container on a random port?

@LeoColman
Copy link
Member

LeoColman commented Jun 23, 2022

From https://github.com/webcompere/system-stubs

warning WARNING: JDK Compatibility. From JDK16 onwards, there are deeper restrictons on the ability to use reflection. Previous versions of this library, and others in the space, encounter an Illegal Reflective Access warning, or even a runtime error such as java.lang.reflect.InaccessibleObjectException when trying to manipulate the Map behind the system's environment variables.
Consequently, this library now uses mockito-inline version 3.x to enable the interception of calls for reading environment variables. This requires consumers to both use a compatible version of Mockito AND be prepared for the inline implementation of Mockito mocks.
Note: Groovy users may need Mockito >= 4.5.0 for compatibility.
Where this isn't appropriate, the v1.x version of this will still work for Java versions below 16, and may also be co-erced into working with via the java stefanbirkner/system-lambda#23 (comment).
The long-term plan for this library is to use more interceptors of system functions with Mockito where possible, unless a more direct route becomes available. While this library will continue to be built for Java 8 at the moment, in future it may also move to a higher base version. The v1.x branch will stay on Java 8.

@LeoColman
Copy link
Member

They seem to still do it in some way, but bringing Mockito in.
It might be a possibility

@LeoColman
Copy link
Member

We do similar stuff with CurrentInstantListener, but using mockk.

@LeoColman
Copy link
Member

Just tested with
openjdk 18.0.1 2022-04-19

And our code is still working. Can you help me reproduce, @Marek00Malik ?

@Kantis
Copy link
Member

Kantis commented Jul 1, 2022

I added info here on how you can work around it: https://kotest.io/docs/extensions/system_extensions.html (see the blue info box)

@Marek00Malik
Copy link
Author

Thanks @Kantis, will test this later today!

@sksamuel
Copy link
Member

sksamuel commented Jul 4, 2022

Closing, please reopen if issue persists.

@jmfayard
Copy link
Contributor

@sksamuel I first raised #3112 which brought me here.

So I edited gradle.properties

-org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx4608M
+org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx4608M --add-opens=java.base/java.util=ALL-UNNAMED

I had a first issue Overriding a variable when mode is set to SetOrError. Use another OverrideMode to allow this. Trying to set {FIXED_OTP=hi42}

That's not a bug per se, but the fix was not obvious, it would be nice to mention it in the documentation
https://kotest.io/docs/extensions/system_extensions.html

-withEnvironment(OtpSource.FIXED_OTP, "hi42", , OverrideMode.SetOrOverride) {
+withEnvironment(OtpSource.FIXED_OTP, "hi42") {
         //
}

Alas that still fails

java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module @47089e5f

https://scans.gradle.com/s/rqvdpgm2f5fq6/tests/:test/com.tignum.backend.core.health.SanityCheckerTest/fixed%20OneTimePassword%20can%20be%20enabled%20only%20in%20the%20local%20environment()?expanded-stacktrace=WyIwIl0&top-execution=1

sschuberth added a commit to oss-review-toolkit/ort that referenced this issue Dec 21, 2022
For more background information see [1].

[1]: kotest/kotest#3035

Co-authored-by: Martin Nonnenmacher <martin.nonnenmacher@bosch.io>
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
sschuberth added a commit to oss-review-toolkit/ort that referenced this issue Dec 21, 2022
For more background information see [1].

[1]: kotest/kotest#3035

Co-authored-by: Martin Nonnenmacher <martin.nonnenmacher@bosch.io>
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
sschuberth added a commit to oss-review-toolkit/ort that referenced this issue Dec 21, 2022
For more background information see [1].

[1]: kotest/kotest#3035

Co-authored-by: Martin Nonnenmacher <martin.nonnenmacher@bosch.io>
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
jmlord added a commit to GEO-BON/bon-in-a-box-pipelines that referenced this issue Jan 13, 2023
@benkeil
Copy link

benkeil commented Mar 3, 2023

same issue...

@noraab
Copy link

noraab commented Mar 6, 2023

For me, the only fix was to have the following in the build.gradle.kts:

tasks.test {
    jvmArgs("--add-opens=java.base/java.util=ALL-UNNAMED")
}

Adding the arguments to gradle.properties did not help.

@Kantis
Copy link
Member

Kantis commented Mar 6, 2023

Thanks, I updated the docs. 29aac29

jmlord added a commit to GEO-BON/bon-in-a-box-pipeline-engine that referenced this issue Oct 25, 2023
jmlord added a commit to GEO-BON/bon-in-a-box-pipeline-engine that referenced this issue Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants