Tools. Tools. 1 von 58



Ähnliche Dokumente
ANT. Kurzvortrag von Manuel Schulze.

Eclipse und Java Einheit 06: Building Eclipse Projete mit Ant

JCoverage. Uni Kassel Projektarbeit Software Engineering Markus Pilsl & Marko Medved

Software-Engineering Grundlagen des Software-Engineering

Das Build Tool Ant. Sebastian Mancke,

Das Build-Tool ANT ETIS SS05

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

Software Engineering in der Praxis

Wie konfiguiriert man Eclipse (mit oder ohne Plugin) Erich Ehses

Versionsverwaltung mit SVN

Einführung in die Informatik Tools

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Softwaretests in Visual Studio 2010 Ultimate Vergleich mit Java-Testwerkzeugen. Alexander Schunk Marcel Teuber Henry Trobisch

Kurzanleitung zu XML2DB

Inhaltsverzeichnis. 1 Einleitung. Literatur. 1.1 CVS (Concurrent Version System) [Pru03, Zee02, Ced05]

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Framework zur Unterstützung von Unit-Tests

Einführung in Subversion

Testen mit JUnit. Motivation

Kurzanleitung zu. von Daniel Jettka

Software-Engineering Grundlagen des Software-Engineering 7.3 Sourcecode-Verwaltung mit Versionsmanagement-Systemen Einführung in Subversion (SVN)

Entwicklungswerkzeuge

Diplomarbeit. Konzeption und Implementierung einer automatisierten Testumgebung. Thomas Wehrspann. 10. Dezember 2008

Web-Technologien Kick-Start

Programmiertechnik II

ECLIPSE PLUG-IN. Redwood Anwendertage 2015

git & git-flow Jens Sandmann Warpzone Münster e.v. Jens Sandmann (WZ) git & git-flow / 31

Übung: Verwendung von Java-Threads

Möglichkeiten des Parallelbetriebs der VR-NetWorld Software Parallelbetrieb VR-NetWorld Software 4.4x und Version 5.0 ab der 2. Beta!

Support-Tipp Mai Release Management in Altium Designer

Versionsverwaltung GIT & SVN. Alexander aus der Fünten. Proseminar: Methoden und Werkzeuge, SS Lehrstuhl i9, Prof. Dr. T.

Praktische Übung 'JUnit-Test'

Java Kurs für Anfänger LMU SS09 Einheit 1 Javaumgebung

Kampf dem Fehlerteufel PMD, Findbugs und Checkstyle in großen Projekten

Einführung in Maven und GWT

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Eclipse 3.0 (Windows)

Hex Datei mit Atmel Studio 6 erstellen

SEP 114. Design by Contract

Software Configuration Management. Referat von Jens Zastrow Software Engineering Projekt WS 2001/2002

Einfu hrung in Subversion mit TortoiseSVN

Git in großen Projekten

Apache Subversion (SVN)

Versionskontrolle mit Subversion

2. ERSTELLEN VON APPS MIT DEM ADT PLUGIN VON ECLIPSE

FS cs108 Programmierpraktikum Subversion. Lukas Beck Cedric Geissmann Alexander Stiemer

Sourcecodeverwaltung

Crashkurs Subversion / Trac / Provisioning. Jan Zieschang, , Berlin

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Client-Server-Beziehungen

Pakete dienen dazu, die Software eines Projektes in größere inhaltlich zusammengehörige Bereiche mit eigenem Namen einzuteilen (siehe Java API).

SVN-Einführung für das SEP DS und CM. Julian Timpner, Stefan Brenner, Stephan Rottmann

Softwareprojekte mit Kultur

Connecting Content. User Manual. Version: 1.2

Java Kurs für Anfänger Einheit 5 Methoden

Installation und Inbetriebnahme von Microsoft Visual C Express

Maven 2 Softwareprojekte mit Kultur

B) Klassenbibliotheken Turtle und Util (GPanel, Console) installieren Ein Unterverzeichnis classes auf der Festplatte erstellen, z.b.

Einführung in Eclipse und Java

Software Qualität Übung 1

am Beispiel von JUnit

Installation einer C++ Entwicklungsumgebung unter Windows --- TDM-GCC und Eclipse installieren

MailUtilities: Remote Deployment - Einführung

CVS-Einführung. Sebastian Mancke,

Log xmllog textlog Log() start(filename) add(message) end() instance() Abbildung 7-10: Die Protokollierungs-API mit einer einfachen Fassade

Einführung in Javadoc

Java Einführung Programmcode

Programmieren in Java

C++ mit Eclipse & GCC unter Windows

JUnit - Test Driven Development. Bernhard Frey, Thorsten Stratmann, Jackson Takam, Michel Müller 1

