# Release Kandidaten mit Maven bauen



## einbyte (14. Nov 2014)

Hi,

wie baut man Release Kandidaten, also Pakete, die nach einem Freigabeprozess zu Kunden sollen, mit Maven?
Die müssen unter anderem reproduzierbar sein, d.h. irgendjemand muss irgendwann die gleichen Sourcen nehmen und daraus das gleiche Paket bauen können.
Wir haben jetzt aus der Not herraus Maven auf ein file:// repository konfiguriert, was mit in der Versionsverwaltung steckt. Durch die komplexen unterschiedlichen Abhängigkeiten werden viele viele Jars in verschiedenen Versionen genutzt (die haben wir mehr oder weniger händisch in das Repository aufgenommen). Das ist alles sehr unübersichtlich, instabil und unübersichtlich.
Ich hab schon viel gegoogelt, aber irgendwie kein gutes "HOWTO build productive stuff with Maven" gefunden.

Wie macht man es richtig?

~/1b


----------



## Ruzmanz (15. Nov 2014)

Der Idealfall:
- Abhängigkeiten mit groupId, artifactId und version angeben
- Abhängigkeiten von Maven Central Rep. etc. automatisch laden
- Projekt mit diesen Abhängigkeiten bauen
[- Nur die POM.xml wird ins Git-Repository gepackt]



> viele viele Jars in verschiedenen Versionen genutzt (die haben wir mehr oder weniger händisch in das Repository aufgenommen).



Was ist das "Repository"? Das "Maven-Repository" oder das "Git-Repository" (CVS, SVN, ...)? Warum habt ihr die händisch aufgenommen?

Ich (privat) packe die JAR-Files und die POM.xml immer mit ins Git, sofern es kein Online-Maven-Repository gibt. Im Unternehmen mit anderen Backupstrategien etc. bietet sich auch ein firmeninternes Maven-Repository an: Maven


----------



## einbyte (17. Nov 2014)

Hallo,
danke für Deine schnelle Antwort!



Ruzmanz hat gesagt.:


> Der Idealfall:
> - Abhängigkeiten mit groupId, artifactId und version angeben
> - Abhängigkeiten von Maven Central Rep. etc. automatisch laden



Ja, die Abhängigkeiten sind in einer "Haupt-POM" mit Version angegeben (das bedeutet übrigens leider nicht, dass in jedem Fall die angegebenen Versionen und nur diese verwendet werden).

Das Maven Repository kann man natürlich nicht direkt nutzen:
Dann hätte man ja das gesamte Internet als Abhängigkeit!
Da kann keiner garantieren, dass man das in 10 Jahren (oder übermorgen) noch bauen kann...



Ruzmanz hat gesagt.:


> - Projekt mit diesen Abhängigkeiten bauen
> [- Nur die POM.xml wird ins Git-Repository gepackt]



Das Ergebnis muss reproduzierbar sein.
Das heißt, man nimmt eine wie auch immer geartete build-Umgebung (z.B. eine bestimmte virtuelle Maschine) und einen Source-Code-Stand (SCM Komponentenversion) und erhält immer wieder das gleiche Binärergebnis - egal, was sich im Internet ändert.

Daher müssen alle Abhängigkeiten (außer des Buildsystems selbst, weil man sich ja leider nicht aus den Haaren aus dem Sumpf ziehen kann) unter Versionskontrolle stehen.



Ruzmanz hat gesagt.:


> Was ist das "Repository"? Das "Maven-Repository" oder das "Git-Repository" (CVS, SVN, ...)? Warum habt ihr die händisch aufgenommen?



Das Maven-Repository.
Es gibt ein lokales, unter Versionskontrolle stehendes Verzeichnis mit den Eigenschaften, die ein Maven file Repository erfüllen muss. Maven darf nur dieses verwenden (weil Maven intern leider an aller forcierten Konfiguration vorbei hardkodierte URLs kennt und verwendet, besteht die Gefahr, dass man übersieht, wenn doch etwas aus dem Internet geladen wurde. Daher sollte ein Buildsystem grundsätzlich keine geeignete Online-Verbindung haben (z.B. firewalled)).



Ruzmanz hat gesagt.:


