mock-server / mockserver

MockServer enables easy mocking of any system you integrate with via HTTP or HTTPS with clients written in Java, JavaScript and Ruby. MockServer also includes a proxy that introspects all proxied traffic including encrypted SSL traffic and supports Port Forwarding, Web Proxying (i.e. HTTP proxy), HTTPS Tunneling Proxying (using HTTP CONNECT) and SOCKS Proxying (i.e. dynamic port forwarding).
http://mock-server.com
Apache License 2.0
4.57k stars 1.07k forks source link

Illegal reflective access by KeyAndCertificateFactoryFactory #1194

Closed saeltz closed 2 years ago

saeltz commented 2 years ago

Describe the issue We're running mock servers in our integration tests and seeing log output regarding illegal reflective access, see below.

What you are trying to do A mockserver is stopped after running a suite of integration tests.

MockServer version 5.12.0

To Reproduce Steps to reproduce the issue:

  1. Starting a mock server in a Scala project.
  2. Running the integration tests on JDK 11.
  3. Stopping the mock server.
  4. Seeing the below log output.
  5. Tests succeed.

Expected behaviour No warning about illegal reflective access. We want to update to JDK 17 soon.

MockServer Log

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.mockserver.socket.tls.KeyAndCertificateFactoryFactory (file:/home/runner/.cache/coursier/v1/https/repo1.maven.org/maven2/org/mock-server/mockserver-core/5.12.0/mockserver-core-5.12.0.jar) to constructor sun.security.util.DerValue(byte,java.lang.String)
WARNING: Please consider reporting this to the maintainers of org.mockserver.socket.tls.KeyAndCertificateFactoryFactory
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
jamesdbloom commented 2 years ago

This is sadly due to poor implementation inside the Java JDK. There is actually no way to test if access to certain classes is allowed without this error appearing despite the fact that the code is only checking the access and then adapting if there is no access. For some reason the JDK authors thought it would be a good idea to log the output in such a way that it was never realistically possible to configure.

In addition the reason this needs to be checked at all is because the introduction of modules in Java which breaks backwards compatibility in a massive way and makes it impossible to create libraries that support both Java 8 and 11+. In my opinion the whole approach to modules in Java is over opinionated and unnecessarily restrictive without achieving the aim / principles really needed, I suspect it may probably cause Java adoption to reduce over time.

This issue is now resolved however in the latest SNAPSHOT version by including a massive library to do all the TLS logic, called Bouncy Castle, previous this was done using JDK classes which kept the size of MockServer smaller.

If you use the SNAPSHOT version which will be released in 3-4 weeks then this output does not happen.

saeltz commented 2 years ago

This issue is now resolved however in the latest SNAPSHOT version

Thanks!

xtermi2 commented 2 years ago

A Workarount is to go back to 5.11.2 until the next release is out, this works for us with JDK 16.

jamesdbloom commented 2 years ago

This is only a warning output by the JVM and it should not stop MockServer which has been tested with Java 17. It due to the poor way this has been implemented in the JDK so there is no way to test is access is possible without this warning being output. MockServer handle the failure and adjusts in the case access is not possible and outputs a message if it is required for bouncy caste to be available in the classpath.

xtermi2 commented 2 years ago

@jamesdbloom Hmm, when I use 5.12.0 togehther with Java 16/17 I get this exception. Thought this is related with this issue.