Über unsMediaKontaktImpressum
Marco Schulz 07. September 2021

Artefakte auf Maven Central veröffentlichen

Wenn Sie ein Open-Source-Projekt betreiben, genügt es nicht, den Sourcecode auf einer Plattform wie GitHub zu veröffentlichen und dann darauf zu warten, dass die eigene Arbeit in der Öffentlichkeit Beachtung findet. Vor langer Zeit mag es auch noch ausreichend gewesen sein, die Binaries auf der eigenen Homepage zum Download zur Verfügung zu stellen. Heute sind Sie da schon etwas mehr gefordert. Ein Weg, um Ihr Projekt einer großen Öffentlichkeit zugänglich zu machen, ist die Bereitstellung Ihrer Java-Artefakte auf der Open-Source-Plattform Maven Central.

Umgebungen wie npm für JavaScript und NuGet für .NET betreiben wiederum eigene Hosting-Dienste, auf denen Sie Ihre Pakete ebenfalls öffentlich ablegen können. Informieren Sie sich bei Bedarf konkret, was Sie tun müssen, um Artefakte auf diese Plattformen zu bringen.

Bevor Sie mit der gesamten Prozedur beginnen, sollten Sie sich vergewissern, dass Ihr Projekt bereits einen Status erreicht hat, der für Nutzer genügend Funktionalität bereitstellt, damit diese auch einen Grund haben, es zu verwenden. Und außerdem sollte es auch möglichst fehlerfrei und sicher sein. Zur Vorbereitung benötigen Sie für Ihr Artefakt eine eindeutige und nicht verwechselbare GroupID. Wenn Sie diese nach dem Vorbild de.myCompany anlegen wollen, müssen Sie nachweisbar Eigentümer der Domäne myCompany.de sein. Können Sie diesen Nachweis nicht erbringen, wird die Veröffentlichung Ihres Artefakts unter der von Ihnen ausgesuchten GroupID verweigert.

Wenn Sie keine eigene Domäne besitzen, dafür aber den Sourcecode für das Projekt bereits in einem GitHub-Repository veröffentlichen, gestattet Maven Central es Ihnen, die GroupID nach dem Schema io.github.<Repository> zu beantragen.

Diese Maßnahmen stellen sicher, dass es zu keinem Missbrauch der Maven-GAV-Parameter kommt. Betrüger können dadurch nicht die Domäne eines populären Open-Source-Projekts für ihre eigenen Interessen ausnutzen. Wenn Sie eine GroupID gefunden haben, die für Sie funktioniert, sind noch folgende Schritte zu erledigen:

  1. Stellen Sie sicher, dass die Einträge der Maven-POM die Anforderungen an eine Veröffentlichung auf Maven Central erfüllen.
  2. Erstellen und veröffentlichen Sie eine gültige GPG-Signatur.
  3. Erzeugen Sie folgende mit GPG signierte Artefakte: pom.xml, project.jar, project-sources.jar und project-javadoc.jar.
  4. Beantragen Sie bei Sonatype einen Upload-Account für Maven Central.
  5. Laden Sie die Artefakte hoch, und validieren und veröffentlichen Sie diese.

Nachdem Sie nun den groben Fahrplan für eine Veröffentlichung auf Maven Central kennen, kümmern wir uns direkt um die Details. Beginnen wir mit dem einfachsten Schritt, und erstellen wir eine vollständige pom.xml:

Listing 1: Eine POM für die Veröffentlichung auf Maven Central (chapter11.4/pom.xml):

00: <?xml version="1.0" encoding="UTF-8"?>
01: <project
02:    xmlns="http://maven.apache.org/POM/4.0.0"
03:    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04:    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
05:                        http://maven.apache.org/xsd/maven-4.0.0.xsd">
06:    <modelVersion>4.0.0</modelVersion>
07:    <name>smaple</name>
08:    <description>Sample project pom fpr publisching on Maven 
                    Central.</description>
09:    <inceptionYear>2021</inceptionYear>
10:    <url>https://enrebaja.wordpress.com</url>
11:    <groupId>io.github.myProject</groupId>
12:    <artifactId>project</artifactId>
13:    <version>1.0.0</version>
14:    <packaging>jar</packaging>
15:    <scm>
16:        <connection>scm:git:https://github.com/ElmarDott/TP-
                                                  CM.git</connection>
17:        <developerConnection>scm:git:file://media/veracrypt1/
           repositories/git-togetherPlatform/Modules/CM</developerConnection>