Konfigurationsdateien mit Git verwalten

B) Klassenbibliotheken Turtle und Util (GPanel, Console) installieren Ein Unterverzeichnis classes auf der Festplatte erstellen, z.b.

Lehrstuhl für Datenverarbeitung. Technische Universität München. Grundkurs C++ Buildsysteme

Prinzipien Objektorientierter Programmierung

Agile Software Verteilung

Praktikum Ingenieurinformatik (PI)

Unit Tests und Fehlersuche

SSH Authentifizierung über Public Key

Java Entwicklung für Embedded Devices Best & Worst Practices!

Fortgeschrittenes Programmieren mit Java. Test Driven Development

Unit Testing mit JUnit. Dr. Andreas Schroeder

Konfiguration Management System. Konfiguration Management System. Versionierung Parallele Entwicklung Workspace

Java-Tutorium WS 09/10

CL-Mini-ABF. Kurzbeschreibung. Installation und Vorbereitung. Stand Ihre HTK-Filiale Michelstadt

Persönliche Build-Höllen für Jedermann Andreas Hartmann & Dr. Halil-Cem Gürsoy

Standard Daten-Backup-Script

Innere Klassen in Java

Software Engineering I

Tanuki Service Wrapper 101. JVM Verwaltung mit der Community Edition. Alexander Pacnik Karlsruhe,

Mobile-Szenario in der Integrationskomponente einrichten

SEW Übung EMFText. 1 Aufgabe. 2 Domänenbeschreibung. 3 Installation von Eclipse/EMFText. 4 Schritt-für-Schritt Anleitung. 4.

Java: Vererbung. Teil 3: super()

Objektorientierte Programmierung

8. Dokumentenverwaltung mit CVS eine Einführung

Workbooster File Exchanger Command Line Tool

Versionsverwaltung mit Mercurial für Einsteiger

OP-LOG

Folgende Voraussetzungen für die Konfiguration müssen erfüllt sein:

Anleitung zur Installation und Verwendung von eclipseuml 2.1.0

Unit Tests. Programmiermethodik. Eva Zangerle Universität Innsbruck

Transkript:

1 von 58

Überblick 2 von 58

Das Ziel Qualität Einige Gesichtspunkte verteilt über den gesamten Lifecycle Struktur und Übersichtlichkeit des Codes Leichte Änderbarkeit und Erweiterbarkeit Dokumentation (z. B. Code-Doku., Change- und Bugfix-Management) Geprüfte Korrektheit Ressourcenverbrauch (z. B. Laufzeit, Speicherplatz) Codekonsistenz Versionspflege Automatisierung von Abläufen beim Erstellen Überwachung und Protokollierung im Betrieb 3 von 58

Werkzeuge und Vorgehensweisen Beispiele: Style-Guides Autoformatierung vgl. Eclipse Audits Refactoring javadoc Code-Metriken Debugger Profiler Testtools z. B. für Unit-Testing Sourcecodeverwaltungssystem z. B. svn, git Build-Mechanismus z. B. ant, maven, gradle 4 von 58

Codeanalyse und Monitoring 5 von 58

Statische Codeanalyse Absicht Analyse der Software, ohne den Code auszuführen. Durchsuchen des (Quell-)Codes nach formalen Kriterien. Mögliche Untersuchungsgegenstände: Allgemeine syntaktische Konventionen (Namensrichtlinien, Formatierung). Programmierrichtlinien (Keine Ausgaben über System.out, kein Import über Wildcard, Verbot von bestimmten Abhängigkeiten) Allgemeine Qualitätsdefizite (mangelhafte Kapselung, Code-Duplikation) Hinweise auf mögliche Fehlerquellen Maßzahlen (Metriken) über die Komplexität (Lines of Code pro Methode, Ausführungspfade pro Methode, komplizierte Programmiermuster) IDE Checkstyle FindBugs PMD 6 von 58

Checkstyle Charakteristiken Für automatisierte Überprüfung (ursprünglich Syntax), in neueren Versionen auch Design-Probleme u. ä. Prüfungen sind konfigurierbar. Default-Konfiguration baut auf den "Sun Code Conventions" auf. Anwendungs- und Integrationsmöglichkeiten Command Line Tool IDE-Plugins, z. B. für Eclipse: Default-Konfigurationen schon vorhanden. siehe Preferences -> checkstyle Kann exportiert und den eigenen Bedürfnissen angepasst werden per Editieren der XML-Datei oder per Wizard Ant-Task bzw. Maven-Plugin für Integration in automatischen Build (s. u.) 7 von 58

