Publish a generated Java SDK to Maven Central through the Central Publisher Portal, not the old OSSRH Jira/Nexus flow — OSSRH reached end of life and shut down on 2025-06-30. The current path: verify your namespace at central.sonatype.com, sign every artifact with GPG, include a sources jar and a javadoc jar alongside your main jar, then upload through the Maven or Gradle plugin, a bundle upload, or the Publisher API. Validation runs automatically and takes a few minutes; once a version is published, Sonatype's policy is that you cannot remove, update, or modify it — publish a new version instead.
If you're still finding OSSRH instructions, skip them
Any guide that mentions s01.oss.sonatype.org, oss.sonatype.org, filing a Jira ticket for a new group ID, or the old Nexus staging repository UI is describing a process that no longer exists for new work. Sonatype's OSSRH sunset notice confirms OSSRH "has reached end of life and has been shut down" as of 2025-06-30. If you have an existing OSSRH account, your namespace was migrated to the Central Publisher Portal automatically — sign in at central.sonatype.com with your existing credentials and generate a new Portal user token rather than reusing an old OSSRH one.
What the Central Publisher Portal needs
| Requirement | Detail |
|---|---|
| Namespace | A verified group ID — usually a domain you control (com.example) or your GitHub-based namespace (io.github.username), verified via DNS TXT record or a GitHub repo check |
| Signing | Every artifact (jar, sources jar, javadoc jar, POM) signed with GPG |
| Artifacts per version | Main jar, -sources.jar, -javadoc.jar, and the POM with required metadata (name, description, URL, license, developer, SCM info) |
| Upload method | Maven plugin, Gradle plugin, direct bundle upload (a zip you build yourself), or the Publisher API |
| Validation | Automatic, "should not take more than a few minutes" per Sonatype's own docs — failures can be fixed and resubmitted |
| Immutability | Published versions cannot be removed, updated, or modified — ship a new version for any fix |
Publishing a generated SDK: the sequence
A generated Java SDK from OpenAPI Generator or another tool needs the same four pieces any Maven Central artifact needs — the difference is where they come from.
1. Verify your namespace once
Before your first publish, verify ownership of the group ID you'll publish under at central.sonatype.com. A domain-based namespace (com.yourcompany) needs a DNS TXT record; a io.github.yourorg namespace needs a public repo under that GitHub org. This is a one-time step per namespace, not per release.
2. Configure your generator to emit sources and javadoc
Most Java generators (including OpenAPI Generator's java target) can be configured to produce a sources.jar and wire up javadoc generation via Maven's maven-source-plugin and maven-javadoc-plugin, or Gradle's java-library plugin with withSourcesJar() / withJavadocJar(). Maven Central rejects a bundle missing either jar, so confirm your build produces all three artifacts before you ever try to publish.
3. Set up GPG signing in CI
Generate a GPG key pair, publish the public key to a keyserver, and store the private key plus passphrase as CI secrets. Both the Maven and Gradle publish plugins have a signing step (maven-gpg-plugin, or Gradle's built-in signing plugin) that signs every artifact in the bundle before upload.
4. Publish via the plugin or the API
A minimal GitHub Actions job for a Maven project:
name: Publish to Maven Central
on:
workflow_dispatch:
inputs:
version:
required: true
type: string
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
- name: Import GPG key
run: echo "${{ secrets.GPG_PRIVATE_KEY }}" | gpg --batch --import
- name: Deploy
env:
SONATYPE_TOKEN: ${{ secrets.SONATYPE_PORTAL_TOKEN }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: mvn -B deploy -Dgpg.passphrase="$GPG_PASSPHRASE"
The central-publishing-maven-plugin (Sonatype's own Maven plugin for the Portal) handles the upload and can be configured for automatic release after validation passes, or held for a manual publish step — the same "preview, then approve" shape you'd want for any generated artifact you haven't hand-reviewed.
5. Confirm, then treat every published version as permanent
Once validation passes and the version releases, it's on Maven Central and cannot be edited or deleted. Run one full dry cycle against a throwaway namespace or a 0.0.1-SNAPSHOT-style pre-release before you point this workflow at a real customer-facing package version.
Generating the Java SDK itself
This post assumes you already have a Java SDK to publish. If you don't yet, OpenAPI Generator is the default option covered in Generate a Java SDK from OpenAPI — that post compares generators; this one picks up once you have a buildable jar and need it on Maven Central.
Where Sourced fits
Sourced generates a preview Java SDK from your OpenAPI spec — it's a Scale-plan feature: pick Java in your project's language picker and Sourced runs the generation and packaging step for you, no local JVM or generator setup required. What Sourced doesn't do yet is run the Maven Central publish step above — namespace verification, GPG signing, and the Portal upload are still something you do yourself, using the sequence in this post, for the Java preview SDK same as for a jar you generated any other way. TypeScript and Python are the two fully managed languages today, with publishing handled end to end; Java joins that tier once registry publish automation ships for it.
Whichever way you generate the Java client, the OpenAPI spec behind it still needs validating and documenting. Validate your spec before codegen — a spec issue that breaks Java codegen breaks docs generation too — and create hosted docs from your repo or start free to get docs, llms.txt, and SDK previews from the same spec, no credit card required.
FAQ
Is OSSRH really gone, or can I still use it for an existing project?
It's gone for everyone. Sonatype's own notice states OSSRH "has reached end of life and has been shut down" as of 2025-06-30. Existing OSSRH accounts were migrated to the Central Publisher Portal; there's no path back to the old Nexus staging flow.
Do I need a domain to publish to Maven Central?
No. A io.github.yourusername namespace, verified against a public GitHub repository you control, is a valid alternative to a domain-based group ID and is the common choice for individual maintainers and smaller projects.
What happens if I publish a bad version by mistake?
You can't remove or overwrite it — Sonatype's policy on the Central Publisher Portal is that published versions are immutable. Publish a corrected version with a new version number; this is exactly why a dry run against a throwaway namespace or pre-release version matters before your first real publish.
Can I automate the whole publish with no manual approval step?
Technically yes — central-publishing-maven-plugin supports automatic release after validation. Whether you should is a different question: a generated SDK can pass validation and still have wrong method names or a bad README example, so most teams gate the final publish behind a manual approval even when the mechanics are automated.
Does Sourced publish my generated Java SDK to Maven Central for me?
Not yet. Sourced generates the Java SDK as a Scale-plan preview (download, don't publish automatically); you run the Maven Central publish sequence in this post yourself. TypeScript and Python get end-to-end managed publishing today.
Get hosted docs and SDK previews from your OpenAPI spec, or start free — unlimited previews, no credit card required.