quarkusio/quarkus

ConversionException/NPE in @QuarkusTest and using Pact-JVM Jupiter Provider

Sabartius opened this issue · 16 comments

Describe the bug
FollowUp to #8978 @tgippi
After Upgrading to Quarkus 1.5.0.Final Provider-Tests are still not possible, because the QuarkusTestExtension fails to xstream.deepCopy some Test-Context

Expected behavior
Tests should run, like in Quarkus 1.2.x

Actual behavior

[ERROR] testTemplate{PactVerificationContext}[1]  Time elapsed: 0.106 s  <<< ERROR!
com.thoughtworks.xstream.converters.ConversionException: 

---- Debugging information ----
cause-exception     : java.lang.NullPointerException
cause-message       : null
class               : java.util.concurrent.ConcurrentHashMap
required-type       : java.util.concurrent.ConcurrentHashMap
converter-type      : com.thoughtworks.xstream.converters.collections.MapConverter
path                : /au.com.dius.pact.provider.junit5.PactVerificationContext/store/valuesStore/parentStore/parentStore/parentStore/storedValues/entry/org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier/value/extensionContext/testDescriptor/children/java.util.Collections$SynchronizedCollection/default/c/org.junit.jupiter.engine.descriptor.ClassTestDescriptor/children/java.util.Collections$SynchronizedCollection/default/c/org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor/configuration/cache/entry
line number         : 420
class[1]            : org.junit.jupiter.engine.config.CachingJupiterConfiguration
required-type[1]    : org.junit.jupiter.engine.config.CachingJupiterConfiguration
converter-type[1]   : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2]            : org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor
required-type[2]    : org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor
class[3]            : java.util.LinkedHashSet
required-type[3]    : java.util.LinkedHashSet
converter-type[2]   : com.thoughtworks.xstream.converters.collections.CollectionConverter
class[4]            : java.util.Collections$SynchronizedSet
required-type[4]    : java.util.Collections$SynchronizedSet
converter-type[3]   : com.thoughtworks.xstream.converters.reflection.SerializableConverter
class[5]            : org.junit.jupiter.engine.descriptor.ClassTestDescriptor
required-type[5]    : org.junit.jupiter.engine.descriptor.ClassTestDescriptor
class[6]            : org.junit.jupiter.engine.descriptor.JupiterEngineDescriptor
required-type[6]    : org.junit.jupiter.engine.descriptor.JupiterEngineDescriptor
class[7]            : org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext
required-type[7]    : org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext
class[8]            : org.junit.jupiter.engine.extension.TimeoutConfiguration
required-type[8]    : org.junit.jupiter.engine.extension.TimeoutConfiguration
class[9]            : org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier
required-type[9]    : org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier
class[10]           : org.junit.jupiter.engine.execution.ExtensionValuesStore
required-type[10]   : org.junit.jupiter.engine.execution.ExtensionValuesStore
class[11]           : org.junit.jupiter.engine.execution.NamespaceAwareStore
required-type[11]   : org.junit.jupiter.engine.execution.NamespaceAwareStore
class[12]           : au.com.dius.pact.provider.junit5.PactVerificationContext
required-type[12]   : au.com.dius.pact.provider.junit5.PactVerificationContext
version             : 1.4.11.1
-------------------------------
Caused by: java.lang.NullPointerException


	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:77)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1487)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1467)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1338)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1329)
	at io.quarkus.test.junit.internal.XStreamDeepClone.clone(XStreamDeepClone.java:21)
	at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:535)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptBeforeEachMethod(QuarkusTestExtension.java:435)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeEachMethod(TimeoutExtension.java:76)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeMethodInExtensionContext(ClassBasedTestDescriptor.java:481)
	at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$synthesizeBeforeEachMethodAdapter$18(ClassBasedTestDescriptor.java:466)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachMethods$2(TestMethodTestDescriptor.java:169)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$5(TestMethodTestDescriptor.java:197)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:197)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachMethods(TestMethodTestDescriptor.java:166)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:133)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask$DefaultDynamicTestExecutor.execute(NodeTestTask.java:198)
	at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.lambda$execute$2(TestTemplateTestDescriptor.java:106)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
	at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:106)
	at org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor.execute(TestTemplateTestDescriptor.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.lang.NullPointerException
	at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
	at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
	at com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryIntoMap(MapConverter.java:107)
	at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:98)
	at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:92)
	at com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:87)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
	... 139 more


To Reproduce
checkout git@github.com:Sabartius/quarkus-pact-issue.git

run with mvn -P1.5 clean test

Configuration

Screenshots

Environment (please complete the following information):

  • Output of uname -a or ver:
  • Output of java -version:
    Java 11
  • GraalVM version (if different from Java):
  • Quarkus version or git rev:
    1.5.0-Final
  • Build tool (ie. output of mvnw --version or gradlew --version):
    Maven 3.6.3

Additional context

