{"id":644,"date":"2015-09-09T16:00:02","date_gmt":"2015-09-09T14:00:02","guid":{"rendered":"http:\/\/invidit.de\/blog\/?p=644"},"modified":"2015-09-20T10:24:33","modified_gmt":"2015-09-20T08:24:33","slug":"mit-maven-raus-aus-der-abhaengigkeit","status":"publish","type":"post","link":"https:\/\/invidit.de\/blog\/mit-maven-raus-aus-der-abhaengigkeit\/","title":{"rendered":"Mit Maven raus aus der Abh\u00e4ngigkeit"},"content":{"rendered":"<p>Hallo Spa\u00df-Coder.<\/p>\n<p>Abh\u00e4ngigkeiten sind nicht sch\u00f6n. Wir versuchen diese in unseren Code so weit es geht zu vermeiden (siehe etwa unsere Artikelserie zum Thema <a href=\"http:\/\/invidit.de\/blog\/aus-prinzip-nur-eine-verantwortlichkeit\/\">SOLID<\/a>). Auf der anderen Seite freuen wir uns, wenn wir das Rad nicht neu erfinden m\u00fcssen. Gerade im Umfeld von Java sind leistungsstarke, meist kostenfreie Open-Source-L\u00f6sungen vorhanden, die wir nutzen k\u00f6nnen, ohne selbst das detaillierte Know-How haben zu m\u00fcssen oder f\u00fcr die Qualit\u00e4tssicherung zu sorgen.<\/p>\n<p>Aber wie behalten wir den \u00dcberblick \u00fcber diese ganzen tollen Bibliotheken? Wie stellen wir sicher, dass wir diese auch an unsere Kunden liefern? Helfen kann uns dabei <a href=\"http:\/\/maven.apache.org\/\">Apache Maven<\/a>.<\/p>\n<p>In dieser Artikelreihe m\u00f6chten wir ein bisschen Licht ins Dunkel um das Mysterium von Apache Maven bringen. Fragen wie &#8222;Was ist Maven?&#8220;, &#8222;Wobei hilft mir Maven?&#8220; oder &#8222;Wann soll ich Maven verwenden?&#8220; werden wir beantworten. Dabei starten wir ganz am Anfang und versuchen die Einstiegsh\u00fcrde so klein wie m\u00f6glich zu halten. Wer jetzt noch <em>\u00e4ngstlichen Respekt<\/em> vor Maven hat, sollte die Angst nach dieser Artikelreihe abgelegt haben und nur noch <em>anerkennenden Respekt<\/em> f\u00fcr Maven empfingen.<br \/>\nUnserer Ansicht nach ist Maven im Umfeld der Java-Programmierung ein unverzichtbar hilfreiches Werkzeug.<\/p>\n<p>Um euch nicht mit grauer Theorie und Absichtserkl\u00e4rungen zu langweilen, halten wir den Teil dar\u00fcber, was Maven ist oder welche Ziele es verfolgt kurz und knapp und st\u00fcrzen uns gleich ins Eingemachte.<\/p>\n<p>&nbsp;<\/p>\n<h1>Was ist Maven?<\/h1>\n<ul>\n<li>Werkzeug zum Management von Software Projekten, typischerweise Java-Projekte.<\/li>\n<li>Verwaltung von Build, Auswertungen (statische Code-Analyse) und Dokumentationen (Haupts\u00e4chlich JavaDoc).<\/li>\n<li>Unterst\u00fctzt die zentralisierte Verwaltung von Software Projekten. Unterst\u00fctzt also die Zusammenarbeit im Team.<\/li>\n<li>Maven ist <b>kein<\/b> reines <b>Build<\/b><b>-Werkzeug. <\/b>Es unterst\u00fctzt vielmehr den gesamten Application Lifeycle (ALM).<b><br \/>\n<\/b><\/li>\n<\/ul>\n<p>Was hinter dem letzten Punkt steckt werden wir in dieser Artikelserie mit und mit aufdecken.<\/p>\n<p>&nbsp;<\/p>\n<h1>Ziele von Maven<\/h1>\n<ul>\n<li>Vereinfachung des Build Prozesses<\/li>\n<li>einheitliches Buildsystem<\/li>\n<li>Qualitativ hochwertige Projekt-Informationen<\/li>\n<li>Guidelines f\u00fcr best-practice Entwicklung<\/li>\n<\/ul>\n<p>Weitere Informationen dazu, was Maven ist oder welche Ziele es verfolgt, kann auf der Webseite von <a href=\"http:\/\/maven.apache.org\/\">Apache Maven<\/a> (in englischer Sprache) gefunden werden. F\u00fcr uns soll das aber erstmal reichen.<\/p>\n<p>&nbsp;<\/p>\n<h1>Terminologie<\/h1>\n<p>Maven verwendet ein paar Begriffe, die immer wiederkehren und die man kennen und zuordnen k\u00f6nnen sollte. Hier die wichtigsten, wie f\u00fcr das Verst\u00e4ndnis dieses und der weiteren Artikel notwendig sind.<\/p>\n<ul>\n<li>Modul\n<ul>\n<li>Ein durch Maven verwaltetes <strong>Software Projekt<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li>Build\n<ul>\n<li>Durchlaufen eines in <strong>Phasen aufgeteilten linearen Zyklus<\/strong> mit dem Ziel, ein definiertes Artefakt zu erzeugen.<\/li>\n<\/ul>\n<\/li>\n<li>Artefakt\n<ul>\n<li>Ein durch den Build <strong>erzeugtes Produkt oder Ausgabe<\/strong>, z.B. JARs, WARs<\/li>\n<\/ul>\n<\/li>\n<li>Deployment\n<ul>\n<li>Das <strong>Ver\u00f6ffentlichen eines Artefakts<\/strong> zur weiteren Verwendung<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h1>Project Object Model<\/h1>\n<p>Ein weiterer Begriff aus dem Umfeld von Maven ist die POM. Die POM &#8211; oder mit vollem Namen das <strong>P<\/strong>roject <strong>O<\/strong>bject <strong>M<\/strong>odel &#8211; ist die zentrale stelle, an der ein Maven-Modul konfiguriert wird. Pro Modul gibt es genau eine Datei mit Namen pom.xml (das ist die POM), in der alles konfiguriert wird, was f\u00fcr das Modul erforderlich ist.<\/p>\n<p>Die <b>POM <\/b>dient &#8230;<\/p>\n<ul>\n<li>&#8230; der Konfiguration des Build-Zyklus<\/li>\n<li>&#8230; der Beschreibung des erzeugten Artefakts zum Konsumieren durch andere, darauf aufbauende Module<\/li>\n<\/ul>\n<p>Dabei wird nicht beschrieben <b>wie <\/b>der Build zu erfolgen hat &#8211; stattdessen wird beschrieben <b>was herauskommen<\/b> soll.<\/p>\n<p>&nbsp;<\/p>\n<h2>Ein Beispiel<\/h2>\n<h3>Die POM<\/h3>\n<pre class=\"lang:xhtml decode:true \" title=\"pom.xml\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" \r\n\txmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 \r\n\thttp:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n\t&lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\r\n\t&lt;groupId&gt;de.invidit&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;tictactoe&lt;\/artifactId&gt;\r\n\t&lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;\r\n&lt;\/project&gt;<\/pre>\n<p>Diese XML-Datei beschreibt ein Modul vollst\u00e4ndig. Gehen wir die einzelnen Abschnitte einmal durch.<\/p>\n<ul>\n<li>&lt;?xml &#8230;&gt;\n<ul>\n<li>die pom.xml ist reines XML und wird auch so konfiguriert.<\/li>\n<\/ul>\n<\/li>\n<li>&lt;project &#8230;&gt;\n<ul>\n<li>dies ist der Haupt-Tag. Hierin befinden sich die Konfigurationen f\u00fcr das Modul. Die Namespaces helfen bei der Bearbeitung, etwa in einer IDE.<\/li>\n<\/ul>\n<\/li>\n<li>&lt;modelVersion&gt;\n<ul>\n<li>Das ist die Version der Konfiguration. Diese \u00e4ndert sich sehr selten.<\/li>\n<li>Sollte im Moment immer 4.0.0 sein.<\/li>\n<\/ul>\n<\/li>\n<li>&lt;groupId&gt; \/ &lt;artifactId&gt; \/ &lt;version&gt;\n<ul>\n<li>Hier\u00fcber wird unser Modul eindeutig identifiziert.<\/li>\n<li>Die <em><strong>G<\/strong>ruppe<\/em> muss eindeutig sein. Hier hat sich die R\u00fcckw\u00e4rtsschreibweise von Dom\u00e4nen etabliert, wie in <em>de.invidit. <\/em>Damit ist sichergestellt, dass sie eindeutig ist.<\/li>\n<li>Das <em><strong>A<\/strong>rtefakt<\/em> tr\u00e4gt den Namen unseres Moduls. Wir haben hier also ein Modul, dass <em>tictactoe<\/em> hei\u00dft. Innerhalb einer Gruppe muss der Name des Artefakts eindeutig sein.<\/li>\n<li>Die <em><strong>V<\/strong>ersion <\/em>zu guter Letzt bestimmt nun ganz genau, welche in welcher Version unser Artefakt vorliegt.<\/li>\n<li>Diese drei Werte werden auch <strong>GAV<\/strong> genannt. Die Abk\u00fcrzung ergibt sich aus den Anfangsbuchstaben.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Damit haben wir unser Maven-Modul beschrieben. Es hat einen Namen, geh\u00f6rt zu einer Gruppe und hat eine eindeutige Versionsnummer. Eine Besonderheit hier ist die Angabe <em>-SNAPSHOT<\/em> hinter der Version. Diese sagt aus, dass es sich um ein Modul handelt, welches sich noch in der Entwicklung befindet. SNAPSHOT-Abh\u00e4ngigkeiten sollten nicht in produktiven Umgebungen verwendet werden, da diese nicht eindeutig wiederherstellbar sind.<\/p>\n<p>Erst nach der Freigabe der Software wird die SNAPSHOT-Version entfernt. Eine Release-Version erkennt man also ganz einfach daran, dass in der Versionsangabe kein SNAPSHOT vorkommt (in unserem Beispiel w\u00e4re also <em>0.0.1<\/em> die Release-Version).<\/p>\n<p>&nbsp;<\/p>\n<h3>Der Code<\/h3>\n<p>Schauen wir mal in die Main-Methode von tictactoe, hier gibt es eine Stelle, die wir gerne verbessern m\u00f6chten.<\/p>\n<pre class=\"lang:java mark:14 decode:true \" title=\"TicTacToe.java\">public void run() {\r\n   while (true) {\r\n      System.out.println(this.playfield.toString());\r\n\r\n      Player player = this.playfield.getCurrentPlayer();\r\n      \r\n      System.out.println(\"Player '\" + player.getName() + \"':\");\r\n      int nextPosition = player.getNextMove(getGameState());\r\n      System.out.println(\"Set '\" + player.getSymbol() + \"' at position '\" \r\n            + (nextPosition+1) + \"'.\");\r\n      try {\r\n         this.playfield.applyAction(nextPosition);\r\n      } catch (GameException e) {                \r\n         e.printStackTrace();\r\n      }  \r\n         \r\n      Player winner = this.playfield.getWinner();\r\n      if (winner != null) {\r\n         printGameResult(\"Winner is '\" + winner.getName() + \"'\");\r\n      }\r\n\r\n      if (this.playfield.isGameTerminated()) {\r\n         printGameResult(\"Game is a draw.\");\r\n      }\r\n   }          \r\n}<\/pre>\n<p>In der markierten Zeile w\u00fcrden wir gerne das fiese <em>printStackTrace()<\/em> durch eine ordentliche Log-Ausgabe ersetzen. Zum Gl\u00fcck wissen wir, dass es mit Log4J eine stabile und gut funktionierende Open-Source-L\u00f6sung f\u00fcr unser Problem gibt. Diese wollen wir nun verwenden.<\/p>\n<p>Unser neuer Code sieht also anschlie\u00dfend so aus:<\/p>\n<pre class=\"lang:java mark:4 decode:true\" title=\"TicTacToe.java\">try {\r\n this.playfield.applyAction(nextPosition);\r\n} catch (GameException e) {                \r\n logger.error(e);\r\n}  \r\n<\/pre>\n<p>Was aber m\u00fcssen wir alles tun, damit diese Zeile auch funktioniert?<\/p>\n<ol>\n<li>Wir m\u00fcssen die Klassenvariable <i>logger<\/i> definieren<\/li>\n<li>Wir m\u00fcssen das package in einer import-Anweisung angeben, in dem die Klasse definiert ist<\/li>\n<li>Wir m\u00fcssen die Klasse im Classpath verf\u00fcgbar machen<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3>Probleme? Nicht f\u00fcr mich!<\/h3>\n<p>Dazu brauchen wir aber kein Werkzeug, oder? Das ist doch super einfach. Drei Zeilen Code einf\u00fcgen, die JAR herunterladen und in der IDE in den Classpath packen, fertig! Wozu Maven und diese pom.xml?<\/p>\n<p>Spannend wird Maven dann, wenn man nicht alleine an einem Projekt arbeitet, sondern im Team. Ich habe nat\u00fcrlich keine Probleme mit der \u00c4nderung, ich habe ja alles gemacht. Checke ich den Code aber nun in unser SVN ein und jemand aus dem Team checkt es aus, bekommt dieser einen Compilefehler. Er hat ja die neue Bibliothekt, also Log4J, noch gar nicht. Er muss sie also ebenfalls herunterladen und in seiner IDE dem Classpath hinzuf\u00fcgen.<\/p>\n<p>Aber woher bekommen die anderen Teammitglieder die Klasse? Woher wissen sie, in welcher Version die Klasse verwendet wird? Wie stellen wir sicher, dass die Klasse nicht bereits in einer anderen Version verwendet wird? Diesen Fragen beantwortet Maven f\u00fcr uns!<\/p>\n<p>Statt die JAR-Datei manuell im Internet zu suchen, herunterzuladen und in den Classpath einzuf\u00fcgen, brauchen wir Maven nur mitzuteilen, was wir brauchen.<\/p>\n<pre class=\"lang:xhtml mark:6-12 decode:true \" title=\"pom.xml\">&lt;project [...]&gt;\r\n\t&lt;groupId&gt;de.invidit&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;tictactoe&lt;\/artifactId&gt;\r\n\t&lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;\r\n\r\n\t&lt;dependencies&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t &lt;groupId&gt;log4j&lt;\/groupId&gt;\r\n\t\t\t &lt;artifactId&gt;log4j&lt;\/artifactId&gt;\r\n\t\t\t &lt;version&gt;1.2.17&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t&lt;\/dependencies&gt;\r\n\r\n&lt;\/project&gt;<\/pre>\n<p>Wir erg\u00e4nzen also die Abh\u00e4ngigkeit (engl. dependency) in der pom.xml. Dabei geben wir im neuen Bereich &lt;dependencies&gt; eine neue &lt;dependency&gt; an und verwenden daf\u00fcr die <strong>GAV<\/strong> von Log4J.<\/p>\n<p>Maven k\u00fcmmert sich nun darum, dass die passende JAR-Datei heruntergeladen wird und stellt sie unserem Modul im Classpath zur Verf\u00fcgung. Bauen wir eine gr\u00f6\u00dfere Anwendung und packen diese in ein WAR, sorgt Maven auch daf\u00fcr, dass alle Abh\u00e4ngigkeiten mit eingepackt werden.<\/p>\n<p>Die Mitglieder aus unserem Team checken nun einfach das Projekt aus und Maven versorgt sie mit den passenden Abh\u00e4ngigkeiten. Einfach, oder?<\/p>\n<p>&nbsp;<\/p>\n<h1>Zusammenfassung<\/h1>\n<p>Durch die einfache Definition unseres Moduls in einer XML-Datei bilden wir die Basis f\u00fcr ein Maven-Projekt. Hier k\u00f6nnen wir dann unsere Abh\u00e4ngigkeiten komfortabel verwalten und dem Team automatisch zur Verf\u00fcgung stellen.<\/p>\n<p>In Maven steckt noch viel mehr. Auch hier sind wir erst an der Oberfl\u00e4che geblieben. Im n\u00e4chsten Artikel wollen wir uns das Ganze mal in der Praxis anschauen und sehen, wie wir Maven dann auch tats\u00e4chlich benutzen und was &#8222;unter der Haube&#8220; dabei so alles passiert.<\/p>\n<p>&nbsp;<\/p>\n<p>Viel Spa\u00df beim Verwalten der Abh\u00e4ngigkeiten.<\/p>\n<p>Eure Spa\u00df-Coder<\/p>\n<p>&nbsp;<\/p>\n<p>Dieser Artikel basiert neben unseren Erfahrungen auf den Ausf\u00fchrungen aus:<\/p>\n<ul>\n<li id=\"gs_cit0\" class=\"gs_citr\" tabindex=\"0\">Maven-Training von Ren\u00e9 Gielen &#8211; <a href=\"http:\/\/it-neering.net\/\">IT Neering<\/a> (nahezu alles, was wir \u00fcber Maven wissen, wissen wir direkt oder indirekt von ihm. Danke Ren\u00e9!)<\/li>\n<li class=\"gs_citr\" tabindex=\"0\">http:\/\/maven.apache.org\/<\/li>\n<li class=\"gs_citr\" tabindex=\"0\">\n<div id=\"gs_cit0\" class=\"gs_citr\" tabindex=\"0\">H\u00fcttermann, Michael &#8211; <em>Agile ALM<\/em>, Manning Publications Co., 2011<\/div>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hallo Spa\u00df-Coder. Abh\u00e4ngigkeiten sind nicht sch\u00f6n. Wir versuchen diese in unseren Code so weit es geht zu vermeiden (siehe etwa unsere Artikelserie zum Thema SOLID). Auf der anderen Seite freuen wir uns, wenn wir das Rad nicht neu erfinden m\u00fcssen. Gerade im Umfeld von Java sind leistungsstarke, meist kostenfreie Open-Source-L\u00f6sungen vorhanden, die wir nutzen k\u00f6nnen, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":658,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[22],"tags":[124],"_links":{"self":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/644"}],"collection":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/comments?post=644"}],"version-history":[{"count":14,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/644\/revisions"}],"predecessor-version":[{"id":659,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/644\/revisions\/659"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media\/658"}],"wp:attachment":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media?parent=644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/categories?post=644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/tags?post=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}