How to: Java Bibliotheken auf Maven Central veröffentlichen – Ein Weg durch den Dschungel

Einleitung
Wer eine freie Java-Bibliothek entwickelt, kommt idealerweise irgendwann an den Punkt, dass die Software der Öffentlichkeit zur Verfügung gestellt werden kann. Für gewöhnlich ist das Maven Central Repository der richtige Ort dafür. Softwareentwickelnde können so über Maven, Gradle und Co. die Bibliothek als Softwarepaket bequem in ihre eigenen Projekte einbinden. Das Veröffentlichen eigener Softwarepakete ist aber leider nicht mit wenigen Mausklicks möglich.
„Die eine richtige“ Dokumentation zu finden, die erklärt, wie die Veröffentlichung genau durchzuführen ist, kann schwierig sein. Der wesentliche Grund dafür ist, dass sich die Vorgehensweise kürzlich grundlegend verändert hat, da es eine Umstellung von OSSRH auf Central Portal gab. So ist ein Großteil der auffindbaren Dokumentation veraltet oder aber neue Dokumentationsseiten verlinken auf alte und wirken somit inkonsistent.
Dieser Artikel soll Schritt für Schritt den Weg aufzeigen, wie eigene Software-Bibliotheken auf dem Maven Central Repository veröffentlicht werden können.
Namespace bei Sonatype reservieren
Alle Softwarepakete, die über Maven zur Verfügung gestellt werden, gehören zu einem Namespace. Der Namespace (oder auch groupId) ist eine Domäne, die im Verantwortungsbereich des Publizierenden liegt. Das kann eine Web-Präsens sein, wie z.B. „de.winterium“ für die Webseite http://www.winterium.de, oder ein Account, wie z.B. „io.github.winterrifier“ für den Github-Account „github.com/winterrifier“.
Um einen Namespace für sich beanspruchen zu können, muss zunächst ein Account unter https://central.sonatype.com/ angelegt werden.

Es ist zudem eine Überlegung wert, ob man dafür einen bereits bestehenden Github-Account als Login verwenden möchte. Der Vorteil wäre die automatische Reservierung des zugehörigen Namespace. Andernfalls ist eine manuelle Verifikation erforderlich, wie sie im Folgenden demonstriert wird.
Verifikation des Namespace
Nach dem Login kann über den Menüpunkt „View Namespaces“ der entsprechende Verwaltungsbereich betreten und anschließend der „Register New Namespace“ Knopf gedrückt werden.


Möglicherweise weist die Webseite bereits zuvor darauf hin, dass noch kein Namespace angelegt wurde und bietet eine entsprechende Abkürzung an.
Im anschließenden Dialogfenster kann nun der zu reservierende Namespace eingetragen werden. Liegt keine Web-Präsenz zum Projekt vor, bietet sich der Account eines Code Hosting Service, wie z.B. Github, an. Aus dem Github-Account „winterrifier“ ergibt sich dann beispielsweise der Namespace „io.github.winterrifier“.
Besteht aber, wie in diesem Beispiel, eine Web-Präsenz, so entspricht der Namespace der Domain-Bezeichnung, allerdings in absteigender Ordnung. Aus der Web-Präsenz „https://underdocx.org“ wird beispielsweise der Namespace „org.underdocx“.

Nach der Bestätigung mittels „Submit“ wurde der Namespace angelegt, ist aber noch nicht bestätigt.

Nun gilt es zu beweisen, dass die Domaine oder der Account wirklich der angemeldeten Person gehört und sie administrativen Zugriff darauf besitzt. Sonatype erzeugt dazu für den noch unbestätigten Namespace einen Verification Key. Für die Web-Präsenzen muss nun ein DNS TXT Eintrag erstellt werden, der den Verification Key enthält. Wie das zu bewerkstelligen ist, hängt vom Anbieter der Domain ab. Einige Anbieter besitzen eine Web-Oberfläche, um bequem neue DNS TXT-Einträge hinzuzufügen.

Für einen Code Hosting Service, wie z.B. Github muss hingegen ein öffentliches Repository erzeugt werden, dessen Name dem Verification Key entspricht. Dieses Repository kann nach der Verifizierung wieder entfernt werden.
Die Veröffentlichung des DNS-Eintrages und die Verifikation des Namespaces können einige Zeit dauern. Solange befindet sich der Namespace im Zustand „Verification Pending“.

Treten keine Fehler auf, so wechselt der Namespace-Zustand automatisch in „Verified“. Ab dann ist die Veröffentlichung von Bibliotheken unter diesem Namespace möglich.

Token generieren
Um später Software-Pakete über Maven hochladen zu können, muss ein Token zur Authentifizierung erzeugt und in die settings.xml von Maven eingetragen werden. Ein Klick auf den „Generate User Token“ Knopf im Account-Bereich, stößt die Generierung eines neuen Tokens an.


Es ist jederzeit möglich, einen neuen Token zu erzeugen, allerdings verlieren dadurch frühere Tokens ihre Gültigkeit. Entsprechend wird vor der Generierung des Tokens eine entsprechende Warnung ausgegeben.

Nach der Bestätigung erscheint ein Dialog mit den neu generierten Token-Daten. Die Daten sind persönlich und müssen geheim gehalten werden. Der Knopf „Copy to Clipboard“-Button kopiert den geheimen Benutzernamen und das Passwort in den Zwischenspeicher. Das ist hilfreich, denn Sonatype wird diese Daten nach einer Minute ausblenden und niemals wieder anzeigen.