> Ich (privat) packe die JAR-Files und die POM.xml immer mit ins Git, sofern es kein Online-Maven-Repository gibt. Im Unternehmen mit anderen Backupstrategien etc. bietet sich auch ein firmeninternes Maven-Repository an: Maven



Genau. Wenn man so ein "firmeninternes Maven-Repository" zusätzlich projektabhänig und projektversionsabhängig macht, kann man reproduzierbar werden. 
Das ist genau was ich mit "ein file:// repository" meinte.

In dem Artikel sind übrigens Fehler, beispielsweise "external dependencies typically don't change, or if they do their filename changes anyway to indicate the new version". Das ist natürlich falsch, weil man keine Kontrolle über all diese Abhängigkeiten hat. Es können Fehler passieren, Server gehackt oder einfach irgendwann nicht mehr weiterbetrieben werden.

Beim Entwurf von Maven war Reproduzierbarkeit wohl leider keine Anforderung (ich finde im Netz dazu jedenfalls nichts), was mich schon ziemlich überrascht hat, weil u.A. Reproduzierbarkeit meiner Erfahrung nach eine Anforderung von vielen Freigabeprozessen ist. Daher meine Frage, wie man das am besten macht, ich bin ja bestimmt nicht der erste


----------



## kama (17. Nov 2014)

Hallo,



einbyte hat gesagt.:


> ... (das bedeutet übrigens leider nicht, dass in jedem Fall die angegebenen Versionen und nur diese verwendet werden).


Wie ist das zu verstehen? Wenn Du eine Version als dependency angibst dann wird genau auch die verwendet? Schildere mal das Problem genauer...



einbyte hat gesagt.:


> Das Maven Repository kann man natürlich nicht direkt nutzen:
> Dann hätte man ja das gesamte Internet als Abhängigkeit!
> Da kann keiner garantieren, dass man das in 10 Jahren (oder übermorgen) noch bauen kann...


Das mit Übermorgen wird funktionieren...mit großer Sicherheit auch noch wesentlich länger...bei 10 Jahren wäre ich auch vorsichtig...Aber genau für das Thema nutzt man einen Repository Manager...und macht davon selbstverständlich ein Backup...



einbyte hat gesagt.:


> Das Ergebnis muss reproduzierbar sein.
> Das heißt, man nimmt eine wie auch immer geartete build-Umgebung (z.B. eine bestimmte virtuelle Maschine) und einen Source-Code-Stand (SCM Komponentenversion) und erhält immer wieder das gleiche Binärergebnis - egal, was sich im Internet ändert.


 siehe Oben Repository Manager...



einbyte hat gesagt.:


> Daher müssen alle Abhängigkeiten (außer des Buildsystems selbst, weil man sich ja leider nicht aus den Haaren aus dem Sumpf ziehen kann) unter Versionskontrolle stehen.


. Die Abhängigkeit packt in einen Repository Manager...in ein Version Control gehören solche Artefakte schilcht nicht...
ABER Mann muss unbedingt sein Build System ins Version Control einchecken...und eben auch die genutzte VM (Betriebssystem).....Java was genutzt wird (JDK)...etc.



einbyte hat gesagt.:


> Das Maven-Repository.
> Es gibt ein lokales, unter Versionskontrolle stehendes Verzeichnis mit den Eigenschaften, die ein Maven file Repository erfüllen muss. Maven darf nur dieses verwenden (weil Maven intern leider an aller forcierten Konfiguration vorbei hardkodierte URLs kennt und verwendet, besteht die Gefahr, dass man übersieht, wenn doch etwas aus dem Internet geladen wurde. Daher sollte ein Buildsystem grundsätzlich keine geeignete Online-Verbindung haben (z.B. firewalled)).


 Das aus Deiner Sicht Maven an der forcierten Konfiguration vorbei geht sieht so aus, dass das nicht richtig ist was Du machst...zeig mal was du gemacht hast...Ein Maven Repository in eine Version Control einzuckecken macht keinen Sinn...wie sieht die settings.xml aus? 



einbyte hat gesagt.:


> Genau. Wenn man so ein "firmeninternes Maven-Repository" zusätzlich projektabhänig und projektversionsabhängig macht, kann man reproduzierbar werden.
> Das ist genau was ich mit "ein file:// repository" meinte.


