Spring Cloud Contract not deploying to Artifactory in Maven multi module projects - maven

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>
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>

Related

Exclude single module of multi-module project from aggregated report

I'm calling mvn site site:stage goal on multi-module project. One of the modules fails because in the chain of dependencies, which I can't influence, is reference to the http:// plugin repository.
This module is already excluded from site generation:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
The problem is, that the site plugin on the aggregator wants to include that project nevertheless and fails on maven-project-info-reports-plugin:3.4.1:dependency-convergence report. I don't need this module in site because it's no-java-source module (it calls plugin that verifies deployment to the application server).
How to configure reporting in the aggregator to exclude one module from generating aggregated report?

What is the best place for JavaDoc files in a Maven project using Tomcat?

I am regularly deploying a Maven project to a Tomcat server, using Travis CI. My project is a web app, so I have configured my pom.xml for building a WAR file, instead of a JAR:
...
<packaging>war</packaging>
...
With Maven, I can generate a directory containing all the JavaDoc files for my project; Maven puts them in the target/site/apidocs directory. But then, when I deploy my project, Travis doesn't perform any mvn site phase so I don't have my JavaDocs on the server.
Should I edit my pom.xml so that Maven puts the JavaDoc files somewhere in the src directory (instead of target) or is there a way to package the JavaDoc files together with the WAR file? I thought that I could create a docs/ directory inside src/main/webapp/. Specifically: is it "good practice" to generate my JavaDoc in src instead of target? if not, how can I have a WAR file containing my JavaDoc?
What would you suggest is the best thing to do?
I already know how to generate a standalone JAR containing my JavaDoc files (see here), but this is not what I'm looking for.
Use the site plugin https://maven.apache.org/plugins/maven-site-plugin/ and the javdoc plugin https://maven.apache.org/plugins/maven-javadoc-plugin/usage.html.
Add the following to your pom.xml
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>http://commons.apache.org/lang/api</link>
<link>http://java.sun.com/j2se/1.5.0/docs/api</link>
<link>http://this-one-will-not-work</link>
</links>
</configuration>
</plugin>
</plugins>
</reporting>
then mvn site:site your documentation will be in target/site you can also deploy it.

Wildfly Deploy Maven - Remove Version

I want to deploy a war that I have created using maven to wildfly using the wildfly-maven-plugin.
The final name of the war is something like: my-war-1.0.war
The war also contains a jboss-web.xml specifying the context root (e.g. /my-war)
Problem Description
If I now deploy the war to wildfly I will get a "my-war-1.0.war" deployment.
If I later want to deploy a new version (e.g. the war is now named my-war-1.1.war) I get a conflict as the context root is already known but the deployment has a new name.
Is there a way using the wildfly-maven-plugin to deploy a "my-war.war" instead?
I need to keep the original final build name inside the maven build for versioning and deploying to our nexus.
The simplest solution is to use the <finalName/> element on the <build/> configuration.
<build>
<finalName>${project.artifactId}</finalName>
</build>
You can use the maven war plugin to rename the final war. For Eg:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warName>my-war</warName>
</configuration>
</plugin>
</plugins>
</build>
This will always generate the war with the name my-war.war in your "target" directory.
I found out that I can use the parameters <name/> and <runtimeName/> inside the <configuration/> of the maven-wildfly-plugin.
That way I can specify what the deployment should be called on the server and each time just replace it. It is important to have the two parameters end in ".war", otherwise you will get a 404 error.
Using this method I can keep the original name of the final build result containing the version (my-app-1.0.war) and archive it inside our internal nexus repository.

How to avoid checking parent project in maven-site-plugin?

