Skip to content

Maven Repositories

View as Markdown

Publish your Maven builds to CloudRepo and resolve your dependencies from it. Maven needs three things: the credential in settings.xml, the repository URL in pom.xml, and one command.

  • A Maven repository. If you have none, see Creating a Repository.
  • A repository token that reaches it, with Read + write if you will publish. See Repository Tokens: Create One and Authenticate. The username is the email address of the account that created the token, and the password is the token.
  • Your repository URL, https://your-org.mycloudrepo.io/repositories/your-repo. The Connection Settings of the repository show it with your names filled in.

1. Put the credential in ~/.m2/settings.xml. The <id> is a name you choose, and it must match the <id> of the repository in your pom.xml. ${env.CLOUDREPO_TOKEN} reads the token from an environment variable, so the token is not in the file; you can paste the token there instead.

~/.m2/settings.xml
<settings>
<servers>
<server>
<id>cloudrepo</id>
<username>you@example.com</username>
<password>${env.CLOUDREPO_TOKEN}</password>
</server>
</servers>
</settings>

Maven reads ~/.m2 by default. If you moved the local repository, put the file where your Maven looks for it. To keep a pasted token out of plain text, encrypt it by following Maven’s password encryption guide.

2. Name the repository in pom.xml. Repositories in <repositories> are where Maven retrieves artifacts from:

pom.xml
<repositories>
<repository>
<id>cloudrepo</id>
<url>https://your-org.mycloudrepo.io/repositories/your-repo</url>
</repository>
</repositories>

The repository in <distributionManagement> is where mvn deploy publishes:

pom.xml
<distributionManagement>
<repository>
<id>cloudrepo</id>
<url>https://your-org.mycloudrepo.io/repositories/your-repo</url>
</repository>
</distributionManagement>

If you have a parent POM, put both blocks there so you write them once.

3. Publish. Run this in the directory of your pom.xml:

Terminal
mvn --batch-mode deploy

Expected: BUILD SUCCESS, and the artifact is listed in the repository in the admin portal. Maven retrieves from the <repositories> entry during any build that needs a dependency from this repository, so there is nothing more to run for that.

Optional: fetch a file with curl. To fetch a file directly rather than through Maven, send the same credential. Put it in ~/.netrc and ask curl to read it:

~/.netrc
machine your-org.mycloudrepo.io
login you@example.com
password YOUR_REPOSITORY_TOKEN

Then fetch the file. Replace the path after /repositories/your-repo/ with your artifact’s group, name and version, and keep ~/.netrc readable by you alone (chmod 600 ~/.netrc):

Terminal
curl --netrc --fail --output docs-maven-1.0.0.jar \
https://your-org.mycloudrepo.io/repositories/your-repo/com/example/docs/docs-maven/1.0.0/docs-maven-1.0.0.jar

Gradle reads a CloudRepo Maven repository with the same URL and a repository token. The Gradle tab of Repository Tokens has a ready-to-paste build.gradle.kts and build.gradle, and Gradle Repositories covers publishing.

In addition to the Standard Settings of every repository, a Maven repository has Snapshot Cleanup and Overwrite Protection.

A snapshot is a version that ends in -SNAPSHOT. Each deploy of a snapshot version writes a new build, so a repository that is built often collects many builds of the same snapshot. A release version has one build.

In the repository’s settings, turn on Snapshot Cleanup and set Snapshots to keep per GAV, from 1 to 10: the number of builds to keep for each snapshot version of an artifact.

Overwrite Protection is on by default for a Maven repository: a repository that has not turned it off is protected, whenever it was created. With it on, publishing a release artifact to a coordinate that already holds one is refused with 409 Conflict, and the artifact already in the repository is left as it is.

Publish refused: status code 409, reason phrase Conflict

Section titled “Publish refused: status code 409, reason phrase Conflict”

If a mvn deploy has just failed and the only explanation in the output is this:

status code: 409, reason phrase: Conflict

you have republished a release version into a repository with Overwrite Protection on, which is the default. CloudRepo sends an explanation in the response body (Version already exists. Overwrites are disabled for this repository.), but Maven prints only the status code and the reason phrase and discards the rest.

Nothing is broken. Your credentials and the repository are fine: the server refused to replace a release artifact that already exists, and the artifact already in the repository is left as it is. It is a policy refusal, not a fault.

Three ways forward, in the order that is usually right:

  1. Publish a new version. Almost always the right answer. A release that someone else’s build has already used should not change under them.
  2. Use a -SNAPSHOT version while you iterate. Snapshot versions are exempt and may be republished as often as you build.
  3. Turn Overwrite Protection off for that repository, from the Overwrite Protection card in its settings, if it is meant to accept republished releases. The cost: a publish then replaces an existing release without a refusal, so a build that resolved that coordinate yesterday can get different bytes today.

Two things are exempt, because Maven rewrites both on every publish:

  • Snapshot versions. A version ending in -SNAPSHOT may always be overwritten, which is what gives Snapshot Cleanup several builds to count.
  • maven-metadata.xml, with its .md5, .sha1, .sha256, .sha512 and .asc sidecars. These index files are rewritten each time you publish a new version.

A checksum or signature that belongs to an artifact, such as my-app-1.0.0.jar.sha1, is not exempt. It is written once with its release and protected along with it.

A proxy repository passes requests through CloudRepo to a public Maven repository you choose from a curated list: Maven Central, Google Maven, Gradle Plugins, Clojars, Confluent, Atlassian, Spring and others. See Proxy Repositories.