pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

Encounter java.lang.NoClassDefFoundError: scala/Product$class when run Pact JVM cases #550

Closed yuandanxu closed 10 months ago

yuandanxu commented 6 years ago

When execute PACT JVM test case, got following error. Actually before this error, there's another scala error, after adding one scala dependency, that issue resolved, but come this one. Anyone encounter similar issue? I've added following dependency in my project.

org.typelevel scala-library 2.12.0

java.lang.NoClassDefFoundError: scala/Product$class at au.com.dius.pact.model.RequestMatching.(RequestMatching.scala:7) at au.com.dius.pact.model.RequestMatching$.apply(RequestMatching.scala:7) at au.com.dius.pact.model.RequestMatching.apply(RequestMatching.scala) at au.com.dius.pact.consumer.BaseMockServer.(MockHttpServer.kt:61) at au.com.dius.pact.consumer.MockHttpServer.(MockHttpServer.kt:202) at au.com.dius.pact.consumer.MockHttpServerKt.mockServer(MockHttpServer.kt:34) at au.com.dius.pact.consumer.ConsumerPactRunnerKt.runConsumerTest(ConsumerPactRunner.kt:12) at au.com.dius.pact.consumer.ConsumerPactTestMk2.testPact(ConsumerPactTestMk2.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at au.com.dius.pact.consumer.BaseProviderRule$1.evaluate(BaseProviderRule.java:59) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.ClassNotFoundException: scala.Product$class at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 33 more

Following is my pom included PACT related dependecies:

    <dependency>
        <groupId>org.typelevel</groupId>
        <artifactId>scala-library</artifactId>
        <version>2.12.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.scala-lang/scala-reflect -->
    <dependency>
        <groupId>org.scala-lang</groupId>
        <artifactId>scala-reflect</artifactId>
        <version>2.12.0</version>
    </dependency>

    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20170516</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-provider-maven_2.11</artifactId>
        <version>3.5.5</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-consumer_2.11</artifactId>
        <version>3.5.5</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-provider_2.11</artifactId>
        <version>3.5.5</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-model</artifactId>
        <version>3.5.5</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-matchers_2.11</artifactId>
        <version>3.5.5</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-pact-broker</artifactId>
        <version>3.5.5</version>
    </dependency>

    <dependency>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-consumer-junit_2.11</artifactId>
        <version>3.5.5</version>
        <scope>test</scope>
    </dependency>

My testing Code: public class ContractTest extends ConsumerPactTestMk2 {

@Rule
public PactProviderRuleMk2 mockProvider = new PactProviderRuleMk2("test_provider", "localhost", 5055, this);

@Override
@Pact(provider="test_provider", consumer="test_consumer")
protected RequestResponsePact createPact(PactDslWithProvider builder) {
    Map<String, String> headers = new HashMap<String, String>();
    headers.put("testreqheader", "testreqheadervalue");

    JSONObject updateJsonObj = new JSONObject();
    JSONObject updateVersion = new JSONObject();
    updateVersion.put("version", "1.4");
    updateJsonObj.put("update", updateVersion);
    return builder.given("test state 1") // NOTE: Using provider states are optional, you can leave it out
            .uponReceiving("ExampleJavaConsumerPactTest test interaction")
                .path("/hostService/hosts/1")
                .method("PUT")
                .body(updateJsonObj)
            .willRespondWith()
                .status(200)
                .body(updateJsonObj)
            .given("test state 2") // NOTE: Using provider states are optional, you can leave it out
            .uponReceiving("ExampleJavaConsumerPactTest second test interaction")
                .method("GET")
                .path("/hostService/hosts/1")
                .body("")
            .willRespondWith()
                .status(200)
                .body("")
            .toPact();
}

@Override
protected String providerName() {
    return "test_provider";
}

@Override
protected String consumerName() {
    return "test_consumer";
}

@Override
protected void runTest(MockServer mockServer) throws IOException {
    HttpClient httpClient = HttpClients.createDefault();        
    HttpPut putReq = new HttpPut(mockServer.getUrl());
    HttpGet getReq = new HttpGet(mockServer.getUrl());

    HttpResponse response = httpClient.execute(getReq);     
    Assert.assertEquals(response.getStatusLine().getStatusCode(), 200);

    response = httpClient.execute(putReq);
    Assert.assertEquals(getVersion(response.getEntity().toString()), "1.3"); 
}
TimothyJones commented 6 years ago

Thanks for the report! You're not the only one affected - I also hit it around the same time you did, (as did this stackoverflow user). @uglyog helped me sort it out by including the dependencies.

We'll have to take a look at the dependencies of 3.5.5, but right now you can either:

  1. Work around it by downgrading to version 3.5.4

  2. Include the missing dependencies explicitly. For me, this was:

And here it is ready to go straight into your POM file:

<dependency>
    <groupId>au.com.dius</groupId>
    <artifactId>pact-jvm-matchers_2.12</artifactId>
    <version>3.5.5</version>
</dependency>

<dependency>
    <groupId>au.com.dius</groupId>
    <artifactId>pact-jvm-model</artifactId>
    <version>3.5.5</version>
</dependency>