spring-cloud-contract-samples
spring-cloud-contract-samples copied to clipboard
Example with external contracts and contractsMode CLASSPATH
Preamble
My setup contains the following modules:
| Module name | Corresponding module in the samples | Description |
|---|---|---|
| my-contracts | beer_contracts | Module with contracts. |
| my-producer | producer_with_external_contracts | Producer of the API. |
| my-consumer | - | Consumer of the API. |
I wanted to execute the Spring Cloud Contract tests during the build with contractsMode CLASSPATH.
For that reason, I created an aggregator containing these three modules und executed mvn clean test.
In the samples, the beer_contracts module with external contracts does not provide the artifact with the classifier stubs.
I choose another approach for my project.
The module my-contracts does provide the artifact with the classifier stubs.
The modules my-consumer and my-producer do not know each other but the API and the module my-contracts.
Issue
To demonstrate how Spring Cloud Contract works with external contracts, the samples contain already the modules beer_contracts and producer_with_external_contracts.
This works with contractsMode LOCAL but not with contractsMode CLASSPATH.
In my project this has a couple of reasons:
After setting contractsMode to CLASSPATH in my-producer the following problems occur:
-
No stubs were found on classpath for [com.example:beer-contracts]I had to add the dependency of
beer-contractsto the plugin dependencies inproducer_with_external_contractslike this:<plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>true</extensions> <configuration> ... <contractDependency> <groupId>de.demo</groupId> <artifactId>my-contracts</artifactId> <classifier>stubs</classifier> </contractDependency> <contractsMode>CLASSPATH</contractsMode> ... </configuration> <dependencies> <dependency> <groupId>de.demo</groupId> <artifactId>my-contracts</artifactId> <version>0.0.1.BUILD-SNAPSHOT</version> <classifier>stubs</classifier> </dependency> </dependencies> </plugin>The next error message is the following:
-
[ERROR] Unresolveable build extension: Plugin org.springframework.cloud:spring-cloud-contract-maven-plugin:2.1.3.BUILD-SNAPSHOT or one of its dependencies could not be resolvedNormally Maven will resolve the dependencies of modules and plugins during the build. The problem here is the
<extensions>true</extensions>tag. I guess that dependencies of extensions have to be available at the time the build starts and can not be resolved during the build. To fix it, I just had to include thespring-cloud-contract-maven-pluginto the extensions and remove the<extensions>true</extensions>tag (or set it to false):<build> <extensions> <extension> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> </extension> </extensions> <plugins> ... <plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>false</extensions> <configuration> ... <contractsMode>CLASSPATH</contractsMode> </configuration> <dependencies> <dependency> <groupId>de.demo</groupId> <artifactId>my-contracts</artifactId> <version>0.0.1.BUILD-SNAPSHOT</version> <classifier>stubs</classifier> </dependency> </dependencies> </plugin> </plugins> </build>
After these fixes, the build and all Spring Cloud Contract tests run properly. Now I have the following questions:
-
Is my approach with
my-contractsand artifact with classifierstubsused in consumer and producer by Spring Cloud Contracts intended? -
How would a setup look with given modules
beer_contractsandproducer_with_external_contractswithcontractsMode CLASSPATH? Just adapting my fixes does not work.
Hi!
Is my approach with my-contracts and artifact with classifier stubs used in consumer and producer by Spring Cloud Contracts intended?
I don't think we have ever assumed that someone would use the classpath mode with external contracts.
How would a setup look with given modules beer_contracts and producer_with_external_contracts with contractsMode CLASSPATH?
For sure you need to add the dependency to the classpath.
[ERROR] Unresolveable build extension: Plugin org.springframework.cloud:spring-cloud-contract-maven-plugin:2.1.3.BUILD-SNAPSHOT or one of its dependencies could not be resolved
This seems to mean that the snapshot dependency of the plugin couldn't have been found. I don't think you need to disable the extensions to retrieve it. Since you've already downloaded the plugin, can you rollback to point number 1 and try again.
I'm actually surprised that the CLASSPATH thing works anyways ;) But it's good to see that it does
Thanks for the fast feedback!
This seems to mean that the snapshot dependency of the plugin couldn't have been found.
I have the same error message with version 2.1.2.RELEASE and <extensions>true</extensions>:
Unresolveable build extension: Plugin org.springframework.cloud:spring-cloud-contract-maven-plugin:2.1.2.RELEASE or one of its dependencies could not be resolved
But this is only relevant for contractsMode CLASSPATH.
Are you interested to provide an example for classpath mode with external contracts or is this scenario too specific? In that case, I will close the issue :)
I have the same error message with version 2.1.2.RELEASE and
true :
wow, I'm surprised!
Are you interested to provide an example for classpath mode with external contracts or is this scenario too specific?
I think that it's specific, but if you're interested, feel free to provide a PR to this repo with a working sample (Maven and Gradle). That way, if anyone is interested, we'll show that there's an option to make this work :)
I created a draft for a PR in #108. To reproduce the error message
[ERROR] Unresolveable build extension: Plugin org.springframework.cloud:spring-cloud-contract-maven-plugin:2.1.3.BUILD-SNAPSHOT or one of its dependencies could not be resolved
you just have to edit the module producer_with_external_contracts_classpath:
Remove
<extensions>
<extension>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
</extension>
</extensions>
Change
<extensions>false</extensions>
to
<extensions>true</extensions>
Bumping this. Same situation, I have a multi-module project with one module containing the actual REST provider, and a separate module containing the contracts (as well as an OpenAPI specification), to be deployed as a separate artifact. This layout seems logical to me, not all that specific. It would be nice if the Classpath mode supported multi-module projects.
+1 to this issue I have 'producer' and 'producer-api' modules. I import 'producer-api' both to 'producer' and 'consumer' modules, so it seems natural to store 'producer' contracts in 'producer-api' module