18:        <url>scm:git:https://github.com/ElmarDott/TP-CM.git</url>
19:    </scm>
20:    <developers>
21:        <developer>
22:            <id>lead</id>
23:            <name>Elmar Dott</name>
24:            <roles>
25:               <role>Build Manager</role>
26:            </roles>
27:            <email>elmar.dott@gmail.com</email>
28:        </developer>
29:    </developers>
30:    <licenses>
31:        <license>
32:            <name>Apache License 2.0</name>
33:            <url>https://www.apache.org/licenses/LICENSE-2.0</url>
34:        </license>
35:    </licenses>
36:    <build>
37:        <plugins>
38:            <plugin>
39:                <groupId>org.apache.maven.plugins</groupId>
40:                <artifactId>maven-jar-plugin</artifactId>
41:                <version>3.2.0</version>
42:            </plugin>
43:            <plugin>
44:                <groupId>org.apache.maven.plugins</groupId>
45:                <artifactId>maven-source-plugin</artifactId>
46:                <version>3.2.1</version>
47:                <executions>
48:                    <execution>
49:                        <phase>package</phase>
50:                        <goals>
51:                            <goal>jar-no-fork</goal>
52:                            <goal>test-jar-no-fork</goal>
53:                        </goals>
54:                    </execution>
55:                </executions>
56:            </plugin>
57:            <plugin>
58:                <groupId>org.apache.maven.plugins</groupId>
59:                <artifactId>maven-javadoc-plugin</artifactId>
60:                <version>3.2.0</version>
61:                <executions>
62:                    <execution>
63:                        <id>attach-javadocs</id>
64:                        <goals>
65:                            <goal>jar</goal>
66:                        </goals>
67:                    </execution>
68:                </executions>
69:            </plugin>
 
70:            <plugin>
71:                <groupId>org.apache.maven.plugins</groupId>
72:                <artifactId>maven-gpg-plugin</artifactId>
73:                <version>1.6</version>
74:                <executions>
75:                    <execution>
76:                        <id>sign-artifacts</id>
77:                        <phase>verify</phase>
78:                        <goals>
79:                            <goal>sign</goal>
80:                        </goals>
81:                    </execution>
82:                </executions>
83:                <configuration>
84:                    <keyname>myKey</keyname>
85:                    <passphraseServerId>${gpg.phassphrase} 
                       </passphraseServerId>
86:                </configuration>
87:            </plugin>
88:        </plugins>
89:    </build>
90: </project>

Um ein erfolgreiches Deployment nach Maven Central durchzuführen, müssen Sie zuerst sicherstellen, dass die Informationen aus Listing 1 bis einschließlich Zeile 35 vollständig und korrekt in jeder Projekt-POM enthalten sind, die Sie nach Maven Central bringen wollen.

Den Eintrag groupId aus Zeile 11 habe ich bereits erläutert. Hierzu aber noch ein kleiner Hinweis: Auch wenn es in den meisten Fällen sehr praktisch ist, dass die Java-Package-Pfade mit der Maven-GroupId übereinstimmen, ist das nicht zwingend vorgegeben. Sie müssen also Ihre Codebasis nicht umstellen, falls Sie hier nicht der Sonatype-Vorgabe gefolgt sind.

Sehr wichtig ist der Eintrag zur Lizenz in den Zeilen 30 bis 35. Auch wenn es Ihnen gleichgültig ist, was die Nutzer mit Ihrem Code anstellen, wird die Lizenz in Deutschland benötigt, da das Urheberrecht greift. Sie haben in diesem Fall juristisch zwei Optionen: Entweder übertragen Sie das Urheberrecht auf eine dritte Person oder Sie vergeben eine sehr weit gefasste Lizenz. Da ich selbst sehr von Open Source überzeugt bin und wenig von Restriktionen halte, verwende ich für meine Projekte üblicherweise die Apache-2.0-Lizenz. Das gestattet auch kommerziellen Projekten eine freie Verwendung. Alternativ können Sie auch Lizenzen aus dem GPL-Universum verwenden.

Lizenzen für Open-Source-Projekte

Es mag lästig und kompliziert sein, sich mit den unterschiedlichen Lizenzen für Softwareprojekte zu beschäftigen, aber es ist leider unumgänglich, wenn Sie möchten, dass Ihre Programme von anderen genutzt werden können. Eine gute erste Anlaufstelle ist das Informationsmaterial des ifrOSS (Institut für Rechtsfragen der Freien und Open Source Software) [1].

Alle diese Anforderungen können Sie auch im offiziellen OSS-Sonatype-Guide nachlesen [2].

Die ab Zeile 36 eingetragenen Plug-ins benötigen Sie, um die drei Artefakte sources.jar, javadoc.jar und project.jar zu erzeugen und zu signieren. Wie Sie eine Signatur erstellen und verwenden, wird uns als Nächstes beschäftigen.

Java-Artefakt mit Maven signieren

