Upload Maven Artifacts to Sonatype Nexus
Goal
Transfer a component version and upload a JAR and its POM into a Nexus maven2 hosted repository, so that Maven resolves the artifact from its coordinates.
You’ll end up with
demo-1.0.0.jaranddemo-1.0.0.pomstored undercom/example/demo/1.0.0/inmaven-releases- Transferred resources with a
Wget/v1access on the stored files
Estimated time: ~10 minutes
Prerequisites
- The setup in Sonatype Nexus, with credentials configured
- A Nexus maven2 hosted repository with release version policy, here
maven-releases - The
mvnCLI
Steps
Add the JAR and the POM as resources
Upload the POM as a resource of its own next to the artifact. The component version holds the JAR and its POM as two resources:
components:
- name: ocm.software/demo
version: 1.0.0
provider: {name: ocm.software}
resources:
- name: jar
type: blob
version: 1.0.0
input: {type: file/v1, path: ./demo-1.0.0.jar, mediaType: application/java-archive}
- name: pom
type: blob
version: 1.0.0
input: {type: file/v1, path: ./demo-1.0.0.pom, mediaType: application/xml}Configure the uploader
A maven2 repository needs a path in the Maven repository layout
<group path>/<artifactId>/<version>/<artifactId>-<version>[-<classifier>].<extension>.
The uploader takes the coordinates from the path. Add the credentials and one rule
per file to your .ocmconfig in the working directory (merged with
$HOME/.ocmconfig):
type: generic.config.ocm.software/v1
configurations:
- type: credentials.config.ocm.software
consumers:
- identity:
type: Wget
hostname: nexus.example.com
scheme: https
credentials:
- type: WgetCredentials/v1
username: <USERNAME>
password: <PASSWORD_OR_USER_TOKEN>
- type: nexus.uploader.transfer.config.ocm.software/v1alpha1
match: resource.access.isType("LocalBlob") && resource.name == "jar"
url: https://nexus.example.com
repository: maven-releases
path: '${"com/example/demo/" + resource.version + "/demo-" + resource.version + ".jar"}'
- type: nexus.uploader.transfer.config.ocm.software/v1alpha1
match: resource.access.isType("LocalBlob") && resource.name == "pom"
url: https://nexus.example.com
repository: maven-releases
path: '${"com/example/demo/" + resource.version + "/demo-" + resource.version + ".pom"}'Run the transfer
ocm transfer cv ctf::./src//ocm.software/demo:1.0.0 ctf::./targetVerify
ocm get cv ctf::./target//ocm.software/demo:1.0.0 -o yamlThe jar resource has this access:
access:
type: Wget/v1
url: https://nexus.example.com/repository/maven-releases/com/example/demo/1.0.0/demo-1.0.0.jar
mediaType: application/java-archiveResolve the artifact with Maven:
mvn dependency:get -Dartifact=com.example:demo:1.0.0 \
-DremoteRepositories=nexus::default::https://nexus.example.com/repository/maven-releasesHow the repository behaves
- Release versions go through the Nexus components API
(
POST /service/rest/v1/components), which updatesmaven-metadata.xml. Itslatestandreleaseare the highest version, not the most recently uploaded one: transferring4.0.0after5.0.0keeps5.0.0. - Snapshot versions go into a snapshot repository such as
maven-snapshotswith a plainPUT, because the components API refuses them. Maven resolves them by their exact version, but they are not added tomaven-metadata.xml. The repository’s version policy decides what it accepts. - Stored files are never overwritten, see Existing files at the upload path.
- A
pathoutside the Maven layout, or nopath, fails before anything is uploaded. - A POM must declare the coordinates of its
path: Nexus stores a POM under the coordinates it declares, so a mismatch fails before anything is uploaded.
Troubleshooting
Symptom: path "…" is not in the Maven repository layout …
Cause: path is missing or not in the Maven layout.
Fix: Set a path in the Maven layout.
Symptom: POM declares …, but path "…" is …
Cause: The groupId, artifactId or version in the POM differ from those in path.
Fix: Set a path that matches the POM coordinates.
Symptom: Version policy mismatch, cannot upload SNAPSHOT content to RELEASE repositories
Cause: A -SNAPSHOT version was routed to a release repository.
Fix: Route -SNAPSHOT versions of both files to maven-snapshots with a rule
declared before both release rules, because the first matching rule wins. The
resource names match the file extensions, so one rule can build both paths:
- type: nexus.uploader.transfer.config.ocm.software/v1alpha1
match: resource.access.isType("LocalBlob") && resource.name in ["jar", "pom"] && resource.version.endsWith("-SNAPSHOT")
url: https://nexus.example.com
repository: maven-snapshots
path: '${"com/example/demo/" + resource.version + "/demo-" + resource.version + "." + resource.name}'For credential and overwrite errors, see Troubleshooting.