FindBugs Bug-Kategorien Correctness Bug Höchstwahrscheinliche Fehler, die offenbar nicht das ausdrücken, was der Programmierer eigentlich wollte. Beispiele: wahrscheinliches Auftreten von NullPointerException Endlosrekursion Aufruf von String-Methoden ohne Abholen des Rückgabewertes (z. B. replace()). Bad Practice Verletzung von allgemein akzeptierten Programmierpraktiken. Beispiele: equals()-methode prüft nicht, ob Parameter den Wert null hat equals()-methode und hashcode()-methode werden nicht gleichzeitig überschrieben Dodgy Verwirrender Code oder solcher, der sehr leicht zu Fehlern führen kann. Beispiele: Switch-Fall-Through (Switch ohne Breaks) Redundanter Null-Check Performance u. weitere 8 von 58

Dynamische Code-Analyse Absicht: Analyse der Software bei der Ausführung. Im "Labor" oder auch in der realen Einsatzumgebung. Mögliche Untersuchungsgegenstände: Fehlersuche Performanz Speicherverbrauch Engpässe und Optimierungspotential 9 von 58

Debugging jdb oder in IDE integrierter Debugger Man beachte: Beim Übersetzen müssen Debug-Informationen (in den class-files) erzeugt werden (javac -g). wesentliche Aspekte Breakpoints Steps: over, into, out Inspektion von lokalen Variablen, Objekten und Call-Stack Watches: überwachte Ausdrücke Remote-Debugging: Debugger und überwachtes Programm laufen in verschiedenen Prozessen. 10 von 58

Profiling Zweck Analyse von Laufzeit-, Speicherverbrauch und Aufrufhierarchien für einzelne Programmteile (Pakete, Klassen, Methoden), Threads,... Aufdecken von "Hot Spots". Graphische Aufbereitung der Analyse-Daten. VM-Unterstützung JVM TI: Java Virtual Machine Profiling Interface Programmierschnittstelle zum Auslesen von Profiling Informationen Profiler-Beispiele Netbeans: integrierter Profiler VisualVM (teils in JDK) JProfiler YourKit 11 von 58

Monitoring Beispiel: JMX (Java Management Extension) Einsatzzweck Überwachen (Monitoring) und Steuern (Management) von Java-Ressourcen (insbes. Netze, Systeme, Anwendungen, Services) in verteilten Umgebungen. typische Anwendungssituationen Beispiel Abfragen und Verändern von Anwendungskonfigurationen Sammeln von Statistiken über das Verhalten einer Anwendung und Bereitstellen der Auswertungen Benachrichtigung über Zustandsänderungen und Fehlersituationen Ab Version 1.5 kann die JVM per JMX überwacht und gesteuert werden. Starten einer remote überwachbaren Applikation java -Dcom.sun.management.jmxremote.port=2000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false de.fhaugsburg.games.scrabblelauncher Zum Abrufen der Informationen Tool im jdk: jconsole bzw. jvisualvm 12 von 58

Logging 13 von 58

Überblick (1) Wesentliche Aufgaben eines Logging-Frameworks Einheitliche Programmierschnittstelle für alle Formen von Log-Meldungen. Unterstützung unterschiedlicher Wichtigkeitsstufen. Timestamps für Log-Meldungen Konfigurationsmöglichkeiten in Richtung Welche Stufen werden geloggt? Wohin wird geloggt? In welchem Format? Gruppierungsmöglichkeit, abhängig von der Herkunft der Meldungen mit unterschiedlicher Konfiguration der Gruppen. 14 von 58

Überblick (2) Grundstruktur eines Logging-Frameworks Quelle: Logging-Guide (Sun) Gebräuchliche Logging-Frameworks Klassiker: Log4J (Apache), Commons-Logging Java-Logging (das Logging-Framework des Jdk) SLF4J neuer: tinylog, Logback 15 von 58

Java-Logging: Meldungen erstellen (1) Beispiel: package logex; import java.util.logging.level; import java.util.logging.logger; public class LoggingDemo { private static Logger logger = Logger.getLogger(LoggingDemo.class.getName()); public static void main(string[] args) { logger.log(level.fine,"i am trace"); logger.fine("i am trace at the same level"); logger.log(level.warning,"i am a warning"); logger.log(level.severe,"i am telling about a severe problem..."); logger.log(level.severe, "an exception occurred", new NullPointerException("I am a pretender")); } } // a somehow more efficient version if (logger.isloggable(level.finest)) logger.log(level.finest, "I am a very fine trace message"); 16 von 58

Java-Logging: Meldungen erstellen (2) Die Log-Level für das Abschicken SEVERE (highest value) WARNING INFO CONFIG FINE FINER FINEST (lowest value) weitere Konstanten für das Filtern beim Logger oder Handler ALL OFF 17 von 58