Hier scheint mir, dass Du einige Grundlagen von Maven und Maven Repositories nicht verstanden hast...Ein Repository Projektabhängig und gar Versionsabhängig zu machen...macht nicht wirklich sinn...Das geht auch mit einem Repository Manager...



einbyte hat gesagt.:


> In dem Artikel sind übrigens Fehler, beispielsweise "external dependencies typically don't change, or if they do their filename changes anyway to indicate the new version". Das ist natürlich falsch, weil man keine Kontrolle über all diese Abhängigkeiten hat. Es können Fehler passieren, Server gehackt oder einfach irgendwann nicht mehr weiterbetrieben werden.


Die Kontrolle die man über die Abhängigkeiten hat nennt sich pom.xml in der eine Abhängigkeit über groupId, artifactId, version eindeutigt Identifiziert wird. Eine Version (in diesem Falle Releases) werden ansonsten nie geändert...
Die Frage ist  was Du mit Fehler passieren meinst? 
Um die Gefahr von Man in the Middle Attacken zu veringern wird seit August Maven Central mit SSL betrieben...weiterhin haben dazu alle Artefakt md5 und sha1 Prüfsummen....Das mit dem nicht mehr Betrieben werden ist eine Möglichkeit aber genau dafür sollte man eben einen eigenen Repository Manager Nutzen...Wenn dann Maven Central nicht mehr Verfügbar ist, bleibt das interne Repository und somit bleibt mein Build baubar...Server Hacking grundsätzlich ist nicht verhinderbar. Da aber die Adminstration der Maven Central in der Hand sehr begrenzten Zahl von Leute ist sehe ich das nicht wirklich ein Problem..



einbyte hat gesagt.:


> Beim Entwurf von Maven war Reproduzierbarkeit wohl leider keine Anforderung (ich finde im Netz dazu jedenfalls nichts), was mich schon ziemlich überrascht hat, weil u.A. Reproduzierbarkeit meiner Erfahrung nach eine Anforderung von vielen Freigabeprozessen ist. Daher meine Frage, wie man das am besten macht, ich bin ja bestimmt nicht der erste


Reporoduzierbarkeit bedeutet, dass ich heute etwas baue in einer Version z.B. 1.0 und das in drei Jahren auch wieder bauen kann....Das hat mit Freigabeprozessen überhaupt nichts zu tun...

Grundlegendes um einen Maven Build Reproduzierbar zu machen. Alle verwendeten Plugins mit ihrer Versionen festlegen..., einen Repository Managemer nutzen und selbstverständlich den Source und alle genutzten Pom Dateien einchecken...und wenn man hier Konsequent ist muss man sowohl Maven, genutztes JDK und in der absoluten Konsequenz auch das Betriebssystem einchecken...

Achso...einen Release Kandidaten baut man in Maven mit den maven-release-plugin...

Maven Release plugin - Introduction

Gruß
Karl Heinz Marbaise


----------



## einbyte (2. Dez 2014)

Hallo,

vielen Dank für Deine Antwort! Leider habe ich sie erst jetzt
gelesen, weil ich eine E-Mail-Notification erwartet hatte und
bisher gar nicht nachschaute.



kama hat gesagt.:


> Hallo,
> Wie ist das zu verstehen? Wenn Du eine Version als dependency angibst dann wird genau auch die verwendet? Schildere mal das Problem genauer...



Man schreibt packageA version=1.2.3 in sein pom.xml und erwartet,
dass genau und nur packageA-1.2.3 verwendet wird, stellt dann
aber fest, dass packageA-1.2.5 verwendet wird.
Bemerkt habe ich das, weil Maven firewalled ist und beim
Downloadversuch von
http://ein.repo.was.gar.nicht.konfiguriert.ist/.../packageA-1.2.5.tgz
hängt, bis es irgendwann ein Timeout gibt. packageA-1.2.3 gibt es
in meinem Repo, 1.2.5 nicht.

