{"id":662,"date":"2015-09-16T16:15:35","date_gmt":"2015-09-16T14:15:35","guid":{"rendered":"http:\/\/invidit.de\/blog\/?p=662"},"modified":"2015-10-14T13:11:11","modified_gmt":"2015-10-14T11:11:11","slug":"hands-on-maven-dependency-management","status":"publish","type":"post","link":"https:\/\/invidit.de\/blog\/hands-on-maven-dependency-management\/","title":{"rendered":"Hands on Maven Dependency Management"},"content":{"rendered":"<p>Hallo Spa\u00df-Coder.<\/p>\n<p>Im Artikel <a href=\"http:\/\/invidit.de\/blog\/mit-maven-raus-aus-der-abhaengigkeit\/\" target=\"_blank\">Mit Maven raus aus der Abh\u00e4ngigkeit<\/a> haben wir einen Einstieg in die Verwaltung von Abh\u00e4ngigkeiten zwischen Java-Projekten gezeigt. Aber wie genau funktioniert das nun in der Praxis? Wie gehe ich vor, wenn ich Unit Tests in meinem Projekt hinzuf\u00fcgen m\u00f6chte und daf\u00fcr JUnit einbinden will? Wo finde ich diese Abh\u00e4ngigkeit f\u00fcr meine POM? Wie macht Maven das mit der Bereitstellung der Abh\u00e4ngigkeiten denn so genau?<\/p>\n<p>Damit Maven genutzt werden kann, muss entweder die IDE-Integration aktiviert oder &#8211; so wie wir es im Laufe des Artikels beschreiben &#8211; Maven lokal installiert sein. Maven ist f\u00fcr verschiedene Plattformen z.B. unter <a href=\"http:\/\/archive.apache.org\" target=\"_blank\">apache.maven.org<\/a> zu finden. Unter <a href=\"http:\/\/www.it-adviser.net\/apache-maven-installieren\/\" target=\"_blank\">http:\/\/www.it-adviser.net\/apache-maven-installieren\/<\/a> findet ihr eine leicht verst\u00e4ndliche Beschreibung der Installation zu Maven auf deutsch. Auf der Kommando-Zeile kann eine erfolgreiche Installation mit dem Befehl <strong>mvn -version<\/strong> \u00fcberpr\u00fcft werden.<\/p>\n<pre class=\"lang:default decode:true\" title=\"mvn -version\">&gt;mvn -version\r\n\r\nApache Maven 3.1.1 (893ca28a1da9d5f51ac03827af98bb730128f9f2; 2013-06-28 04:15:32+0200)\r\nMaven home: D:\\Development\\maven\r\nJava version: 1.7.0, vendor: Oracle Corporation\r\nJava home: D:\\Programme\\Java\\jdk1.7.0\\jre\r\nDefault locale: de_DE, platform encoding: Cp1252\r\nOS name: \"windows 7\", version: \"6.1\", arch: \"amd64\", family: \"windows\"<\/pre>\n<p>Dabei muss die Version von Maven ausgegeben werden (hier: 3.1.1). Damit Maven erfolgreich betrieben werden kann, muss auch das JDK von Java installiert sein. Das habt ihr aber wahrscheinlich sowieso schon, ihr wollt ja schlie\u00dflich Java programmieren \ud83d\ude09<\/p>\n<p>Im Folgenden gehen wir davon aus, dass ihr das Grundverst\u00e4ndnis aus dem vorangegangenen Artikel mitbringt. Falls euch was unklar ist, <a href=\"http:\/\/invidit.de\/blog\/mit-maven-raus-aus-der-abhaengigkeit\/\">lest dort noch einmal nach<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h1>Unser kleines Projekt<\/h1>\n<p>Beginnen wir damit, ein neues Java-Projekt anzulegen. Diesmal allerdings nicht in unserer Lieblings-IDE, sondern als <strong>P<\/strong>roject <strong>O<\/strong>bject <strong>M<\/strong>odel &#8211; also POM. Wir beschreiben damit, was am Ende als Ergebnis herauskommen soll. Dies sieht im ersten Schritt wie folgt aus:<\/p>\n<pre class=\"lang:xhtml decode:true\" title=\"Leere POM\">&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    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\r\n    &lt;groupId&gt;de.invidit&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;HelloWorld&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.0.0-SNAPSHOT&lt;\/version&gt;\r\n&lt;\/project&gt;<\/pre>\n<p>Wie erinnern uns an die Beschreibung unseres Moduls als GAV, also mit der <strong>g<\/strong>roupId, <strong>a<\/strong>rtifactId und <strong>v<\/strong>ersion. Unser Projekt soll den Namen <em>HelloWorld<\/em> &#8211; was auch sonst \ud83d\ude09 &#8211; haben und zun\u00e4chst in der Version 1.0.0 als Schnappschuss &#8211; also als Version die sich noch in der Entwicklung befindet &#8211; ver\u00f6ffentlicht werden.<\/p>\n<p>Was passiert nun, wenn wir Maven unser Modul bauen lassen? Probieren wir es aus und rufen dazu auf der Kommando-Zeile <strong>mvn package<\/strong> im unserem Projektverzeichnis in dem die pom.xml liegt auf. Maven ist so freundlich und kompiliert unseren Code &#8211; in diesem Fall haben wir noch keine Programmquellen -, f\u00fchrt alle Unit Tests aus und erstellt die Datei <strong>HelloWorld-1.0.0-SNAPSHOT.jar<\/strong> im Unterordner <strong>target<\/strong>.<\/p>\n<pre class=\"lang:default decode:true\" title=\"Erster Build mit Maven\">&gt;mvn package\r\n\r\n[INFO] Scanning for projects...\r\n[INFO]\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Building HelloWorld 1.0.0-SNAPSHOT\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO]\r\n[...]\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] BUILD SUCCESS\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Total time: 5.803s\r\n[INFO] Finished at: Tue Sep 15 19:39:00 CEST 2015\r\n[INFO] Final Memory: 8M\/122M\r\n[INFO] ------------------------------------------------------------------------<\/pre>\n<p>&nbsp;<\/p>\n<h1>Unser Projekt macht auch was<\/h1>\n<p>Legen wir eine typische Java-Klasse mit dem Namen <em>HelloWorld.java<\/em> und diesem Inhalt an:<\/p>\n<pre class=\"lang:java decode:true\" title=\"HelloWorld\">package de.invidit.hello;\r\n\r\npublic class HelloWorld {\r\n\r\n\tpublic static void main(String[] args) {\r\n\t\tSystem.out.println(getHelloPhrase(\"Maven\"));\r\n\t}\r\n\r\n\tpublic static String getHelloPhrase(String name) {\r\n\t\treturn \"Hello \" + name + \"-World\";\r\n\t}\r\n}<\/pre>\n<p>Die Ausgabe auf dem Standardausgabestrom soll also &#8222;Hello Maven-World&#8220; sein. Aber wo legen wir die Datei zu unserer Klasse ab?<\/p>\n<p>Maven arbeitet an vielen Stellen nach dem Prinzip &#8222;Convention over Configuration&#8220;. So auch bei den Verzeichnissen, in denen unsere Quelldateien abgelegt werden. Hier sieht Maven einen Standard f\u00fcr die Verzeichnisstruktur vor, an den sich alle Maven 3 Projekte halten sollten. Dieser sieht folgenderma\u00dfen aus:<\/p>\n<ul>\n<li>src\n<ul>\n<li>main\n<ul>\n<li>java\n<ul>\n<li>[packages]\n<ul>\n<li>[Klassen]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>test\n<ul>\n<li>java\n<ul>\n<li>[packages]\n<ul>\n<li>[Test-Klassen]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Unsere obige Quelldatei legen wir demnach also im Verzeichnis <strong>\/src\/main\/java\/de\/invidit\/<\/strong> unter dem Namen <strong>HelloWorld.java<\/strong> an.<\/p>\n<p>Was passiert nun, wenn wir mit Maven erneut unser Projekt bauen? Rufen wir <strong>mvn package<\/strong> also nochmal auf. Hmmm&#8230;die Ausgabe sieht genauso aus wir vorher, aber nun ist unser Code in der JAR-Datei enthalten, was wir \u00fcberpr\u00fcfen k\u00f6nnen, in dem wir unsere main()-Methode einfach mal aufrufen (dazu m\u00fcssen wir zuvor in das target-Verzeichnis wechseln):<\/p>\n<pre class=\"lang:default decode:true\" title=\"Aufruf HelloWorld\">&gt;java -cp HelloWorld-1.0.0-SNAPSHOT.jar de.invidit.hello.HelloWorld\r\n\r\nHello Maven-World<\/pre>\n<p>Gro\u00dfartig! Aber das ist nur der Anfang. Bis hierhin bietet uns Maven noch keine Vorteile gegen\u00fcber unserer IDE.<\/p>\n<p>&nbsp;<\/p>\n<h1>Vor dem Refaktorisieren schreiben wir nat\u00fcrlich Tests<\/h1>\n<p>Die Ausgabe auf dem Standardausgabestrom ist nicht sonderlich elegant. Wir ersetzen diese lieber durch eine Ausgabe\u00a0 in eine Log-Datei. Aber &#8211; bevor wir die \u00c4nderung an unserem Code vornehmen, sichern wir diese durch Unit Tests ab. Dazu nutzen wir selbstverst\u00e4ndlich die bereits vorgestellten Bibliotheken <a href=\"http:\/\/invidit.de\/blog\/hoer-mal-wer-da-testet-java-edition\/\">JUnit und AsssertJ<\/a>.<\/p>\n<pre class=\"lang:java decode:true \" title=\"Test\">public class HelloWorldTest extends TestCase {\r\n\r\n\tpublic void testGetHelloPhraseForGivenValueReturnsCorrectPhrase() throws Exception {\r\n\t\tString expected = \"Hello Maven-World\";\r\n\r\n\t\tString actual = HelloWorld.getHelloPhrase(\"Maven\");\r\n\r\n\t\tAssertions.assertThat(actual).isEqualTo(expected);\r\n\t}\r\n}<\/pre>\n<p>Nach der Verzeichnisstruktur von oben liegt unsere Klasse <em>HelloWorldTest.java<\/em> im Verzeichnis <strong>\/src\/<span style=\"text-decoration: underline;\">test<\/span>\/java\/de\/invidit\/<\/strong>. Maven unterscheidet in der Struktur bereits zwischen Produktivem Quellcode und Testcode.<\/p>\n<p>Um unser Projekt zu bauen, rufen wir erneut was auf? Genau: <strong>mvn package<\/strong>. Auf Grund der Standardverzeichnisstruktur von Maven wird unser Unit Test nach dem Kompilieren ausgef\u00fchrt.<\/p>\n<pre class=\"lang:default decode:true\" title=\"Build Failure\">&gt; mvn package\r\n\r\n[...]\r\n[INFO] -------------------------------------------------------------\r\n[ERROR] COMPILATION ERROR :\r\n[INFO] -------------------------------------------------------------\r\n[ERROR] \\src\\test\\java\\de\\invidit\\hello\\HelloWorldTest.java:[10,22] error: package junit.framework does not exist\r\n[ERROR] \\src\\test\\java\\de\\invidit\\hello\\HelloWorldTest.java:[11,27] error: package org.assertj.core.api does not exist\r\n[ERROR] \\src\\test\\java\\de\\invidit\\hello\\HelloWorldTest.java:[13,36] error: cannot find symbol\r\n[ERROR] \\src\\test\\java\\de\\invidit\\hello\\HelloWorldTest.java:[20,2] error: cannot find symbol\r\n[INFO] 4 errors\r\n[INFO] -------------------------------------------------------------\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] BUILD FAILURE\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Total time: 0.998s\r\n[INFO] Finished at: Tue Sep 15 20:33:25 CEST 2015\r\n[INFO] Final Memory: 14M\/154M\r\n[INFO] ------------------------------------------------------------------------\r\n[...]<\/pre>\n<p>WTF!? Maven kommt gar nicht erst zu unserem Test, da bereits das Kompilieren abbricht. Den Fehlermeldungen k\u00f6nnen wir entnehmen, dass sowohl JUnit als auch AssertJ nicht gefunden werden. Wo bekommen wir diese jetzt her?<\/p>\n<p>Suchen wir Bibliotheken, die wir mit Maven in unser Projekt einbinden wollen, k\u00f6nnen wir die Suche unter <a href=\"http:\/\/search.maven.org\">search.maven.org<\/a> nutzen und dort einfach unsere Bibliothek suchen. Wer sich den Link nicht merken oder speichern m\u00f6chte, setzt bei der Suche in der bevorzugten Suchmaschine &#8222;maven&#8220; vorneweg und bekommt in der Regel einen guten Treffer. Der Vorteil bei diesen Verzeichnissen ist, dass der Eintrag f\u00fcr unsere POM direkt kopiert werden kann, wenn ich eine Version der Bibliothek ausgew\u00e4hlt habe. Nehmen wir JUnit und AssertJ als Abh\u00e4ngigkeit auf, sieht unsere POM so aus:<\/p>\n<pre class=\"lang:xhtml decode:true \" title=\"POM mit Abh\u00e4ngigkeiten\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\"\r\n         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0\r\n\thttp:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n    &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\r\n    &lt;groupId&gt;de.invidit&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;HelloWorld&lt;\/artifactId&gt;\r\n    &lt;version&gt;1.0.0-SNAPSHOT&lt;\/version&gt;\r\n\r\n    &lt;dependencies&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;junit&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;junit&lt;\/artifactId&gt;\r\n            &lt;version&gt;4.12&lt;\/version&gt;\r\n            &lt;scope&gt;test&lt;\/scope&gt;\r\n        &lt;\/dependency&gt;\r\n        &lt;dependency&gt;\r\n            &lt;groupId&gt;org.assertj&lt;\/groupId&gt;\r\n            &lt;artifactId&gt;assertj-core&lt;\/artifactId&gt;\r\n            &lt;version&gt;2.1.0&lt;\/version&gt;\r\n            &lt;scope&gt;test&lt;\/scope&gt;\r\n        &lt;\/dependency&gt;\r\n    &lt;\/dependencies&gt;\r\n&lt;\/project&gt;<\/pre>\n<p>Schauen wir mal, ob Maven nun in der Lage ist, unseren Code zu kompilieren und den Test auszuf\u00fchren. Erneut rufen wir <strong>mvn package<\/strong> auf.<\/p>\n<pre class=\"lang:default mark:4-5 decode:true\">&gt; mvn package\r\n\r\n[...]\r\n-------------------------------------------------------\r\n T E S T S\r\n-------------------------------------------------------\r\nRunning de.invidit.hello.HelloWorldTest\r\nTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.062 sec\r\n\r\nResults :\r\nTests run: 1, Failures: 0, Errors: 0, Skipped: 0\r\n\r\n[INFO]\r\n[INFO] --- maven-jar-plugin:2.3.1:jar (default-jar) @ HelloWorld ---\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] BUILD SUCCESS\r\n[INFO] ------------------------------------------------------------------------\r\n[INFO] Total time: 4.150s\r\n[INFO] Finished at: Tue Sep 15 20:50:21 CEST 2015\r\n[INFO] Final Memory: 9M\/122M\r\n[INFO] ------------------------------------------------------------------------<\/pre>\n<p>YEAH! Am Ende unseres erneuten Aufrufs erhalten wir nun die gew\u00fcnschte Information, das unser Test ausgef\u00fchrt wurde.<\/p>\n<p>Der Test war erfolgreich;<\/p>\n<ul>\n<li>1 Test wurde ausgef\u00fchrt (Tests run)<\/li>\n<li>0 Tests waren fehlerhaft (Failures und Errors)<\/li>\n<li>0 Tests wurden \u00fcbersprungen (Skipped).<\/li>\n<\/ul>\n<p>Nach dem Punkt &#8222;Results :&#8220; sehen wir noch einmal eine Zusammenfassung aller Tests aus unserem Modul. Da wir derzeit nur genau einen Test haben, unterscheiden sich die beiden Ausgaben nicht.<\/p>\n<p>Wie aber hat Maven das nun gemacht? Schauen wir ein wenig weiter oben in die Ausgabe, sehen wir die L\u00f6sung dieses R\u00e4tsels:<\/p>\n<pre class=\"lang:default decode:true\" title=\"Download der Abh\u00e4ngigkeiten durch Maven\">[INFO] ------------------------------------------------------------------------\r\n[INFO] Building HelloWorld 1.0.0-SNAPSHOT\r\n[INFO] ------------------------------------------------------------------------\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/junit\/junit\/4.12\/junit-4.12.pom\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/junit\/junit\/4.12\/junit-4.12.pom (24 KB at 123.7 KB\/sec)\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/org\/hamcrest\/hamcrest-core\/1.3\/hamcrest-core-1.3.pom\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/org\/hamcrest\/hamcrest-core\/1.3\/hamcrest-core-1.3.pom (766 B at 11.9 KB\/sec)\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/org\/hamcrest\/hamcrest-parent\/1.3\/hamcrest-parent-1.3.pom\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/org\/hamcrest\/hamcrest-parent\/1.3\/hamcrest-parent-1.3.pom (2 KB at 31.1 KB\/sec)\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/org\/assertj\/assertj-core\/2.1.0\/assertj-core-2.1.0.pom\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/org\/assertj\/assertj-core\/2.1.0\/assertj-core-2.1.0.pom (6 KB at 63.1 KB\/sec)\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/org\/assertj\/assertj-parent-pom\/1.3.6\/assertj-parent-pom-1.3.6.pom\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/org\/assertj\/assertj-parent-pom\/1.3.6\/assertj-parent-pom-1.3.6.pom (15 KB at 105.7 KB\/sec)\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/junit\/junit\/4.12\/junit-4.12.jar\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/org\/assertj\/assertj-core\/2.1.0\/assertj-core-2.1.0.jar\r\nDownloading: http:\/\/repo1.maven.org\/maven2\/org\/hamcrest\/hamcrest-core\/1.3\/hamcrest-core-1.3.jar\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/org\/hamcrest\/hamcrest-core\/1.3\/hamcrest-core-1.3.jar (44 KB at 68.8 KB\/sec)\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/org\/assertj\/assertj-core\/2.1.0\/assertj-core-2.1.0.jar (680 KB at 440.1 KB\/sec)\r\nDownloaded: http:\/\/repo1.maven.org\/maven2\/junit\/junit\/4.12\/junit-4.12.jar (308 KB at 182.6 KB\/sec)\r\n[...]<\/pre>\n<p>Maven l\u00e4dt also die von uns definierten Abh\u00e4ngigkeiten ohne weiteres Zutun herunter. Woher Maven das bekommt (in diesem Fall htp:\/\/repo1.maven.org) ist wieder eine Konvention von Maven.<\/p>\n<p>Wenn wir uns das Ganze ein wenig genauer anschauen, finden wir allerdings auch etwas Verwirrendes. Was ist denn <em>hamcrest-core<\/em>? Das haben wir doch gar nirgendwo hingeschrieben!?! Wo kommt das her?<\/p>\n<p>Dies ist eine weitere St\u00e4rke von Maven. Die von uns verwendete Bibliothek <em>JUnit<\/em> hat selbst eine weitere Abh\u00e4ngigkeit, n\u00e4mlich <em>hamcrest-core<\/em>. Dass das so ist, wussten wir bis eben gar nicht &#8211; und es muss uns auch nicht weiter interessieren. Maven sorgt daf\u00fcr, dass wir alle weiteren Abh\u00e4ngigkeiten bekommen, die von den von uns genutzten Bibliotheken ben\u00f6tigt werden.\u00a0 Abh\u00e4ngigkeiten dieser Art werden <strong>transitive Abh\u00e4ngigkeiten<\/strong> genannt.<\/p>\n<p>&nbsp;<\/p>\n<h1>Eine kleine \u00dcbung zum Abschluss<\/h1>\n<p>Nachdem wir nun die Grundlagen gemeinsam durchgegangen sind und einen Test zur Absicherung der Funktionalit\u00e4t unserer Klasse geschrieben haben, gibt es zum Abschluss nun eine kleine Aufgabe.<\/p>\n<p>Was m\u00fcssen wir in der POM anpassen, um den Code erfolgreich packen zu k\u00f6nnen (mvn package), wenn wir den Code unserer Klasse folgenderma\u00dfen \u00e4ndern:<\/p>\n<pre class=\"lang:java mark:3-4,8,11 decode:true\">package de.invidit.hello;\r\n\r\nimport org.apache.log4j.LogManager;\r\nimport org.apache.log4j.Logger;\r\n\r\npublic class HelloWorld {\r\n\r\n\tprivate static Logger logger = LogManager.getLogger(HelloWorld.class);\r\n\r\n\tpublic static void main(String[] args) {\r\n\t\tlogger.info(getHelloPhrase(\"Maven-Dependency\"));\r\n\t}\r\n\r\n\tpublic static String getHelloPhrase(String name) {\r\n\t\treturn \"Hello \" + name + \"-World\";\r\n\t}\r\n}\r\n<\/pre>\n<p>Viel Spa\u00df beim t\u00fcfteln.<\/p>\n<p>&nbsp;<\/p>\n<h1>Zusammenfassung und Ausblick<\/h1>\n<p>Wir hoffen, dass ihr durch das Selbst-Hand-Anlegen ein wenig mehr Gef\u00fchl f\u00fcr den Umgang mit Maven bekommen habt und sich ein bischen die Magie von Maven entfaltet hat.<\/p>\n<p>In den kommenden Artikeln zur Serie werden wir noch ein paar weitere Geheimnisse l\u00fcften, etwa wohin Maven die Abh\u00e4ngigkeiten den herunterl\u00e4dt, was dieses &#8222;package&#8220; was wir verwendet haben zu bedeuten hat und wie wir in komplexeren Projekten unsere Abh\u00e4ngigkeiten effektiv verwalten k\u00f6nnen.<\/p>\n<p>&nbsp;<\/p>\n<p>Habt ihre Fragen oder Anregungen, sprecht uns gerne in den Kommentaren an. Auch wenn ihr Probleme mit den Anweisungen oder der Abschluss\u00fcbung haben solltet, k\u00f6nnt ihr gerne dort nachfragen.<\/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 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\">http:\/\/search.maven.org<\/div>\n<\/li>\n<li class=\"gs_citr\" tabindex=\"0\">http:\/\/mvnrepository.com<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hallo Spa\u00df-Coder. Im Artikel Mit Maven raus aus der Abh\u00e4ngigkeit haben wir einen Einstieg in die Verwaltung von Abh\u00e4ngigkeiten zwischen Java-Projekten gezeigt. Aber wie genau funktioniert das nun in der Praxis? Wie gehe ich vor, wenn ich Unit Tests in meinem Projekt hinzuf\u00fcgen m\u00f6chte und daf\u00fcr JUnit einbinden will? Wo finde ich diese Abh\u00e4ngigkeit f\u00fcr [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":689,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[22],"tags":[126,125,124],"_links":{"self":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/662"}],"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=662"}],"version-history":[{"count":23,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/662\/revisions"}],"predecessor-version":[{"id":851,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/662\/revisions\/851"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media\/689"}],"wp:attachment":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media?parent=662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/categories?post=662"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/tags?post=662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}