I have small maven project. I'm trying to add generating site by maven-site-plugin, but it doesn't work. When I'm building this project i get following error:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.3:site (default-site) on project server-wms-product: SiteToolException: The site descriptor cannot be resolved from the repository: ArtifactResolutionException: Unable to locate site descriptor: Could not transfer artifact [PARENT-PROJECT]:xml:site_en:1.0.141.1 from/to eclipse (http://maven.eclipse.org/nexus/content/repositories/testing/): Connection to http://maven.eclipse.org refused
My project is extension for other project, so in my pom.xml is set parent project which isn't mine and I can't add site configuration there.
So is there any chance to skip checking parent project's site in site generation?
My pom.xml looks like this:
<project>
<parent>
<artifactId>base-server-product</artifactId>
<groupId>XXXXXXXXXXXx</groupId>
<version>1.0</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<configuration>
<reportPlugins>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>
</project>
And of course i have site.xml file in src/site.
Configure attaching the site descriptor to the artifacts in the parent pom.
<project>
<artifactId>base-server-product</artifactId>
<groupId>XXXXXXXXXXXx</groupId>
<version>1.0</version>
...
<build>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<executions>
<execution>
<id>attach-descriptor</id>
<goals>
<goal>attach-descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Core functionality has been separated from site generation in maven 3. You can find the reasons here. If you want to refer to the parent module's site from the submodule, you have to attach the site.xml to the deployed artifacts.
I have the exact same problem, and after much googling, came across this article which solved my problem:
http://amanica.blogspot.com/2010/08/archiva-gives-maven-site-plugin-invalid.html?m=1
Basically you want to add a basic site_en.xml to /src/site/ folder in your parent pom.xml.
For a reason I can't fathom, with me, it was enough to run maven in offline mode once.
I came across this question when working on an open source project I don't own where I wanted to submit an update to a site being generated in this manner. I wanted to test and view the change locally, but kept hitting this error.
User #Frischling alluded to this above (credit to them). It turns out what I wanted was not to edit any existing information or update any pom.xml files, but just build entirely in offline mode.
I was trying to run this command and it was failing with the error the original poster mentioned:
mvn site
To do this build offline instead, execute the following commands:
# Download the dependencies for the target
mvn dependency:go-offline site
# Build the target offline
mvn --offline site
Then the output got correctly generated to the target/site directory like I expected.
It's not ideal if you own the project or part of the project, but for a case like mine where I owned none of it, it was the perfect option.
The previous answers didn't work for me.
But Mark's one, here, solved the issue I had: https://stackoverflow.com/a/57429991/5056068
Etienne

Order of maven multi module is not maintained for eclipse plugins

We have a bunch of eclipse plugin projects, features and update sites. We have created a master pom where we define the modules:
<modules>
<module>bundles/b1</module>
<module>features/f1</module>
<module>p2/site1</module>
<module>bundles/b2</module>
</modules>
We wanted to preserve this order and as per Guide to working with Multiple Modules
As per the link above we assumed that the order will be preserved as per the order in which the module elements were listed.
Our requirement:
site1 produces a site_assembly.zip. We wanted to take this zip file and wrap into around into a bundle which is what "b2" bundle does.
Our observation:
Maven reactor order which is printed at the beginning of the multi-module build is proper, however the build for every module is forked.
Because of (1) the bundle b2 get built before the site1 project is build and is able to produce a site assembly zip.
We tried adding a dependency in "b2"'s pom.xml to site1 but the build failed as it tries to build b2 first which has dependency on site1 which has not been built till now.
We observed the same behavior when we had unit test as osgi fragment. In the order we clearly specified that the host comes before the test fragment but when the maven build is invoked then it always built the fragment before the host and it used to fail.
Plugins that are defined in master pom:
<plugin>
<!-- enable tycho build extension -->
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<disableP2Mirrors>true</disableP2Mirrors>
<resolver>p2</resolver>
<target>
<artifact>
<groupId>com.x.y</groupId>
<artifactId>p2.build.target</artifactId>
<version>${project.version}</version>
<classifier>x</classifier>
</artifact>
</target>
</configuration>
</plugin>
We are not sure if maven-tycho-plugin interferes with the reactor order, so any help would be appreciated.
Tycho resolves the dependencies from the Eclipse descriptor files (MANIFEST.MF, feature.xml, etc.) and re-orders the modules so that required artifacts are built first.

Resources