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.59k stars 1.07k forks source link

Updating 5.10.0 -> 5.11.1 breaks with NoSuchMethodError: JsonNumEquals.getInstance() #1003

Closed jmizv closed 2 years ago

jmizv commented 3 years ago

Describe the issue I have a test case which uses MockServer in version 5.10.0.

What you are trying to do See the following code executed with 5.10.0 does not raise the error but after upgrading to 5.11.1 this error appears:

 @Test
  void should_create_source_with_proxy(ClientAndServer clientAndServer) {
    Integer port = clientAndServer.getLocalPort();
    AtomicReference<HttpRequest> httpRequestHolder = new AtomicReference<>();
    clientAndServer.when(HttpRequest.request("/"))
        .respond(httpRequest -> responseCallbackWithNotFound(httpRequest, httpRequestHolder));
  // ....

Error:

ExecutionError - com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()'

MockServer version 5.11.1

To Reproduce Using this code should be enough. Switching between both version to see that the error happens only in the newer version:

import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockserver.client.MockServerClient;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.junit.jupiter.MockServerExtension;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;

@ExtendWith(MockServerExtension.class)
class SomeTest {

  @Test
  void should_create_source_with_proxy(ClientAndServer clientAndServer) {
    Integer port = clientAndServer.getLocalPort();
    AtomicReference<HttpRequest> httpRequestHolder = new AtomicReference<>();
    clientAndServer.when(HttpRequest.request("/"))
        .respond(httpRequest -> responseCallbackWithNotFound(httpRequest, httpRequestHolder));
  }

  private HttpResponse responseCallbackWithNotFound(HttpRequest httpRequest, AtomicReference<HttpRequest> httpRequestHolder) {
    httpRequestHolder.set(httpRequest);
    return HttpResponse.notFoundResponse();
 }
}

Expected behaviour No exception in this code.

MockServer Log 2021-03-25T17:49:15.008Z [MockServer-EventLog4] ERROR o.mockserver.log.MockServerEventLog:102 - 57677 exception validating JSON com.google.common.util.concurrent.ExecutionError: com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()' at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2049) at com.google.common.cache.LocalCache.get(LocalCache.java:3951) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4935) at com.github.fge.jsonschema.core.processing.CachingProcessor.process(CachingProcessor.java:122) at com.github.fge.jsonschema.processors.validation.InstanceValidator.process(InstanceValidator.java:109) at com.github.fge.jsonschema.processors.validation.ValidationProcessor.process(ValidationProcessor.java:56) at com.github.fge.jsonschema.processors.validation.ValidationProcessor.process(ValidationProcessor.java:34) at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79) at com.github.fge.jsonschema.main.JsonValidator.validate(JsonValidator.java:104) at org.mockserver.validator.jsonschema.JsonSchemaValidator.isValid(JsonSchemaValidator.java:122) at org.mockserver.validator.jsonschema.JsonSchemaValidator.isValid(JsonSchemaValidator.java:113) at org.mockserver.serialization.ExpectationSerializer.deserialize(ExpectationSerializer.java:114) at org.mockserver.serialization.ExpectationSerializer.deserializeArray(ExpectationSerializer.java:171) at org.mockserver.mock.HttpState.handle(HttpState.java:527) at org.mockserver.netty.HttpRequestHandler.channelRead0(HttpRequestHandler.java:92) at org.mockserver.netty.HttpRequestHandler.channelRead0(HttpRequestHandler.java:48) at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at org.mockserver.dashboard.DashboardWebSocketHandler.channelRead(DashboardWebSocketHandler.java:141) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at org.mockserver.closurecallback.websocketregistry.CallbackWebSocketServerHandler.channelRead(CallbackWebSocketServerHandler.java:55) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296) at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at org.mockserver.netty.unification.PortUnificationHandler.switchToHttp(PortUnificationHandler.java:260) at org.mockserver.netty.unification.PortUnificationHandler.decode(PortUnificationHandler.java:138) at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501) at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at java.base/java.lang.Thread.run(Thread.java:832) Caused by: com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()' at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2049) at com.google.common.cache.LocalCache.get(LocalCache.java:3951) at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974) at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4935) at com.github.fge.jsonschema.core.processing.CachingProcessor.process(CachingProcessor.java:122) at com.github.fge.jsonschema.processors.validation.ValidationChain.process(ValidationChain.java:107) at com.github.fge.jsonschema.processors.validation.ValidationChain.process(ValidationChain.java:57) at com.github.fge.jsonschema.core.processing.ProcessorMap$Mapper.process(ProcessorMap.java:166) at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79) at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:141) at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:133) at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ... 69 common frames omitted Caused by: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()' at com.github.fge.jackson.JsonNumEquivalence.doHash(JsonNumEquivalence.java:44) at com.github.fge.jackson.JsonNumEquivalence.doHash(JsonNumEquivalence.java:27) at com.google.common.base.Equivalence.hash(Equivalence.java:112) at com.google.common.base.Equivalence$Wrapper.hashCode(Equivalence.java:228) at java.base/java.util.HashMap.hash(HashMap.java:340) at java.base/java.util.HashMap.put(HashMap.java:613) at java.base/java.util.HashSet.add(HashSet.java:221) at com.github.fge.jsonschema.core.keyword.syntax.checkers.common.EnumSyntaxChecker.checkValue(EnumSyntaxChecker.java:68) at com.github.fge.jsonschema.core.keyword.syntax.checkers.AbstractSyntaxChecker.checkSyntax(AbstractSyntaxChecker.java:116) at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:112) at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:118) at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:118) at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.validate(SyntaxProcessor.java:118) at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.rawProcess(SyntaxProcessor.java:70) at com.github.fge.jsonschema.core.keyword.syntax.SyntaxProcessor.rawProcess(SyntaxProcessor.java:45) at com.github.fge.jsonschema.core.processing.RawProcessor.process(RawProcessor.java:77) at com.github.fge.jsonschema.core.processing.RawProcessor.process(RawProcessor.java:41) at com.github.fge.jsonschema.core.processing.ProcessorChain$ProcessorMerger.process(ProcessorChain.java:190) at com.github.fge.jsonschema.core.processing.ProcessingResult.of(ProcessingResult.java:79) at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:141) at com.github.fge.jsonschema.core.processing.CachingProcessor$1.load(CachingProcessor.java:133) at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) ... 83 common frames omitted 2021-03-25T17:49:15.014Z [MockServer-EventLog4] ERROR o.mockserver.log.MockServerEventLog:102 - 57677 exception processing request:

  {
    "method" : "PUT",
    "path" : "/mockserver/expectation",
    "headers" : {
      "content-type" : [ "application/json; charset=utf-8" ],
      "host" : [ "127.0.0.1:57677" ],
      "accept-encoding" : [ "gzip,deflate" ],
      "content-length" : [ "296" ],
      "connection" : [ "keep-alive" ]
    },
    "keepAlive" : true,
    "secure" : false,
    "body" : {
      "id" : "45cb1d07-311c-4047-8340-62555fee81a2",
      "priority" : 0,
      "httpRequest" : {
        "path" : "/"
      },
      "httpResponseObjectCallback" : {
        "clientId" : "00e6c6e0-21ae-41eb-a64d-f519a1b59490"
      },
      "times" : {
        "unlimited" : true
      },
      "timeToLive" : {
        "unlimited" : true
      }
    }
  }