Java-Logging: Konfiguration (1) Eine einfaches Beispiel: # Level for root logger.level= INFO # specific loggers and there level logex.loggingdemo.level = FINE # a parent logger logex.level = SEVERE handlers= java.util.logging.consolehandler # Limit the messages printed on the console to the specified level and above. java.util.logging.consolehandler.level = FINE # Define the format of the console output java.util.logging.consolehandler.formatter = java.util.logging.simpleformatter 18 von 58

Java-Logging: Konfiguration (2) Ergänzungen für File-basiertes Logging handlers= java.util.logging.filehandler, java.util.logging.consolehandler # file output is in user's home directory. java.util.logging.filehandler.pattern = %h/java%u.log # write records in XML format java.util.logging.filehandler.formatter = java.util.logging.xmlformatter Die Handler-Klassen MemoryHandler (zum Puffern im HS und Ausgabe an einen nachfolgenden Handler) StreamHandler ConsoleHandler FileHandler SocketHandler und eigene... 19 von 58

Java-Logging: Konfiguration (3) Vorgabe des Konfigurationsfiles Ein Default-File im Jdk unter lib/logging.properties. Festlegen eines eigenen Konfig-Files über die System-Property java.util.logging.config.file: Programmaufruf: java -Djava.util.logging.config.file=... Alternativ kann auch eine Klasse als Konfigurations-Input spezifiziert werden. Die Logger-Hierarchie Verwaltung durch den LogManager Ein Root-Logger mit leerem Namen: Zugriff: Logger.getLogger("") Hierachie ergibt sich aus dem hierarchischen Aufbau der Logger-Namen. Zum Bestimmen des Log-Levels eines Loggers wird in der Hierarchie nach oben gelaufen, bis bei einem Logger ein gesetztes Level gefunden wird. 20 von 58

Unit-Testing 21 von 58

Hintergrund Stichworte Test-Driven Development, Test-First-Development Unit-Tests Testautomatisierung Regressionstests Mock-Objekte Testframeworks: z. B. JUnit vgl. System.out.println(), Debugger und assert - Statement. Ziele Isoliertes Testen von einzelnen Einheiten (z. B. Klassen). Testcode für die Testfälle in eigene Klassen auslagern. Tests solle regelmäßig und automatisiert ablaufen können. Testinfrastruktur bereitstellen. hohe Testabdeckung 22 von 58

Unit-Testing: Die Quintessenz Entwicklertest Primär zum Testen kleinerer Einheiten (oft Klassen) in isolierter Form: Testkörper. Ein oder mehrere Testklassen pro Testkörper. Ein oder mehrere Testfälle pro (testwürdiger) Methode. Jeder Testfall wird als Testmethode ausgeführt. Pro Testfall wird eine Instanz der Testklasse erzeugt. Die Testfälle werden grundsätzlich unabhängig voneinander (in beliebiger Reihenfolge) ausgeführt. In Fixtures werden (allgemeine) Vorarbeiten ausgeführt. Strukturierungshilfe: Versammle die Testfälle mit gemeinsamem Fixture in einer Testklasse. Testklassen können zu Suiten zusammengefasst werden. Insbesondere bei häufigen Änderungen sind automatisierte Unit-Tests unumgänglich: Regressionstests. Einbindung in den Build-Prozess (vgl. Maven-Standardarchetyp und Eclipse-Integration). Ziel: grüner Balken! 23 von 58

Unit-Testframeworks: Die Historie Die Wurzeln Erich Gamma und Kent Beck auf dem Flug von Zürich nach Atlanta zur OOPSLA JUnit 3.x Ableiten von der TestCase-Klasse. Damit werden assert...- und fail-methoden geerbt. Namenskonvention: Testfall-Methoden beginnen mit test... setup() und teardown()-methode für Fixture-Aufbau und Aufräumen TestNG stärkere Gruppierungsmöglichkeit für Testfälle Definition von Abhängigkeiten bei den Testfällen. Eigenes HTML-Reporting... JUnit 4.x Statt Namenskonventionen Annotationen. Statischer Import für die assert...- und fail-methoden Übernahme von TestNG-Features... 24 von 58

Ein Beispiel mit JUnit4 (1) Der Test-Körper public class Money { public final int amount; public Money(int amount) { if (amount < 0) throw new NegMoneyException("amount would be: " + amount); this.amount = amount; } public Money add(money money) { return new Money(this.amount + money.amount); } public Money subtract(money money) { return new Money(this.amount - money.amount); } public boolean equals(object o) { if (!(o instanceof Money)) return false; Money money = (Money) o; return this.amount - money.amount == 0; } } public String tostring() { return "Money: " + amount; } 25 von 58