settings.xml einrichten
Die settings.xml ist die Konfigurationsdatei für Maven. Sie befindet sich für gewöhnlich im „conf“-Ordner der Maven-Installation. Der zuvor im Zwischenspeicher abgelegte Token kann nun in die settings.xml eingefügt werden. Als „id“ wird in diesem Beispiel „central“ verwendet. Die settings.xml-Datei sollte in etwa wie folgt aussehen:
<server> <id>central</id> <username>????</username> <password>?????????????????????</password> </server>
pom.xml einrichten (Teil 1)
Die pom.xml muss alle Daten zum Bauen des Projekts, sowie zur Veröffentlichung der Bibliothek enthalten.
Basisdaten
In der Regel wurden die folgenden Basisdaten bereits bei der Erstellung des Projekts in die pom.xml eingetragen.

Lizenz
Über das XML-Element „licenses“ werden die Lizenzen des Projekts definiert. Der Eintrag für die MIT Lizenz muss dabei wie folgt aussehen:
<licenses> <license> <name>MIT License</name> <url>http://www.opensource.org/licenses/mit-license.php</url> </license> </licenses>
Eine Alternative könnte die Apache V2.0 Lizenz sein:
<licenses> <license> <name>The Apache License, Version 2.0</name> <url>http://www.opensource.org/licenses/mit-license.php</url> </license> </licenses>
Informationen zu den Entwickelnden
Alle beteiligten Entwickler können über das -Element aufgeführt werden
<developers> <developer> <name>Gerald Winter</name> <url>info@underdocx.org</url> </developer> </developers>
Source Control Management
Über wird das zugehörige Repository des Projekts adressiert. Je nach Quelle des Codes kann sich die Deklaration unterscheiden. Im folgenden Beispiel wird das öffentliche Github-Repository von „underdocx“ referenziert, weitere Beispiele sind unter [1] zu finden:
<scm> <connection>scm:git:git://github.com/winterrifier/underdocx.git</connection> <developerConnection>scm:git:git://github.com/winterrifier/underdocx.git</developerConnection> <url>https://github.com/winterrifier/underdocx/tree/main</url> </scm>
GPG einrichten
Um die Einrichtung der pom.xml abschließen zu können, muss zuvor mit Hilfe von GPG ein Schlüsselpaar (ein öffentlicher und ein geheimer Schlüssel) erstellt und der öffentliche Schlüssel registriert werden. Dies ermöglicht die digitale Signatur der hochzuladenden Ressourcen. Dazu sollte zunächst von https://www.gnupg.org die Software GnuPG auf dem System installiert werden.
Um ein Schlüsselpaar zu generieren, muss in der Konsole das folgende Kommando aufgerufen werden:
gpg --gen-key
GnuPG fragt anschließend nach dem Benutzernamen, einer Email-Adresse und einem sicheren Passwort, das später für alle weiteren GPG-Operationen verwendet werden muss.

Nach erfolgreicher Erstellung des Schlüsselpaares wird die Key-ID (hier grün markiert) ausgegeben.
Zur Registrierung des öffentlichen Schlüssels muss schließlich noch das folgende Kommando eingegeben werden, wobei durch die gerade ausgegebene Key-ID zu ersetzen ist:
gpg --keyserver keyserver.ubuntu.com --send-keys <KEY_ID>
pom.xml einrichten (Teil 2)
Maven PGP Plugin
Die digitale Signatur der Software erfolgt über das Maven GPG Plugin, das wie unten dargestellt, in das -Element der pom.xml einzutragen ist. Im Element muss die zuvor generierte Key-ID eingetragen werden.
<plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <version>3.2.7</version> <executions> <execution> <id>sign-artifacts</id> <phase>verify</phase> <goals> <goal>sign</goal> </goals> </execution> </executions> <configuration> <keyname>--- Hier die Key-Id einfügen ---</keyname> </configuration> </plugin> ... </plugins>
Maven Publishing und Maven Source Plugin
Die beiden folgenden Plugins ermöglichen schließlich das Veröffentlichen der Bibliothek und können ohne Modifikation übernommen werden. Wichtig ist, dass die „publishingServerId“ der Id in der settings.xml-Datei entspricht.
<plugins> ... <plugin> <groupId>org.sonatype.central</groupId> <artifactId>central-publishing-maven-plugin</artifactId> < artifactId>central-publishing-maven-plugin</artifactId > <extensions>true</extensions> <configuration> <publishingServerId>central</publishingServerId> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.2.1</version> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar-no-fork</goal> </goals> </execution> </executions> </plugin> ... </plugins>
Bereit zum „Publishen“?
Die pom.xml sollte nun vollständig konfiguriert sein. Durch das folgende Kommando wird das Projekt gebaut, signiert und zu Maven Central hochgeladen
mvn clean deploy
Wenn alles erfolgreich gelaufen ist, muss die Bibliothek nur noch veröffentlicht werden. Das passiert genau dort wo alles angefangen hat, auf https://central.sonatype.com/. Unter „View Deployments“ sollte das zuvor hochgeladene Paket im Zustand „Validated“ stehen.

Durch den Klick auf „Publish“ wird das Paket veröffentlicht. Dieser Vorgang kann einige Minuten in Anspruch nehmen.

Das grüne Label „Published“ signalisiert die erfolgreiche Veröffentlichung.

Andere Software-Projekte können von nun an die neue Bibliothek bequem einbinden. Sonatype liefert dazu die Möglichkeit, die passenden Snippets zu kopieren um sie in das eigene Projekt hinzuzufügen, wie hier zum Beispiel für Gradle.

Links
[1] Sonatype Dokumentation https://central.sonatype.org/publish/requirements/
[2] Astha Singh: Publish Java Library on Maven Central Via the Central Portal https://astha-singh.medium.com/publish-java-library-on-maven-central-via-the-central-portal-1e951952084f
[3] Underdocx https://underdocx.org

Softwareentwicklung