error:

incorrect expectation json format for:

    {
      "id" : "45cb1d07-311c-4047-8340-62555fee81a2",
      "priority" : 0,
      "httpRequest" : {
        "path" : "/"
      },
      "httpResponseObjectCallback" : {
        "clientId" : "00e6c6e0-21ae-41eb-a64d-f519a1b59490"
      },
      "times" : {
        "unlimited" : true
      },
      "timeToLive" : {
        "unlimited" : true
      }
    }

schema validation errors:

ExecutionError - com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()'

incorrect expectation json format for:

{ "id" : "45cb1d07-311c-4047-8340-62555fee81a2", "priority" : 0, "httpRequest" : { "path" : "/" }, "httpResponseObjectCallback" : { "clientId" : "00e6c6e0-21ae-41eb-a64d-f519a1b59490" }, "times" : { "unlimited" : true }, "timeToLive" : { "unlimited" : true } }

schema validation errors:

ExecutionError - com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()' java.lang.IllegalArgumentException: incorrect expectation json format for:

{ "id" : "45cb1d07-311c-4047-8340-62555fee81a2", "priority" : 0, "httpRequest" : { "path" : "/" }, "httpResponseObjectCallback" : { "clientId" : "00e6c6e0-21ae-41eb-a64d-f519a1b59490" }, "times" : { "unlimited" : true }, "timeToLive" : { "unlimited" : true } }

schema validation errors:

ExecutionError - com.google.common.util.concurrent.ExecutionError: java.lang.NoSuchMethodError: 'com.github.fge.jackson.JsonNumEquals com.github.fge.jackson.JsonNumEquals.getInstance()' at org.mockserver.client.MockServerClient.sendRequest(MockServerClient.java:209) at org.mockserver.client.MockServerClient.sendRequest(MockServerClient.java:229) at org.mockserver.client.MockServerClient.upsert(MockServerClient.java:977) at org.mockserver.client.ForwardChainExpectation.respond(ForwardChainExpectation.java:91)

lrozenblyum commented 3 years ago

Hi I faced the same problem and downgraded to 5.10.0. The reason looks to be a conflict of jackson-coreutils 1. and 2. in the classpath. Most likely you have a transitive dependency with this library 1.*

jamesdbloom commented 2 years ago

MockServer uses the latest version of Jackson if you upgrade the dependency in your project that would also resolve the problem.