Ein Beispiel mit JUnit4 (2) Festlegen der Test-Umgebung (Fixture) import static org.junit.assert.*; import org.junit.after;... public class MoneyTest { private final Money money1 = new Money(30); private final Money money2 = new Money(20); @Before public void setup() {... } @After public void teardown() {... } @BeforeClass public static void setupbeforeclass() {... } @AfterClass public static void teardownafterclass() {... } 26 von 58

Ein Beispiel mit JUnit4 (3) Die Testmethoden @Test public void testequals() { asserttrue("money objects with equal amount must be equal", money1.equals(new Money(30))); assertfalse("money objects with different ammount cannot be equal", money1.equals(money2)); } @Test public void testadd() { assertequals("30+20=50",new Money(50), money1.add(money2)); } @Test public void testsubtract() { assertequals("30-20=10",new Money(10), money1.subtract(money2)); } @Test(expected=NegMoneyException.class) public void testnegativemoney() { money2.subtract(money1); } 27 von 58

Test durchführen 1. Möglichkeit: StdAlone Einen Testrunner verwenden (Bestandteil von JUnit). 3. Möglichkeit: IDE z. B. Eclipse: vgl. run-dialog Das JAR für JUnit muss dabei im Build-Path des Projektes sein. 3. Möglichkeit Integration in einen Build-Prozess (vgl. ant oder maven) 28 von 58

Weitere Features von JUnit 4.x vgl. JUnit-Dokumentation Parametrisierte Tests: Testmethode durchläuft mehrere Fälle, die als Parameter durch eigene Methode (markiert durch @Parameters)bereitgestellt werden Zeitconstraints über timeout-parameter von @Test @Ignore-Annotation Hamcrest-Matcher als Comfort-Methoden mit präziseren Fehlermeldungen in Verbindung mit assertthat()-methode. Beispiel: assertthat(teststring, both(containsstring("a")).and(containsstring("b"))) Kategorien durch Markierung für getrennte Ausführung Rules (@Rule, Standardimplementierungen und Templates) zum komfortablen Eingriff vor und nach der Testausführung (Bsp. temporäre Files und Exception-Überprüfungen) Class-Rules @FixMethodOrder zur sortierten Ausführung von Testmethoden (Strategie als Parameter, deterministischer Default: MethodSorters.DEFAULT), ab JUnit 4.11 29 von 58

Behandlung von Abhängigkeiten Die gängigen Möglichkeiten Stubs stellen eine rudimentäre Implementierung einer Schnittstelle zur Verfügung Dummys simulieren Verhalten für bestimmte Testfälle Mocks s. u. Voraussetzungen Programmierung gegen Schnittstellen einfache Ersetzbarkeit von Implementierungen (Konfigurationsaufgabe) 30 von 58

Mocking Absicht: Auch Objekte, die von anderen Objekten abhängen, isolierten Tests zugänglich machen. Definition: Mock-Objekt Wirkt als Dummy-Objekt an Stelle eines realen Objekts, das nicht verfügbar ist oder in einem Testfall schlecht benutzbar ist (Datenrückgabe, Exceptions). Zusätzlich: Mock-Objekte sollen Erwartungen formulieren und einen Selbstvalidierungsmechanismus besitzen. Mocking-Frameworks Die Gebräuchlichsten JMock EasyMock Mockito Gemeinsamkeiten Domänenspezifische Sprache, die die Java-Syntax benutzt. Damit können Erwartungen im Hinblick auf Methodenaufrufe (wie oft, Parameter) sowie Rückgabewerte für die Aufrufe formuliert werden. Mockobjekte werden daraus automatisiert erstellt. 31 von 58

TDD: Test-Driven-Development (1) Grundprinzip Testfall wird vor der Implementierung der Funktion erstellt (Test-First). Entwicklung in kleinen Schritten, die jeweils getestet werden. Testfälle müssen in kurzer Zeit durchgeführt werden können. Testfälle repräsentieren einen Teil der Spezifikation und treiben die Entwicklung. Integration Rahmen: agile Vorgehensweise TDD und Refactoring: automatisierte Tests sorgen für funktionale Integrität Refactoring sorgt für strukturelle Integrität Nur getesteter Code wird in Source-Code-Verwaltungssystem eingecheckt. Häufige Integration auf Integrationsserver. 32 von 58

TDD: Test-Driven-Development (2) Das Vorgehen im Einzelnen Die elementaren Schritte Testfall erstellen. Kompilierung scheitern lassen. Gerade soviel Code erstellen, dass der Test fehlschlägt. Test erfüllen Die Farbübergänge des Erfolgsbalkens rot --> grün --> rot --> grün (Erster Übergang betrifft dabei Compilierung) Die Behandlung von Bugs Ähnlich Erst Testfall erstellen, der (infolge des Bugs) fehlschlägt,... 33 von 58

Build-Management 34 von 58

Überblick Grundprinzipien von Build- Im Rahmen eines Projektes gibt es verschiedene Teilziele (z. B. Initialisieren, Übersetzen, Release fertigstellen, Doku. erstellen, Aufräumen): Targets. Für jedes Ziel müssen bestimmte Aufgaben erledigt werden (z. B. Verzeichnisse erstellen oder löschen, Dateien kopieren, javac oder javadoc oder jar aufrufen): Tasks. Die Teilziele können Abhängigkeiten besitzen (z. B. Übersetzen vor Testen): Dependencies. Tasks werden nur ausgeführt, falls erforderlich (z. B. Übersetzen nur dann, wenn nötig): Incremental Build. Für Flexibilität und Wiederverwendung ist Parametrisierung erforderlich (z. B. Pfade, Compilerdirektiven): Properties. Targets, Tasks, Dependencies etc. werden in Konfigurationsdateien festgelegt: Build-Files. Historie "althergebrachte" make, gnumake, nmake Einschränkungen bezogen auf eine plattformspezifische Shell: Shell-Kommandos als Tasks, Bezug zu Shellvariablen Aktuelle Build- in der Java-Welt Ant, Maven, Gradle 35 von 58

Ant: Charakteristiken plattformunabhängiges Build-Tool Buildfile hat XML-Format Es sind viele Standardtasks vorhanden. Parametrisierung über Java-Properties. Weitere Tasks können in Form von Java-Klassen definiert werden. Auf teilweise mächtige Shell-Kommandos muss verzichtet werden (zumindest deren direkte Einbindung). 36 von 58

Ant: Beispiel Build-File (1) <project name="helloproject" default="dist" basedir="."> <!-- == set global properties for this build == --> <property environment="env" /> <property name="appname" value="greetings" /> <!-- base directories --> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <property name="lib" location="lib"/> <!-- source directories --> <property name="src.main" location="${src}/main"/> <property name="src.test" location="${src}/test"/> <!-- build directories --> <property name="build.main" location="${build}/main"/> <property name="build.test" location="${build}/test"/> <property name="build.testreports" location="${build}/testreports"/> <property name="build.javadoc" location="${build}/javadoc"/> <property name="build.log" location="${build}/log"/> <property name="build.dist" location="${build}/dist"/> 37 von 58

Ant: Beispiel Build-File (2) <!-- == filesets ==--> <fileset id="mainsources" dir="${src.main}"> <include name="**/*.java" /> </fileset> <fileset id="testsources" dir="${src.test}"> <include name="**/*test.java" /> </fileset> <!-- === external libs classpath === --> <path id="externallibs"> <pathelement location="${lib}/junit.jar" /> </path> 38 von 58

Ant: Beispiel Build-File (3) <!-- ================================================= --> <target name="init"> <!-- Create the build directories --> <mkdir dir="${build.main}" /> <mkdir dir="${build.test}" /> <mkdir dir="${build.testreports}" /> <mkdir dir="${build.javadoc}" /> <mkdir dir="${build.log}" /> <mkdir dir="${build.dist}" /> <!-- Create the time stamp --> <tstamp/> <!-- Create log file --> <record name="${build.log}/build-${dstamp}-${tstamp}.log" /> </target> <!-- ================================================= --> <target name="compile" depends="init" description="compile all" > <javac srcdir="${src.main}" destdir="${build.main}"> <classpath refid="externallibs" /> </javac> <javac srcdir="${src.test}" destdir="${build.test}"> <classpath> <pathelement location="${build.main}" /> <path refid="externallibs" /> </classpath> </javac> </target> 39 von 58

Ant: Beispiel Build-File (4) <!-- ================================================= --> <target name="test" depends="compile" description="unit testing" > <delete dir="${build.testreports}" /> <mkdir dir="${build.testreports}" /> <junit printsummary="yes" fork="yes"> <classpath> <pathelement location="${build.main}" /> <pathelement location="${build.test}" /> <path refid="externallibs" /> </classpath> <formatter type="plain" /> <batchtest todir="${build.testreports}"> <fileset refid="testsources" /> </batchtest> </junit> </target> <!-- ================================================= --> <target name="dist" depends="test" description="generate application jar" > <jar destfile="${build.dist}/${appname}-${dstamp}.jar"> <fileset dir="${build.main}"> <include name="**/*.class" /> </fileset> </jar> </target> 40 von 58

Ant: Beispiel Build-File (5) <!-- ================================================= --> <target name="clean" description="clean up" > <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}"/> <delete dir="${dist}"/> </target> <!-- ================================================= --> <target name="doc" depends="init" description="generate javadocs" > <javadoc destdir="${build.javadoc}" windowtitle="${appname} Dokumentation"> <fileset refid="mainsources" /> <classpath> <path refid="externallibs" /> </classpath> </javadoc> </target> <!-- ================================================= --> <target name="run" depends="compile" description="run appl. from the build "> <java classname="hi.hello"> <arg value="bob" /> <classpath> <pathelement path="${build.main}" /> </classpath> </java> </target> 41 von 58