Irgendwo ist dokumentiert, dass es neben den konfigurierten
Repositories fest eingebaute "fall-backs" gibt, was ich aus Sicht
der Reproduzierbarkeit wirklich doof finde (wenn es "mein" Repo
nicht "gibt", weil es z.B. ausgefallen ist, soll es fehlschlagen,
nicht einfach irgendwas anderes nehmen, auch wenn dieses
"irgendwas andere" irgendjemand "offiziell" nennt).
Irgendwie las ich auch, dass das Depency-tracking sehr komplex
ist und dass es versucht, Konflikte automatisch zu lösen.




kama hat gesagt.:


> Das mit Übermorgen wird funktionieren...mit großer Sicherheit auch noch wesentlich länger...bei 10 Jahren wäre ich auch vorsichtig...


10 oder gar 20 Jahre sind hier übliche Zeiträume, aber aus
Gründen der Reproduzierbarkeit muss es alles, was verwendet wird,
dokumentiert, versioniert usw. sein.




kama hat gesagt.:


> . Die Abhängigkeit packt in einen Repository Manager...in ein Version Control gehören solche Artefakte schilcht nicht...



Doch, es muss je verwendete Software archiviert und jede
verwendete Hardware dokumentiert sein. Wenn man eine
transaktionsichere Versionsverwaltung hat, bietet sich unter
Umständen an, diese zu verwenden.



kama hat gesagt.:


> ABER Mann muss unbedingt sein Build System ins Version Control
> einchecken...und eben auch die genutzte VM
> (Betriebssystem).....Java was genutzt wird (JDK)...etc.



Maven plugins, wie zum Beispiel das Compiler-Plugin, gehören
meiner Meinung nach zum Buildsystem. Da sich diese im Repository
befinden, müssen diese Artifakte also doch ins VCS...




kama hat gesagt.:


> Das aus Deiner Sicht Maven an der forcierten Konfiguration vorbei geht sieht so aus, dass das nicht richtig ist was Du machst...



Ja, ich verwende Maven, was für diese Anforderungen nicht gut
geeignet ist. Ant wäre wohl günstiger. Aber hier ist wohl keine
Änderung geplant.



kama hat gesagt.:


> zeig mal was du gemacht hast...Ein Maven Repository in eine Version Control einzuckecken macht keinen Sinn...wie sieht die settings.xml aus?



           <repositories>
                <repository>
                    <id>3rdparty</id>
                    <name>third party2</name>
                    <url>file://${env.BASEPATH}/lib/3p/maven/repo</url>
                    <snapshots>
                        <enabled>true</enabled>
                        <updatePolicy>never</updatePolicy>
                    </snapshots>
                    <releases>
                        <enabled>true</enabled>
                        <updatePolicy>never</updatePolicy>
                    </releases>
                </repository>
            </repositories>    

gleiches für <pluginRepositories>, <mirrors> ist leer.




kama hat gesagt.:


> Hier scheint mir, dass Du einige Grundlagen von Maven und Maven Repositories nicht verstanden hast...Ein Repository Projektabhängig und gar Versionsabhängig zu machen...macht nicht wirklich sinn...Das geht auch mit einem Repository Manager...



Das verstehe ich nicht. Was genau habe ich nicht verstanden?
Es macht keinen Sinne, geht aber mit einem Repository Manager?
Hier macht es aber Sinn, und geht ohne Respository Manager.



kama hat gesagt.:


> Die Kontrolle die man über die Abhängigkeiten hat nennt sich pom.xml in der eine Abhängigkeit über groupId, artifactId, version eindeutigt Identifiziert wird. Eine Version (in diesem Falle Releases) werden ansonsten nie geändert...



Das ist zu stark vereinfach. Maven macht hier wesentlich mehr.

Vermutlich würde es sonst wohl auch kaum funktionieren, denn typischerweise verwendet man wohl hunderte Artifakte, die von anderen abhängen. Da ist es unwahrscheinlich, dass zwei dieser, die direkt oder indirekt von einem gemeinsamen dritten abhängen, dieses in der gleichen Version wünschen.



kama hat gesagt.:


> Die Frage ist  was Du mit Fehler passieren meinst?
> Um die Gefahr von Man in the Middle Attacken zu veringern wird seit August Maven Central mit SSL betrieben...weiterhin haben dazu alle Artefakt md5 und sha1 Prüfsummen....Das mit dem nicht mehr Betrieben werden ist eine Möglichkeit aber genau dafür sollte man eben einen eigenen Repository Manager Nutzen...Wenn dann Maven Central nicht mehr Verfügbar ist, bleibt das interne Repository und somit bleibt mein Build baubar...Server Hacking grundsätzlich ist nicht verhinderbar. Da aber die Adminstration der Maven Central in der Hand sehr begrenzten Zahl von Leute ist sehe ich das nicht wirklich ein Problem..



Ein Packet wird geupdatet, enthält einen neuen Bug. Als Folge funktioniert das building nicht mehr.

Ein Packet wird geupdatet, enthält eine Korrektur für einen Bug. Als Folge funktioniert das building nicht mehr, da es unglücklicherweise von diesem Bug abhängt.

Der Maven.org Besitzer bezahlt eine Rechnung nicht, und das System fällt aus.

Eine Gesellschaft erwirbt Markenrechte an "MaveNorg" und mahnt maven.org erfolgreich ab; die domain wird geschlossen.

In Zukunft verwendet vielleicht seit 10 Jahren keiner mehr Maven, das Internet ist IPv8 basiert und das DNS replacement hat noch nie was von maven.org gehört.

Ein Mitbewerber kauft oder hackt maven.org und schleust ein falsches Paket ein.

Das Internet geht nicht, weil ein Bagger die LWL Kabel zerfetzt hat.

Reicht? 



kama hat gesagt.:


> Reporoduzierbarkeit bedeutet, dass ich heute etwas baue in einer Version z.B. 1.0 und das in drei Jahren auch wieder bauen kann....Das hat mit Freigabeprozessen überhaupt nichts zu tun...



Da gibt es in großen Firmen formale Prozesse, die einzuhalten sind, beispielsweise Freigabeprozesse (engl: release processes oder realisation processes...), die beispielsweise Reproduzierbarkeit fordern.

Wenn keine Reproduzierbarkeit gefordert ist, hat man das "Problem" natürlich nicht, klar.



kama hat gesagt.:


> Grundlegendes um einen Maven Build Reproduzierbar zu machen. Alle verwendeten Plugins mit ihrer Versionen festlegen..., einen Repository Managemer nutzen und selbstverständlich den Source und alle genutzten Pom Dateien einchecken...und wenn man hier Konsequent ist muss man sowohl Maven, genutztes JDK und in der absoluten Konsequenz auch das Betriebssystem einchecken...



Genau. Weil man sich am Ende eh nicht aus den Haaren aus dem Sumpf ziehen kann, mag es ausreichen, das Image einer virtuellen Maschine abzulegen.
(das ist strenggenommen immer noch nicht ausreichend, weil dessen Host ja Asuwirkungen auf die Ergebnisse haben kann).



kama hat gesagt.:


> Achso...einen Release Kandidaten baut man in Maven mit den maven-release-plugin...
> 
> Maven Release plugin - Introduction



Das heißt leider "release", hat aber formal wenig mit Freigaben zu tun. Die meinen vielleicht "official deploy" oder sowas.

Sicherlich sind "no uncommited changes in the sources" usw. einfache erste Anforderungen an eine Freigabe, aber für professionelle Projekte hat man natürlich westenlich mehr. Das kann beliebig kompliziert sein, von "keine trouble tickets mit prio killing deadly offen" bis hin zu "darf nur bei Vollmond gebaut worden sein".
Am Ende muss irgendjemand einen Zettel unterschreiben. Dazu muss sichergestellt sein, dass die ganze Anforderungen, welche auch immer gelten, erfüllt sind.
Das ist dann eine formale Freigabe (engl. release). Das ist ein Prozeßergebnis, kein tool output. Aber das geht über den Scope der Entwicklung natürlich auch hinaus und ist hier wohl off topic. Ein bißchen was dazu findet sich z.B. in der Wikipedia Releasemanagement, wobei sowas aber natürlich stark vom Entwicklungsmodell und den Prozessen abhängt. Steuerungen für Atomraketen haben sicherlich ganz andere als die kleine free to play web app 

Beste Grüße
~/1b


----------

