I have a multi module project in which each module deploys fine to Artifactory until I add spring-cloud-contract-maven-plugin to one of the modules (the service, as it is a producer API).
The project has this structure:
parent
- common (shared DTOs)
- client
- service
We want to remove the client and the common in the future and have Feign clients in the consumers for reducing the coupling, and have a basic project without inner modules, but for now we have to keep this structure.
I first noticed that the stubs were not pushed to Artifactory, so my initial workaround was to add this to the Jenkins pipeline
sh './mvnw clean deploy -U --projects=xxx-service'
It deploys the service and the stubs, but I noticed that none of the modules gets deployed when this command is executed:
sh './mvnw clean deploy -U'
This is the end of the output:
[INFO] Installing /xxx/xxx-service/target/xxx-service-1.7.0-SNAPSHOT.jar to /xxx/.m2/repository/xxx/xxx-service/1.7.0-SNAPSHOT/xxx-service-1.7.0-SNAPSHOT.jar
[INFO] Installing /xxx/xxx-service/pom.xml to /xxx/.m2/repository/xxx/xxx-service/1.7.0-SNAPSHOT/xxx-service-1.7.0-SNAPSHOT.pom
[INFO] Installing /xxx/xxx-service/target/xxx-service-1.7.0-SNAPSHOT-stubs.jar to /xxx/.m2/repository/xxx/xxx-service/1.7.0-SNAPSHOT/xxx-service-1.7.0-SNAPSHOT-stubs.jar
[INFO]
[INFO] --- maven-deploy-plugin:2.8.2:deploy (default-deploy) @ xxx-service ---
[INFO] Deploying xxx:xxx-service:1.7.0-SNAPSHOT at end
I have tried to move all the Maven configuration to the parent POM file and keep the contracts and the base test classes in the service module. I have looked to this page that explains how to configure the plugin and I have seen that I can use contractsDirectory to specify the directory of the contract files, gmavenplus-plugin to specify the directory of the generated tests and packageWithBaseClasses to specify the package of the base classes. However I don't see any way to specify the directory of the base classes. I cannot move the base test classes to the parent because they use some classes of the service module for generating the mocks.
Is there any way of doing it or I have to create a separate project for the contracts?
Thanks in advance
Cause of the problem:
I had this in a parent project extended by my API:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
<configuration>
<deployAtEnd>true</deployAtEnd>
</configuration>
</plugin>
Why is this a problem:
maven-deploy-plugin seems to conflict with multi module projects with plugins that use extensions like spring-cloud-contract-maven-plugin. There is a known issue documented here, look to the answer of Jerome that is also here.
Solution 1:
Remove the deployAtEnd option from the previous block so it would be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
</plugin>
Solution 2:
Configure the plugin in all the modules although they don't need it. For doing so:
Add an empty "contracts" folder under src/test/resources on all the modules
Add this to the pom file of the service module:
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
<configuration
<baseClassForTests>com.xxx.BaseContractTest</baseClassForTests>
</configuration>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
<version>${spring-cloud-contract.version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>