Ant: Beispiel Build-File (6) <!-- ================================================= --> <target name="rundist" depends="dist" description="run the distribution"> <java classname="hi.hello"> <arg value="fred" /> <classpath> <fileset dir="${build.dist}"> <include name="**/*.jar"/> </fileset> </classpath> </java> </target> <!-- ================================================= --> <target name="all" depends="clean, dist, doc" description="clean, generate the distribution and the docu" /> </project> 42 von 58

Ant: Ausführen von Build-Files Syntax ant [options] [target [target2 [target3]...]] Beispiele für options -f <buildfilename> -D<property>=<value> -propertyfile <name> 43 von 58

Maven: Motivation Vereinheitlichung von Build-Prozessen für Opensource-Projekte Ant: Toolbox zum Erstellen von Builds --> Maven: Standards und Muster für Projektmanagement im Hinblick auf vereinheitlichte, wiederverwendbare Builds Die üblichen Aufgaben: Prepare, Compile, Assemble, Test, Run, Deploy,... Bereitstellen von Bibliotheken und Maven-Erweiterungen (Plugins) in zentralen Repositorys Basierend auf Abhängigkeitsbeziehungen werden die benötigten Bibliotheken aus den Repositories automatisch heruntergeladen. Fokus: "Building the Application" not "Building the Build" 44 von 58