Just fiddled around with that and it seems that the QuarkusTest-Extension tries to clone au.com.dius.pact.provider.junit5.PactVerificationContext at some point using XStream which happens in QuarkusTestExtension:544 - it seems this is to provide JUnit5 invocation context arguments to a different classloader according to the comment:

// the arguments were not loaded from TCCL so we need to deep clone them into the TCCL
// because the test method runs from a class loaded from the TCCL

Unfortunately it seems that au.com.dius.pact.provider.junit5.PactVerificationContext cannot be serialized/deserialized by XStream. I tried to run the test without @QuarkusTest and simply tried to serialize/deserialize the PactVerificationContext using XStreamDeepClone and ran into the exact same issue:

@BeforeEach
void before(PactVerificationContext context) {
    context.setTarget(new AmpqTestTarget());

    var deepClone = new XStreamDeepClone(getClass().getClassLoader());
    var b = deepClone.clone(context); // Exception happens
}

We can't avoid deep cloning since the arguments need to converted to be loaded by the ThreadContext ClassLoader.
What does probably need to be improved is the deep clone implementation itself. Currently we have the simplest possible solution that works for most cases, but it clearly needs improvement

@geoand can you tell if deep cloning can be avoided once JUnit5 resolves the issue junit-team/junit5#201 ?

I see that #9886 has been resolved to fix the Supplier use case in a very specific way; however I can't see pointers to a general solution to solve the problem in this issue for example.

Yes, if JUnit fixes that issue (we have been monitoring it), then all nastiness of doing the deep cloone should go away

Is there some update on that issue? I just tested with Quarkus 1.11.1.Final and pact 4.1.15, the issue is the same.

Have any workarounds been identified for this issue, or is Pact unable to run with Quarkus for now?

I just faced the same issue here.

If you run with this PR: #17306

And add the following to application.properties:

quarkus.class-loading.parent-first-artifacts=au.com.dius:pact-jvm-consumer,au.com.dius:pact-jvm-consumer-java8,au.com.dius:pact-jvm-junit5,au.com.dius:pact-jvm-core-matchers,au.com.dius:pact-jvm-core-model,au.com.dius:pact-jvm-core-pact-broker,au.com.dius:pact-jvm-core-support,au.com.dius:pact-jvm-provider,au.com.dius:pact-jvm-provider-junit5

Then Pact will work.

Ideally this would add these artifact to Quarkus as being parent-first so it would 'just work', however the only place that really makes sense is core, which does not really feel right. @geoand WDYT?

Sure, it's not ideal to have this configuration in the core module, but we already do it for mockito (which no reasonable person would use outside of a test), so I think it's fine.

Did this resolution work for anyone here? I'm still getting the exact same error, and I've updated to the Quarkus version where the PR is baselined.

  <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-bom</artifactId>
      <version>2.0.0.Alpha3</version>
      <type>pom</type>
      <scope>import</scope>
  </dependency>

I've updated my Quarkus Maven Plugin to the same, and I've made the necessary additions to application.properties.

@stuartwdouglas used for the fix the old pact artifact ids which were used until Apr, 2020.
For me it failed because I am using the latest ids which are:
<parentFirstArtifact>au.com.dius.pact.core:model</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact.core:matcher</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact.core:support</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact.core:pactbroker</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact:consumer</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact.consumer:junit5</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact:provider</parentFirstArtifact> <parentFirstArtifact>au.com.dius.pact.provider:junit5</parentFirstArtifact>

I was able to make it work by added those to core/runtime/pom.xml.

@stuartwdouglas should I do a pull request with those appended to the list or should I replace the old artifact ids?

Go ahead and add the new coordinates to the list

@skattela I'm extremely grateful to your amazing eye!

Looks like my application.properties component for the fix should be adjusted then as well.

I dont think that you need the entries in the application.properties. For me it works without them.
The required changes are now merged and part of 2.0.0.CR3.
Here you can find an example of a pact contract test with a Quarkus consumer and a Quarkus provider.

@skattela I'm missing from your example how to use CDI managed beans from Quarkus in the Pact verification test.

In our case, we want to use a service to get the provider into a state, but the injected service is always null.

More specifically, in our @BeforeEach JUnit callback the injected beans are not null, but then in the method annotated with @State, the beans are null - I assume they are executed in a different context.

About my previous comment:
I investigated this issue and found out, that with that setup we generate two different test class instances.
I think this is normally also the case, but here Pact uses the instance, where Quarkus does not inject anything.

Here's the first instance creation (which will then be used by Pact)
https://github.com/quarkusio/quarkus/blob/2.6/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java#L687
A little below initTestState(extensionContext, state); is called, and it creates the "proper" instance:
https://github.com/quarkusio/quarkus/blob/2.6/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusTestExtension.java#L727

Maybe we can return the actualTestInstance within interceptTestClassConstructor().

@geoand I think this is a question for you

EDIT: I opened this as its own issue, see #22611