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

Pact JVM 4.2.9 not compatible with Java 15 #1426

Closed jonrosner closed 12 months ago

jonrosner commented 3 years ago

In the README of pact-jvm Github repo it says that 4.2.x is compatible with Java 11-15. But when I try to run my provider tests using gradle I get the following error:

$ ./gradlew clean pactVerify
Verification Failed - Could not load class mypackage.MyClass :
java.lang.UnsupportedClassVersionError: mypackage/MyClass has been compiled by a more 
recent version of the Java Runtime (class file version 59.0), this version of the Java 
Runtime only recognizes class file versions up to 55.0

I am using Java 15 to compile my code as is stated in the error log (version 59.0). Running my tests without pact-jvm works just fine.

here is my provider config:

plugins {
    id("au.com.dius.pact") version "4.2.9"
}

dependencies {
    testImplementation("au.com.dius.pact", "provider", "4.2.9")
}

pact {
    serviceProviders {
        create("Provider") {
            verificationType = ANNOTATED_METHOD
            packagesToScan = listOf("...mypackage...")
            hasPactWith("consumer") {
                pactSource = file("config/consumer-Provider.json")
            }
        }
    }
}

And finally my very simple provider test:

class PactTest {

    @PactVerifyProvider("a valid message")
    String verifyMessage() {
        return "{\"testParam1\":\"value1\",\"testParam2\":\"value2\"}";
    }
}
uglyog commented 3 years ago

mypackage.MyClass is not a Pact-JVM class. It has been compiled with JDK 15 (class file version 59), but you are running JDK 11 (class file version 55).

Pact-JVM will run on all versions of Java 11-15.

jonrosner commented 3 years ago

No I am not running jdk 11. I have the following config in my build.gradle.kts:

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(15))
    }
}

Also I selected 15 for java and javac using update-alternatives.

$ java --version
openjdk 15.0.2 2021-01-19
OpenJDK Runtime Environment (build 15.0.2+7-27)
OpenJDK 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
$ javac --version
javac 15.0.2

When I downgrade everything to Java 11 it works fine, then I get the following output:

$ ./gradlew pactverify -Ppact.verifier.publishResults=true
Starting a Gradle Daemon, 1 busy and 4 stopped Daemons could not be reused, use --status for details

> Task :pactVerify_Provider

Verifying a pact between consumer and Provider

  Notices:
    1) The pact at http://localhost:9292/pacts/provider/xxx is being verified because the pact content belongs to the consumer version matching the following criterion:
    * latest version of a consumer that has a pact with Provider

  [from Pact Broker http://localhost:9292/pacts/provider/xxx]
  Given ProviderOk
         WARNING: State Change ignored as there is no stateChange URL
  a valid message
    generates a message which
      has a matching body (OK)
      has matching metadata (OK)

BUILD SUCCESSFUL in 24s
6 actionable tasks: 1 executed, 5 up-to-date
jonrosner commented 3 years ago

This issue actually blocks us from implementing Pact into our company infrastructure. Is there any resolution to this yet? Why does the documentation say that Java 15 is supported?

uglyog commented 3 years ago

Coming back to my original comment, this is not a problem with Pact-JVM, but with your project. Pact-JVM runs fine on JDK 15. You can see the CI build for it running on all JDK versions from 11 to 15: https://github.com/pact-foundation/pact-jvm/runs/3456724915?check_suite_focus=true

Can you provide debug logs running on JDK 15? Or an example project that demonstrates the problem?

johnsgp commented 3 years ago

Which version of Java is Gradle using? Try gradlew -v

jonrosner commented 3 years ago

It turns out that JAVA_HOME was pointed to a wrong Java version, even though I was using update-alternatives. So basically what @uglyog said was totally correct but it only caused a problem when running pactverify. Running unit tests worked (aka. used Java 15), running the app worked and all other gradle tasks worked.

Can anyone explain to me what happened here exactly? Why do all other commands work and only the pactverify fails with this exception?

rholshausen commented 1 year ago

pactVerify uses class path scanning to find annotated methods. That is causing the class to be loaded.