Die Prinzipien von Maven Convention over configuration Ein standardisiertes Verzeichnissystem für Projekte Ein primäres Ergebnis pro Projekt Standards für Namenskonventionen Declarative execution POM (Project Object Model) Vererbungsprinzip und Basis-POM Reuse of build logic Separation of concerns durch ein Plugin-Konzept Deklarative Ausführung der Plugins Coherent organization of dependencies Artefact A (JAR,...) hängt ab von Artefact B version x Repositories (remote, local) Abhängigkeiten werden durch Nachschlagen in den Repositories aufgelöst Transitive Abhängigkeiten werden unterstützt 45 von 58

Maven: Beispiel POM <project xmlsn="... > <groupid>de.fhaugsburg.prog</groupid> <artifactid>junit4demo</artifactid> <packaging>jar</packaging> <version>1.0-snapshot</version> <build> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-compiler-plugin</artifactid> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>4.0</version> <scope>test</scope> </dependency> </dependencies> </project> 46 von 58

Builds und IDE am Beispiel Eclipse Die wesentlichen Eigenschaften Ein integrierter Build-Mechanismus als Default (siehe Project Properties --> Builders) Eigene Builder können dort definiert werden (z. B. ant-basiert) Ant-Buildfiles können in eigenem View ausgeführt werden. Maven kann per Plugin integriert werden. Eigener Projekttyp Maven-Projekt: Beim Import werden alle Abhängigkeiten in den Classpath aufgenommen. 47 von 58

Versionsverwaltung 48 von 58

Versionsverwaltungssysteme allgemein Das Anliegen Zentrale Ablage von Verzeichnissen und Dateien wie z. B. Quellcodes u. ä.. Verwaltung von unterschiedlichen Versionsständen. Dabei werden jeweils gespeichert: die Änderungen im Vergleich zur Vorgängerversion (Platzersparnis!), Metainformationen wie Benutzer und Änderungs-Kommentar. Gemeinsames Arbeiten von verschiedenen Entwicklern an diesen Dateien soll möglich sein, mit Konfliktauflösung. Abspalten und Zusammenführen von Entwicklungszweigen ist zu unterstützen. Wichtige Versionsverwaltungssysteme CVS (Concurrent Versioning System): ein Vorläufer SVN (Subversion) GIT und einige kommerzielle Programme 49 von 58

Die wichtigsten Eigenschaften von SVN zentrales Repository und lokale Arbeitsbereiche: Check-In, Check-Out Versionierung von Dateien und Verzeichnissen (Dabei Berücksichtigung von Löschen und Umbenennen) Atomare Check-Ins Parallelität: Unterstützung von Lock-Modify-Unlock und Copy-Modify-Merge Unterstützung von Metadaten (Properties für Elemente im Repository) flexible Client-Server-Struktur (lokaler File-Zugriff, svn-server oder Apache-Modul) Festlegen von benutzerbezogenen Zugriffsbeschränkungen. 50 von 58

