Ein Ansatz, diesem Problem vorzubeugen, sind sicher straffe Dokumentationsrichtlinien und die Verordnung, verwendeten externen Code in einem zentralen Repository in einer vorgegebenen Struktur abzulegen - viel Aufwand für die Entwickler, und nur schlecht durchsetz-, weil kaum kontrollierbar. Einen besseren Ansatz stellt ein Tool wie Apache Maven2 dar: Abhängigkeiten, in zentralen (und durchaus auch lokal pflegbaren) Repository-Strukturen abgelegt, werden in einer projektspezifischen Definition deklarativ festgelegt, lassen sich dabei versionsgenau vorgeben und werden durch maven bei Übersetzung bzw. Ausführung des Projektes automatisch aus dem Repository auf das lokale System geholt, wobei das Werkzeug hier auch "transitive Abhängigkeiten" (d.h. die Abhängigkeiten, die "direkt" am Projekt definierte Abhängigkeiten wieder hervorrufen) berücksichtigt.
Weitergehende Ausführungen zu maven sind imstande, den Rahmen dieses Textes beträchtlich zu sprengen, weswegen grundlegende Kenntnisse im Umgang mit dem Werkzeug hier vorausgesetzt werden.
Alles in allem ist maven damit ein enorm mächtiges Werkzeug, und die Tatsache, daß ein exzellentes Plugin dieses sehr gut und nahtlos in die IDE integriert, ein weiteres sehr gutes Argument für NetBeans 6. Dieses Feature muß allerdings über "Tools" -> "Plugins" nachinstalliert werden, um nutzbar zu sein:
![]() |
Nach Setzen der Auswahl in der Spalte "Install" und Klick auf den "Install"-Button, gefolgt von einer zu bestätigenden Anzeige der (Apache-)Lizenz des Plugins, lädt der NetBeans-Plugin-Manager die erforderlichen Pakete herunter und installiert diese in der IDE. Danach kann die Arbeit mit maven beginnen.
Wie bereits in JavaSeStarterDe festgestellt, setzt NetBeans komplett auf ant als Build-Mechanismus, was den Vorteil hat, Projekte ohne IDE zu bauen und verteilen zu können. Im konkreten Fall hat dies noch einen anderen positiven Aspekt: Bei maven-basierten Projekten wird (im Gegensatz zu anderen IDEs mit maven-Integration) der normalerweise zum Einsatz kommende Build-Mechanismus komplett außer Kraft gesetzt und ausschließlich maven für Build und Deployment des Projektes verwendet. Daraus folgt auch, daß kaum IDE-spezifische Infrastruktur innerhalb des Projektordners erforderlich ist und folglich NetBeans, mit installiertem maven-Plugin, auch über "Open Project..." jedes beliebige Maven2-Projekt sofort öffnen und bearbeiten kann.
Darüber hinaus kann die IDE natürlich auch entsprechende Projekte erzeugen (über "File" -> "New Project" und die Auswahl der Kategorie "Maven"):
![]() |
Infolgedessen kann ein 'Archetyp' ausgewählt werden, der im Wesentlichen einer leeren Maven-Projektstruktur mit pom.xml für konkrete Anwendungsfälle entspricht. Für das Beispiel ist 'quickstart' eine gute Wahl:
![]() |
Danach werden die grundlegenden Informationen abgefragt, die das Projekt als maven-Artifact beschreiben:
![]() |
Zwei Einträge werden hierbei automatisch gebildet und sind nicht änderbar:
Hat der Assistent die Arbeit der Projekterzeugung abgeschlossen, ist die Struktur in 'Projects' und 'Files' einsehbar. Abgesehen davon, daß eine Demo-Basisklasse (App.java) samt zugehörigem Unittest-Gerüst erzeugt worden sind, ist zu erkennen:
![]() |
Der "logischen" Sicht der IDE (in 'Projects') liegt eine maven-spezifikationskonforme Dateistruktur zugrunde, die sich mit jedem Werkzeug, welches in der Lage ist, mit Maven2-Projekten umzugehen, problemlos bearbeiten läßt. Für Maven2-Projekte ist das Gros der Werkzeuge der IDE darauf ausgelegt, die zugrundeliegende pom.xml zu modifizieren. Die Parallelen zeigen sich zuerst beim Blick in die "allgemeinen Eigenschaften" des Projektes (Rechtsklick auf das Projekt in 'Projects' -> "Properties"):
![]() |
Änderungen dort, etwa das Einstellen der im Quellcode verwendeten Java-Version (falls nicht unbedingt 1.4 erforderlich, ist zumindest 1.5 wegen Generics und der verbesserten for-Schleife doch empfehlenswert) unter "Properties" -> "Source", die direkt als "plugin"-Element in pom.xml übernommen wird:
![]() |
Theoretisch läßt sich diese Anwendung sofort ausführen - verschiedene Plugins für maven erlauben diese Art der Integration mit NetBeans - , allerdings muß zuvor noch definiert werden, welches die ausführbare Startklasse des Projektes ist, über "Properties" -> "Run":
![]() |
Danach läßt sich die Anwendung wie eine "herkömmliche" Java SE - Applikation aus der IDE heraus ausführen.
![]() |
Bislang hat die Verwendung von maven allerdings noch keinen nennenswerten Gewinn gegenüber dem herkömmlichen Build-Mechanismus gebracht. Um dies zu ändern, soll das leere Beispielprojekt um Code angereichert werden, der das Logo der NetBeans-Website in eine lokale Datei speichert und sich dabei des Apache Commons HttpClient bedient. Über die Website läßt sich dieser als Jar-Datei herunterladen und auch in einem ant-basierten Projekt leicht in den Classpath einfügen. Zur Nutzung in Maven2-Projekten findet sich der Code auch als Artefakt in den maven-Repositories, was in diesem Fall erforderlich sein wird.
Um Abhängigkeiten zu Maven2-Projekten hinzuzufügen, existieren zwei Wege. Unter Nutzung der IDE-Integration geschieht dies über Rechtsklick auf "Libraries" in einem geöffneten Projekt und Auswahl der Option "Add Library",...
![]() |
... die ein Eingabefenster zur Auswahl eines Maven2-Artefaktes erlaubt. Hierbei sind die Felder "GroupId", "ArtifactId" und "Version" eleganterweise in der Lage, Vervollständigungsvorschläge anzuzeigen für Artefakte, die im lokalen Maven2-Repository des Nutzers bereits vorhanden und bekannt sind. Um diese Vervollständigungen zu aktualisieren, indiziert die Maven-Integration gelegentlich dieses lokale Repository (was auf Unix-Systemen in .m2/repository im Home-Verzeichnis des Nutzers liegt). Bedarfsweise kann diese Indizierung auch manuell gestartet werden über 'Tools' -> 'Options' -> 'Miscellaneous' -> 'Maven2' -> 'Index Now', was je nach Umfang des Repositories einige Augenblicke in Anspruch nehmen kann:
![]() |
Für den HttpClient sollten die Werte wie im Beispiel übernommen werden, wobei für die Bedeutung der Felder auf grundlegende Maven2-Dokumentation verwiesen sei:
Nach Bestätigung wird die Bibliothek als Abhängigkeit zum Projekt hinzugefügt. Je nachdem, ob bereits im lokalen Repository vorhanden oder nicht, wird die Darstellung in 'Projects' ausfallen. So nicht vorhanden, werden diese rot markiert:
![]() |
Durch erneutes Ausführen von "Run" bzw. alternativ durch Rechtsklick auf das Projekt und Auswahl von "Clean and build" ändert sich dieser Zustand, die benötigte Bibliothek wird heruntergeladen, gleichermaßen werden auch eventuell durch commons-httpclient gegebene Abhängigkeiten aufgelöst und als "transitive dependencies" im Projekt angezeigt:
![]() |
Alternativ hierzu lassen sich Abhängigkeiten auch direkt in der pom.xml des Projektes definieren, die sich in 'Projects' im Unterordner 'Project Files' findet. Beide Wege sind gleichwertig:
![]() |
HttpClient client = new HttpClient(); HttpMethod getLogo = new GetMethod("http://www.netbeans.org/images/v5/nb-logo2.gif");
int status = client.executeMethod(getLogo); FileOutputStream logo = new FileOutputStream(System.getProperty("java.io.tmpdir")+File.separator+"nblogo.gif"); logo.write(getLogo.getResponseBody()); System.out.println("Logo erfolgreich heruntergeladen. HTTP-Status: " +status);
Danach sollte der Code mit <ALT>+<SHIFT>+<F> ordentlich formatiert werden, bevor mit <CTRL>+<SHIFT>+<I> der Bildschirm zur Definition der benötigten Imports angezeigt werden kann:
![]() |
Dieser erscheint im gegebenen Fall, da verschiedene Klassen über den Namen nicht eindeutig auffindbar sind und der Entwickler insofern zu entscheiden hat, welche Klasse des Namens HttpClient importiert werden soll. Nach Bestätigung mit 'Ok' verbleiben noch mehrere Markierungen im Code, die auf unbehandelte Exceptions zurückzuführen sind. Um die Fähigkeiten des NetBeans-Code-Editors zu nutzen, kann beispielsweise auf die rote Markierung vor der Zeile logo.write(... geklickt und die Option 'Surround Block with try-catch' gewählt werden:
![]() |
Danach sollte die Klasse korrekt und vollständig implementiert, das Projekt ausführbar sein. Nach einem erneuten Aufruf von 'Run' zeigt sich wiederum, wie maven das Projekt ausführt und mit knapper Meldung endet:
![]() |
So dies erscheint, sollte sich eine Datei 'nblogo.gif' auf der Festplatte finden, wahlweise unter '/tmp' (Unix-Systeme) oder im temporären Verzeichnis auf Windows-Plattformen ('C:/Temp'), und mit einem Bildbetrachter der Wahl zu öffnen sein.
Auch im Falle der Maven2-Integration sind die in NetBeans-Projekte komplett ohne die IDE verwendbar, lassen sich Standard-Ziele wie install, clean oder build korrekt ausführen (wozu allerdings eine vollständige Maven2-Installation außerhalb von NetBeans erforderlich ist):
![]() |
Schlecht reproduzierbar in Maven2 generell ist der im Java SE - Teil demonstrierte Versuch, das Projekt außerhalb der IDE auszuführen, da dies bei Maven2-Artefakten nicht erklärtes Ziel ist (weder ist im MANIFEST.MF der Jar-Datei eine Startklasse definiert, noch sind Verweise auf erforderliche Bibliotheken, wie hier den HttpClient, hinterlegt). Sollen Artefakte als "ausführbare .jar-Dateien" bereitgestellt werden, ist die Nutzung zusätzlicher (Maven2-)Plugins erforderlich, was allerdings, wie insgesamt Details zu Maven2, jenseits dieses Dokumentes liegt. Die Erklärungen zum 'assembly-plugin' bieten hierzu einen Lösungsweg, der sich sowohl mit als auch ohne NetBeans nutzen läßt.
| mvn-01-plugin.jpg | ![]() |
147377 bytes |
| mvn-02-project.jpg | ![]() |
30498 bytes |
| mvn-03-archetype.jpg | ![]() |
46462 bytes |
| mvn-04-pomxml.jpg | ![]() |
46126 bytes |
| mvn-05-newproject.jpg | ![]() |
59772 bytes |
| mvn-06-properties.jpg | ![]() |
92902 bytes |
| mvn-07-sourcelevel.jpg | ![]() |
62513 bytes |
| mvn-08-prerun.jpg | ![]() |
22521 bytes |
| mvn-09-postrun.jpg | ![]() |
116309 bytes |
| mvn-10-addlib.jpg | ![]() |
32119 bytes |
| mvn-11-artifact.jpg | ![]() |
16636 bytes |
| mvn-12-missingjar.jpg | ![]() |
11217 bytes |
| mvn-13-depsfine.jpg | ![]() |
30073 bytes |
| mvn-13-depspom.jpg | ![]() |
33485 bytes |
| mvn-14-imports.jpg | ![]() |
41953 bytes |
| mvn-15-exceptions.jpg | ![]() |
56701 bytes |
| mvn-16-run.jpg | ![]() |
15673 bytes |
| mvn-17-console-install.jpg | ![]() |
160719 bytes |