Um eine Signatur erstellen zu können, benötigen Sie das freie Konsolenwerkzeug GnuPG [3]. Eine detaillierte Installationsanleitung, die für Ihr Betriebssystem passt, finden Sie auf der GPG-Homepage. Wenn Ihre Installation geglückt ist, erhalten Sie nach Eingabe von gpg –-version eine Ausgabe wie in Abb. 1 und können mit dem Erstellen des Schlüsselpaars beginnen.

Um ein Schlüsselpaar zu erzeugen, benötigen Sie den Befehl gpg --gen-key und folgen den Anweisungen im Konsolenfenster. Nach Beendigung des Vorgangs überprüfen Sie das Ergebnis mit gpg --list-keys. Die Ausgabe ist in etwa wie folgt:

ed@elmar-dott:~$ gpg --list-keys
/home/ed/.gnupg/pubring.kbx
---------------------------
pub   rsa2048 2019-11-10 [SC]
      3F7CC7E99FCEBC9C150070198A4AD8DFED275F75
uid   [unknown] togetherPlatform (for OSS publishing) <elmar.dott@gmail.com>
sub   rsa2048 2019-11-10 [E]

Als nächsten Schritt machen Sie Ihre Signatur öffentlich bekannt. Dafür existieren Server, auf denen die öffentlichen Schlüssel abgelegt werden (Achten Sie strikt darauf, Ihren privaten Schlüssel sicher aufzubewahren. Ich empfehle das Programm KeePassX. Um Ihren Public Key öffentlich bekannt zu machen, tippen Sie Folgendes in die Kommandozeile:

gpg --keyserver hkp://pool.sks-keyservers.net --send-keys 3F7CC7E99FCEBC9C150070198A4AD8DFED275F75

Die Zahlenkette für den Parameter send-keys entnehmen Sie dem Eintrag pub aus der Ausgabe der Schlüssel.

Nach diesem kurzen Exkurs zur Schlüsselerzeugung kehren wir zu Listing 1 zurück. Wenn Sie anstelle von Maven andere Build-Werkzeuge einsetzen, finden Sie bei Sonatype weitere Informationen [4].

Konkret geht es um die beiden Zeilen 84 und 85 aus Listing  1. Gewiss werden hier die Informationen Ihres Signaturpassworts nicht für jedermann lesbar auf GitHub veröffentlicht. Also schauen wir uns einmal genauer an, wie es zu den Einträgen keyname und passphraseServerId gekommen ist. Der Wert für keyname entspricht Ihrer Schlüssel-ID, was in der Schlüsselausgabe oben unter der Zeile uid zu finden ist. Für die passphrase hilft uns die Maven-settings.xml weiter. Dort finden Sie einen Eintrag ähnlich wie in Listing 2:

Listing 2: Die Maven-settings.xml

</profiles>
    <profile>
      <id>env-vars</id>
      <properties>
               <gpg.phassphrase>passwort</gpg. phassphrase >
     </properties>
    </profile>
</profiles>
<!-- List of profiles that are active for all builds. -->
<activeProfiles>
    <activeProfile>env-vars</activeProfile>
</activeProfiles>

In der settings.xml wird das Profil env-vars mit der Property gpg.phassphrase angelegt. Der hier eingetragene Wert ist das Passwort Ihres Schlüsselpaars. Solange Sie sicherstellen können, dass keine unautorisierte Person Zugriff auf Ihre settings.xml hat, können Sie das Passwort im Klartext dort hineinschreiben.

Wenn Sie nun einen Build ausführen, finden Sie im target-Verzeichnis zusätzlich zu den erzeugten Dateien die signierten Varianten. Wenn Sie diese Prozedur erfolgreich gemeistert haben, ist es Zeit, im Managementsystem Jira von Sonatype einen Account zu beantragen [5]. Klicken Sie auf den Link Sign up, und Sie gelangen zum Registrierungsformular. Bei erfolgreichem Abschluss der Registrierung erhalten Sie eine Bestätigungs-E-Mail und können sich nun am Jira-Ticketsystem anmelden.

Die Anmeldeinformation

Nachdem Sie auch diesen Schritt erfolgreich hinter sich gebracht haben, eröffnen Sie nun ein Ticket, in dem Sie Ihr Anliegen schildern, Zugang zu Maven OSS Nexus erhalten zu wollen. Zuerst klicken Sie auf die Schaltfläche Create (s. Abb. 2).

In dem Pop-up, das sich nun öffnet, wählen Sie als Projekt Community Support | Open Source Project Repository Hosting (OSSRH) aus, falls es nicht bereits eingestellt ist. Der einzustellende Issue Type lautet New Project. Nehmen Sie sich Zeit und seien Sie möglichst genau beim Ausfüllen des Formulars. Die meisten Felder sind selbsterklärend oder enthalten ein gut verständliches Beispiel. Leider kommen Sie nicht umhin, die Felder Summary und Description in Ihrem Antrag in englischer Sprache auszufüllen. Wenn Sie sich in der Sprache nicht so sicher fühlen, brauchen Sie keine Angst zu haben. Solange Sie sich kurzfassen und klar rüberkommt, was Sie wollen, kümmert sich niemand um Ausdruck oder Grammatikfehler.

Ein Beispiel als Ausfüllungshilfe:

  • Summary: Publishing my project XYZ to Maven Central.
  • Description: XYZ is a Multi Modul Project. The GroupId of all uploaded artifacts is similar to the GitHub Project Domain. It contains 3 artifacts and a separate parent POM. The first Release is already prepared and I wish to publish this on Maven Central.
  • GroupId: io.github.XYZ
  • Project URL: Wenn keine eigene Homepage für das Projekt vorhanden ist, ist dies die gleiche URL wie das SCM.
  • SCM URL: https: //github.com/XYZ.
  • Username(s): Der Account-Name, mit dem Sie das Ticket anlegen.

Wenn Sie alles ausgefüllt haben, können Sie das Formular abschicken. Sobald das Ticket bearbeitet wurde, werden Sie benachrichtigt. Lesen Sie die Benachrichtigung sehr sorgfältig: Manchmal gibt es Beanstandungen, die Sie korrigieren können. Wenn Sie nicht auf Beanstandungen reagieren, wird aber irgendwann das Ticket geschlossen und Ihr Antrag abgelehnt. Sobald Sie nun die Nachricht erhalten haben, dass für Ihre GroupId ein Repository eingerichtet wurde, können Sie auch schon mit dem Hochladen beginnen. Sollten Sie Artefakte mit einer anderen GroupId hochladen wollen, wird Ihnen das nicht gelingen. Der OSS Nexus hat hierfür einen Validator und lehnt nicht-konforme Artefakte oder unvollständige Uploads ab.

Sie können sich mit dem angelegten Jira-Login anmelden [6]. Sie benötigen keine weitere Registrierung. Um die Artefakte hochzuladen, wechseln Sie nach dem erfolgreichen Login auf den Menüpunkt Staging Upload.

Ich verwende für mein Projekt immer den Upload-Modus Artifact(s) with a POM (s. Abb. 3), so bleibt es mir erspart, jedes Mal die notwendigen GAV-Parameter einzutragen.

Die Projekt-POM wird über den Button Select POM to Upload hochgeladen. Anschließend dürfen Sie der Reihe nach alle Artefakte inklusive der Signaturen auswählen und hochladen. Nach jedem Upload müssen Sie auf den unscheinbaren Button Add Artifact klicken, damit die Datei in der Artifacts-Liste erscheint. In das Feld Description tragen Sie einen Kommentar für sich ein. Wenn Sie das alles geschafft haben, klicken Sie auf den Button Upload Artifact(s). Ihr Upload wird nun validiert und dann können Sie das Deployment finalisieren. Unter dem Menüpunkt Staging Repositories geht es nun weiter. Hier erscheint jetzt Ihr Upload (s. Abb.4).

Wenn die Validierung nichts zu beanstanden hat, ist die Schaltfläche Release aktiv und Sie können den letzten Schritt mit einem Klick auf diesen Button beenden.

Erfahrungsgemäß läuft die Übernahme der Artefakte nach Maven Central über Nacht. Am nächsten Morgen sollten Ihre Dateien über die Suche nach der GroupId auf der Webseite erscheinen [7]. Auch wenn es anfänglich etwas kompliziert erscheint, ist eine Veröffentlichung der Binärdateien Ihres Projekts auf Maven Central keine Raketenwissenschaft und mit überschaubarem Aufwand umzusetzen.

Der Artikel ist ein Auszug aus dem Buch...

Continuous Integration mit Jenkins – Das Handbuch für Entwickler und DevOps-Teams. Mit vielen Best Practices und Tipps für gutes Software Engineering
Marco Schulz, 400 Seiten, 2021, gebunden, Rheinwerk Computing, ISBN 978-3-8362-7834-8

Quellen
  1. Informationsmaterial des ifrOSS (Institut für Rechtsfragen der Freien und Open Source Software): Welches sind die wichtigsten Open Source Lizenzen und welchem Lizenztyp gehören sie an?
  2. Sonatype: Requirements
  3. GnuPG: Download
  4. Sonatype: GPG
  5. Sonatype: Login
  6. nexus repository manager
  7. Sonatype: Search

Autor
© Marco Schulz

Marco Schulz

Marco Schulz realisiert seit über fünfzehn Jahren für namhafte Unternehmen auf unterschiedlichen Plattformen umfangreiche Webapplikationen. Er ist freier Consultant, Trainer und Autor verschiedener Fachartikel.
>> Weiterlesen
Kommentare (0)

Neuen Kommentar schreiben