Zentrale Konzepte von SVN Revisions und Changesets Jede Transaktion im Repository erzeugt eine neue (fortlaufende Revisionsnummer). Der aktuelle Stand im Repository wird dieser Revision zugeordnet (Repository in Revison x). Die Menge der geänderten Dateien und Verzeichnisse, ausgehend von der vorhergehenden Revision, nennt man Changeset. Trunk, Tags und Branches Trunk: Der Hauptenwicklungspfad Linearer Entwicklungspfad: Codefreeze während der Vorbereitung einer Release erforderlich. Branches: Verzweigungen, um parallele Fortentwicklung von Versionen zu ermöglichen Problem: spätere Zusammenführung von Branches Tag: Markierung einer Version zu einem Zeitpunkt (Revision) durch einen frei wählbaren Bezeichner. Schnitt durch das Repository i. d. R. als potentieller Wiederaufsetzpunkt 51 von 58

Release-Planung zugehörige Branches und Tags mögliche Optionen Release-Branch (für Main-Release) wird offengehalten, solange das Release beim Kunden im Einsatz ist und evtl. Erweiterungen oder Fehlerbehebungen in Minor-Releases erfolgen kann. Release-Branch wird nach Fertigstellung des Releases gelöscht. Patch-Releases erfordern eine Neuanlage eines Branches auf Basis des REL-Tags des Releases. 52 von 58

typische Repository-Struktur in SVN projekt +--trunk +--src... +--tags +--PREP-1.0.0 +--src... +--REL-1.0.0... +--branches +--RB-1.0.0... 53 von 58

Verwaltung des SVN-Repositories Shell- svnadmin, svn Sowohl für ein lokales Repository als auch Remote-Repository einsetzbar Datei-Explorer Beispiel Windows: Integration mit Tortoise IDEs Beispiel Eclipse: Plugins Subclipse und Subversive 54 von 58

SVN: Der Start Details siehe http://svnbook.red-bean.com/ Erzeugen eines Repositorys svnadmin create.../svn-repos/myproject Benutzer- und Zugriffsrechte festlegen Dateien svnserve.conf passwd authz im Verzeichnis myproject/conf Start des Subversion-Servers dedizierter SVN-Server: snvserve -d -r.../svn-repos Testen der Verbindung svn list svn://localhost/myproject Konfiguration von Client-Properties (Bsp. Editor für Änderungskommentare festlegen) Datei config unter Unix im Verzeichnis <home>/.subversion unter Windows im Ordner C:\Dokumente und Einstellungen\<username>\Anwendungsdaten 55 von 58

Zentrale Kommandos zur Versionsverwaltung (1) Projektstruktur anlegen in temporärem Verzeichnis Verzeichnisse trunk, branches, tags und ggf. Unterverzeichnisse anlegen im temporären Verzeichnis: svn import svn://localhost/myproject --message "mein Kommentar" --username <root> --password <root> (Wenn die Optionen fehlen, werden sie interaktiv abgefragt) Check-out des Arbeitsbereiches svn checkout svn://localhost/myproject/trunk Achtung: Metadaten von SVN in Unterverzeichnissen.svn 56 von 58

Zentrale Kommandos zur Versionsverwaltung (2) Aktualisieren des lokalen Arbeitsbereiches svn update (im Hauptverzeichnis des Checkouts oder Unterverzeichnissen) Regeln beim update: Falls lokal keine Änderung durchgeführt wurde, wird eine evtl. vorhandene neuere Revision im Repository ausgecheckt. Falls lokal eine Änderung da, aber keine neuere Revision im Repository da ist, wird die Datei als modified markiert. Falls lokal eine Änderung da und eine neuere Revision im Repository vorhanden ist, wird versucht diese lokal mit der lokalen Kopie zu mergen (nur bei Textdateien). Falls die Unterschiede gleiche Bereiche betreffen, wird lokal eine Variante erzeugt, die beide Versionen der unentscheidbaren Bereiche markiert darstellt. In diesem Fall manuelle Auflösung erforderlich. 57 von 58

Zentrale Kommandos zur Versionsverwaltung (3) Versionen vergleichen svn diff Hinzufügen von neuen Verzeichnissen und Dateien svn add Lokale Änderungen in das Repository aufnehmen svn commit Gelingt nur, wenn Revision im Repository und lokalen Arbeitsbereich identisch sind. Ansonsten vorher update mit evtl. Konfliktauflösung durchführen Zustandsinformationen abholen svn status 58 von 58