0

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

rafaborrego
  • 610
  • 1
  • 8
  • 19
  • Can you upload your sample somewhere so that i can check it out? – Marcin Grzejszczak Dec 18 '17 at 10:25
  • I have created a reduced version of the project and it works fine, so it is a conflict with some configuration that doesn't happen in other projects that I have with a single module. It seems as the issues are caused by a custom parent project that extends spring-boot-starter-parent. The deployment of my API works fine if I copy the code of that parent to it, but not if it extends it. Interestingly it works if I remove the line from the plugin configuration but then it doesn't generate the stubs. I will continue investigating and post more info. Thanks – rafaborrego Dec 19 '17 at 17:24
  • It seems to be related to: https://issues.apache.org/jira/plugins/servlet/mobile#issue/MDEPLOY-193 as explained here: https://stackoverflow.com/questions/36328154/maven-deploy-plugin-deployatend-not-working . I will try to figure out how the plugins are clashing and how to solve it – rafaborrego Dec 19 '17 at 17:47
  • I have managed to make it work with a workaround and I have also found the right solution that is removing deployAtEnd from the configuration of maven-deploy-plugin. I have documented both in the answer. – rafaborrego Dec 19 '17 at 19:25

1 Answers1

2

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>
  • Add this to the pom file of the other modules:
<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>
rafaborrego
  • 610
  • 1
  • 8
  • 19