gradle init isn't enough.
Motivation. Nearly all tutorials online will tell you to run
gradle init , which will detect Maven's
pom.xml and convert some basic configurations to Gradle's
build.gradle. That's sweet, but you almost always need more than that. The complexity roots from the fact that both Maven and Gradle are very modularized, and their plugins aren't interchangeable.
Scope. This post serves as a catalog of unofficial (but de facto) Gradle equivalents of Maven plugins I’ve collected. When it’s not readily available elsewhere, I’ll also provide sample configurations for both build tools in each case, putting them equivalent as much as possible.
Code Formatter, Contract Scaffolding, and Version Bumping
Well-maintained software may provide a Maven plugin and a Gradle one simultaneously. For example, the code formatter Spotless has a Maven edition and a Gradle edition. Across both build tools, Spotless recognizes the same set of configurations, so all you need to do is to translate some XML to Groovy — a trivial task.
For other plugins, things can be tough. If you are lucky, you can find unofficial ports, wrappers, or mimickers of the Maven plugin in the Gradle world. As an example, Swagger Codegen maintains an official plugin for Maven, while Gradle users would have to settle with an unofficial wrapper. (For usage of this plugin itself, see the section below, “Generate code from OpenAPI contracts”.)
Even for what you’d consider “basic” features, this is often still the case. For example, to bump version numbers at release time, Maven offers an official plugin (namely, the Maven Release Plugin), but Gradle users have to rely on a third-party developer (namely, gradle-release):
While you’d define the version in
pom.xml with Maven, Gradle puts it in a separate file,
# Managed by the plugin `gradle-release`. Edit with caution.
Note for CI users:
gradle-release needs to know which remote branch it can push the version-bumping commit to. Therefore, when checking out the code, remember to check out to a branch (on contrast to a Detached Head).
Publishing to a Maven Repository
Releasing and publishing often go hands in hands. Since you’re migrating a project from Maven, chances are that you are publishing its artifacts to a Maven Repository.
With Maven, you would run
mvn deploy for uploading your artifact to a remote MR or
mvn install for the local. These two commands are realized by two separate plugins, Maven Deploy Plugin and Maven Install Plugin). On the Gradle side, however, one plugin provides both, confusingly named Maven Publish Plugin. Equivalents of those two commands are
gradle publish and
gradle publishToMavenLocal, respectively.
Defining your own Maven Repository server
Your organization may have an internal Maven Repository. In that case, your
pom.xml might have been configured with a Distribution Management tag:
On the Gradle land, this can be written more succinctly:
Authenticating for Maven Repository
Most likely, your Maven Repository requires authentication. In your
settings.xml, you may find a
<server /> section with username and password (encrypted, of course):
Good news is that Gradle can simply read your Maven
settings.xml for the credentials. Just add the plugin
This plugin will read from
servers for the
<server /> whose
<id /> matches
Generate code from OpenAPI contracts
If you’re building API servers in 2022, you may be practicing Contract-First Development, with your contract adhering to OpenAPI Specification.
In the Maven world, to generate code from the contract, a popular choice is the Swagger Codegen Maven plugin. Your
pom.xml would be configured like this (taken from the official README file):
The Gradle equivalent is the Gradle Swagger Generator Plugin:
Configurations for Swagger Codegen are defined under
<configOptions /> in Maven and in
additionalProperties in Gradle. To ease the migration between the two, put Swagger Codegen configurations in a separate file. (In my examples above, that's the
swagger-config.json.) Both the Maven plugin and the Gradle plugin can read it.
You may be surprised to learn how differently the two build tools grow their ecosystems. For many features, Maven boasts official plugins, whereas Gradle users rely on community efforts. Migrating from Maven to Gradle is no easy work.
That being said, if the two were identical, why bother with the migration at all? Pick your poison. As commonly said, software engineering is about making tradeoffs. The best we can do is to make everybody’s lives easier by summarizing and sharing the field knowledge, as this article — and my whole blog — is striving to.