Obsah

Beruška

Maven

  • Projekt od Apache, 2001
  • Původně součástí knihovny Jakarta Alexandria
  • Apache License 2.0
  • http://maven.apache.org/

  • Software pro správu projektů a automatizované sestavování


Maven logo

Kompilace z příkazové řádky

compile

mkdir -p target/classes/ 
javac -cp lib/log4j-1.2.8.jar src/ -d target/classes/ 
cp `find src/ -type f | grep -v *.java` target/classes/ 
jar -c target/example-1.0.jar target/classes/

clean

rm -r target/
  • Pamatujete?
  • Tohle umí Maven taky :-)

Kompilace v Antu

$ ant dist

<project name="example" default="compile" basedir=".">
    <property name="app.name" value="example"/>
    <property name="app.version" value="1.0"/>
    <property name="build.home" value="${basedir}/target" />

    <target name="clean" description="Delete old build directory">
        <delete dir="${build.home}" />
    </target>
    <target name="dist" depends="compile">
        <jar destfile="${build.home}/${app.name}${app.version}.jar">
            <fileset dir="${build.home}/classes"><include name="**/*.*" /></fileset>
        </jar>
    </target>
    <target name="compile" description="Compile project">
        <mkdir dir="${build.home}/classes/" />
        <javac srcdir="${basedir}/src/java" destdir="${build.home}/classes">
            <classpath>
                 <pathelement location="${basedir}/lib/log4j-1.2.8.jar" />
            </classpath>
        </javac>
    </target>
</project>

  • Obsah build.xml
  • Vidíme definice několika příkazů
  • Jsou zde vidět definice závislosti
  • Jednoduché :-)

Kompilace v Mavenu

KočkaObsah pom.xml:
$ mvn package
<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>cz.softeu</groupId>
  <artifactId>test</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
  • pom.xml odpovídá build.xml
  • jednoduchý skript
  • mvn package = kompilace a sestavení JARu
  • Jedna definice závislosti

Ant vs Maven

Ant logo
  • Ant
    • programátorský přístup
    • každý projekt má velmi odlišné skripty

  • Maven
    • deklarativní přístup
    • projekty mají unifikovanou strukturu
Maven logo

→ lepší znovupoužitelnost u Mavenu

  • Maven - standardizuje
  • Ant - systém pravidel a závislostí
  • Vysvětlit proč jsem přešel na Maven

U složitějšího

  • Ant: Vezmi překladač, zkompiluj tyto zdrojové soubory a výsledek zabal jako JAR. Pak z balíku PMD použij nástroj PMD a spusť analýzu nad těmito zkompilovanými soubory. Pak v dalším JARu najdi nástroj Cobertura, tyto class soubory instrumentuj do tohoto adresáře, spusť testy, ale použij instrumentované soubory a vygeneruj report.
  • Maven: Chci vytvářet JAR, zde jsou zdrojové texty programu, zde jsou zdrojové texty testů, chci pustit PMD a provést měření pokrytí testy.


Adresářová struktura

  • pom.xml

  • src/main/java
  • src/main/resources
  • src/main/webapp

  • src/test/java
  • src/test/resources
  • POM = Project Object Model
  • Adresářová struktura je ukázkou standardizace

Maven a příkazová řádka

Koza šrouborohá
  • mvn
    • compile
    • test
    • package
    • install

    • clean
    • site
  • Jsou to zároveň i fáze sestavení
  • Vycheckoutuju a spustím mvn eclipse:eclipse
  • Do netbeans je plugin

groupId/artifactId

  • Identifikace součástí pro Maven
    • <groupId />
    • <artifactId />
    • <version />
  • Příklad:
    • Zápis v XML:
      <groupId>cz.softeu</groupId>
      <artifactId>my-app</artifactId>
      <version>1.0-SNAPSHOT</version>
    • Zkráceně: cz.softeu:my-app:jar:1.0-SNAPSHOT
    • Přeloženo na:
          cz/softeu/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.pom
          cz/softeu/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT.jar
          cz/softeu/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT-sources.jar
          cz/softeu/my-app/1.0-SNAPSHOT/my-app-1.0-SNAPSHOT-javadoc.jar
  • SNAPSHOT = vývojová
  • Identifikuje pluginy, závislosti, projekty, ...
  • SNAPSHOT – jedná seo o vývojovou verzi
  • Pokud verze neobsahuje SNAPSHOT, nesmí se soubor již měnit (tj. nová verze má jiné číslo)

pom.xml

Lvice
<project>
  <modelVersion>4.0.0</modelVersion>

  <groupId>cz.softeu</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
...
  • packaging – jar, war, maven-plugin, pom, ejb, ear, rar, par

pom.xml – informace o projektu

<project>
...
  <name> Ukázkový projekt </name>
  <description> Ukázkový projekt do mé přednášky </description>
  <url> http://blog.softeu.cz/ </url>
  <inceptionYear> 2007 </inceptionYear>
  <licenses> LGPL </licenses>
  <organization> SoftEU s.r.o </organization>
  <developers>
     <developer>
        <id>fers</id>
        <name>Petr Ferschmann</name>
        <email>pferschmann (at) softeu (.) com</email>
        <organization>SoftEU s.r.o.</organization>
        <timezone>+1</timezone>
     </developer>
  </developers>
  
<contributors>...</contributors> ...
  • developers - hlavně pro site a generované stránky.
  • Licence - možná bude podpora schválení licence. Hlavně pro sunovské jary

pom.xml – závislosti

Psoun prériový
<project>
...
  <dependencies>
        <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
        </dependency>  
  </dependencies>
  
  <properties>
        <mojePromenna>hodnota</mojePromenna>
        <junit.version>3.8.1</junit.version>
  </properties>
...
  • scope - test, compile, runtime, provided
  • tranzitivní závislosti
    • Odpovídá linuxovým balíčkům :-)
    • Maven neumí provides
    • Java Module System potvrzuje potřebnost tohoto - bude jistě kooperace
    • Zmínit Seam a profily (např. Hibernate)
  • <optional/> - aplikace může být použitelná i bez ní
  • zmínit proměnné ${junit.version}

pom.xml – build

<project>
...
  <build>
       <defaultGoal> install </defaultGoal>
       <finalName> application-${pom.version} </finalName>
       
       <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>

                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
       </plugins>
  </build>
...
  • ${pom.version} - pomocí ${pom.xxx} můžu přistupovat ke všemu a názvy odpovídají položkám v pom.xml
  • Takto nastavuji target 1.5 a utf-8 pro compiler
  • Zmínit <configuration/>

pom.xml – antrun

...
   <build>       
       <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>vypis</id>
                        <phase>generate-sources</phase>
                        <configuration>
                            <tasks>
                                <echo message="Project is ${pom.version}"/>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
       </plugins>
   </build>
...
  • co je antrun
  • zmínit <executions/>
  • antrun má goal 'run' (tj. antrun:run) a chci jej pustit ve fázi generate-sources

pom.xml – dědičnost

  • Dědičnost vs agregace
  • Dědičnost:
    <build>
        <parent>
            <groupId>cz.softeu.parent</groupId>
            <artifactId>parent-project</artifactId>
            <version>1.10</version>
        </parent>
  • Dojde ke sloučení rodičovského a aktuálního pom.xml.
  • mvn help:effective-pom

  • Jako kdyby jste sloučili XML přes sebe
  • Super pom.xml

pom.xml – profily

Osel somálský
  • Adaptace pro různé prostředí/situace:
   ...
    <profiles>
        <profile>
            <id>test</id>
            <properties>
                <my.skip.test>false</my.skip.test>
            </properties>
        </profile>
        
        <profile>
            <id>fers</id>
            <activation>
                <property>
                    <name>user.name</name>
                    <value>fers</value>
                </property>
            </activation>
        </profile>
    ...
  • Profily mohou obsahovat téměř to samé co pom.xml
  • Ruční aktivace -Ptest
  • Automatická aktivace (<activation/>), lze použít os.name
  • Aktivace přes settings.xml
  • Aktivace: pro akci, testovací prostředí, dle systému.
  • Osel: toto je fotografie 20% světové populace osla somálského

Multiprojekt

  • common – obecné části
  • remote – API pro WebServices
  • web – webová část (war)
  • ear – Java EE archív


    |-- pom.xml
    |-- common
    |   `-- pom.xml
    |-- remote
    |   `-- pom.xml
    |-- web
    |   `-- pom.xml
    `-- ear
        `-- pom.xml
  • milión pomů
  • závisí na stejných verzích knihoven
  • má vnitřní závislosti (vše závisí na common, web závisí na remote, ...)
  • má stejná nastavení pro pluginy
  • jednotné nástroje týmové práce (sledování chyb, verzovací systém, ...)

Multiprojekt – pom.xml

<project>
    ...
    <packaging>pom</packaging>
    ...
    <modules>
        <module>common</module>
        <module>remote</module>
        <module>web</module>
        <module>ear</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.3.1</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    ...
  • pokud odvodíme od tohoto projektu, můžeme zde udělat centrální nastavení
  • dependencyManagement vs dependency
    • Chceme nastavit verze závislostí
    • v jednotlivých podprojektech závislosti.
  • Kompilace mezi závislostmi - nedokáže to automaticky detekovat změny a přeložit jen něco
  • Maven řeší vnitřní závislosti

Multiprojekt 3

Panda červená
  • Multiprojekt se skládá z více projektů
  • Dědičnost vs agregace

  • mvn package – sestaví JAR v target/
  • mvn install – nakopíruje JAR do ~/.m2/repository
  • Závislosti jsou brané z ~/.m2/repository/
  • pokud odvodíme od tohoto projektu, můžeme zde udělat centrální nastavení
  • dependencyManagement vs dependency

Stránka projektu

Maven logo
  • Maven umí vygenerovat stránku projektu mvn site.
  • Generuje reporty:
    • Pokrytí testy (Cobertura)
    • Výsledky testů (Surefire)
    • Duplicita kódu (CPD)
    • JavaDocs
    • JDepend
    • PMD
    • FindBugs
    • StatSCM
    • JXR
  • APT
    • Lze psát vlastní stránky – podobné wiki.
    • Možno exportovat do HTML, PDF, RTF, ...
  • Některé projekty používají i jako veřejnou stránku.

Stránka projektu 2

Site

Stránka projektu 3

Site 2

Site – výsledky testů

<project>
  ...
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-report-plugin</artifactId>
      </plugin>
      
      <!-- kvůli odkazům do zdrojových textů -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jxr-plugin</artifactId>
      </plugin>
    </plugins>
    ...
  
  • Ukázková stránka

Site – výsledky testů

Surefire

Site – pokrytí testy

Java code
<project>
  <reporting>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>cobertura-maven-plugin</artifactId>
        </plugin>        
            

Site – pokrytí testy

Cobertura

Site – StatSCM

Lines of codes
  • Lines of codes

Maven ve firmě

Rys ostrovid
  • Přínosy Mavenu ve firmě
  • Jak používat Maven ve firmě

  • DevZuz Maestro – komerční distribuce
  • Microsoft Team Foundation Server
  • Když je jeden projekt, nevyplatí se to
  • Pokud jsou hodně velká specifika, lze Maven použít. V nejhorším si napíšete vlastní continuum :-)

Prostředí pro vývoj

Cluster
  • Wiki
  • Bugtracking (BugZilla)
  • SCM (Subversion, CVS) + webový přístup
  • Kontinuální integrace (Continuum)
  • E-mailové konference
  • Stránka projektu (JavaDoc, Dokumentace, ...)
  • Vnitřní životní cyklus projektu
  • doporučuji projekt trac (wiki, bugtracking, SCM view)
  • Prostor pro zlepšení - ukládání meta informací - seznam projektů, aktivní projekty, ...

Prostředí

<project>
    <issueManagement>
        <system>Bugzilla</system>
        <url>http://127.0.0.1/bugzilla/</url>
    </issueManagement>
    
    <scm>
        <connection>scm:svn:https://svn.firma.cz/trunk/</connection>
    </scm>
    
    <mailingLists>...</mailingLists> 
    <repositories>...</repositories>
    <pluginRepositories>...</pluginRepositories>
  • Bugtracking - zatím jen přidá odkaz do stránky projektu (co třeba Mylyn v eclipse)
  • lze rozlišovat mezi connection a developerConnection (anonymní vs autorizovaný přístup).
  • SCM - API, které umožnuje abstrahovat verzovací systém

Continuum

Continuum logo
  • Přidáme SCM adresu k pom.xml: scm:svn:https://svn.firma.cz/trunk/pom.xml
  • Notifikace:
    <project>
        <ciManagement>
            <system>continuum</system>
            <url>https://continuum.firma.cz/</url>
            <notifiers>
                <notifier>
                    <type>mail</type>
                    <configuration>
                        <address>pferschmann@softeu.com</address>
                    </configuration>
                </notifier>
            </notifiers>
        </ciManagement>    
    
  • Automaticky propojeno se SCM. Notifikace jsou v metadatech projektu (podporuje větve, apod.)
  • Umí notifikovat o chybě a o úspěchu
  • Checkoutuje projekty každý do vlastního adresáře – nelze používat relativní cesty mezi projekty.
  • Snažit se o nezávislost na prostředí – např. pro test pouštět mvn tomcat:run apod

Nasazení v SoftEU

  • SoftEU: používáme Artifactory společně s Apachem – deployujeme do apache a artifactory pak cachuje

Úložiště ve firmě

Medvěd hnědý
  • Potřebujeme tyto úložiště:
    • releases
    • snapshots
    • knihovny třetích stran
    • lokální cache
  • Potřebujeme tyto "site":
    • releases
    • snapshots
  • Snapshoty jsou nahrávány Continuuem po úspěchu testů.

  • Artifactory
  • SoftEU: používáme Artifactory společně s Apachem – deployujeme do apache a artifactory pak cachuje

Rodičovský projekt

  • Celofiremní rodičovský projekt
  • Definuje:
    • Jak se deployuje site/releases/snapshots
    • Reporty
    • Úložiště (Repository)
    • distributionManagement
    • Default goal
    • eclipse:eclipse rovnou stahuje zdrojáky
    • Verze používaných modulů
    • Profily:
      • test
      • site
      • site-slow
      • release
  • Pozor: Každý projekt má znovu úložiště, kde je umístěn rodičovský projekt.
  • Vycheckoutujete projekt a potřebujete najít rodičovský projekt
  • pro projekty máme i projektový rodičovský projekt

Build number?

Orel kamčatský
  • "Build number" nahrazeno číslem revize ze SCM
  • Vlastní plugin svn-info
  • Formát:
    • trunk v9500
    • branches/beta1 v9431
  • Uloženo jako property do classpath. Posíláme mailem při chybě (talkback)

Release

  • Používáme plugin "release"
    • mvn release:prepare -DautoVersionSub­modules=true
    • mvn release:perform

<distributionManagement>
    <repository>
        <id>softeu-repo</id>
        <url>scp://repo.firma.cz/releases</url>
    </repository>
    <snapshotRepository>
        <id>softeu-repo</id>
        <url>scp://repo.firma.cz/snapshots</url>
    </snapshotRepository>
    <site>
        <id>softeu-repo</id>
        <url>scp://repo.firma.cz/sites</url>
    </site>
</distributionManagement>
  • Dělá to
    • Vytvoření tagu
    • Automatické přečíslování projektu (vhodné použít -DautoVersionSub­modules=true)
    • Nahrání do verze repository (JAR, pom, sources, javadoc)
  • Sdílené knihovny, Oddělené životní cykly od jednotlivých projektů
  • Babička a release engeneer

SoftEU – problémy a hodnocení

  • Změna přístupu
  • Sjednocení projektů
  • Zjednodušení prostředí
  • Více reportů
  • Pozor na reprodukovatelnost buildů

ano či ne
  • Závislosti – přechod z antu na maven
    • složité ant tasky
    • Nejednoznačné oddělení podprojektů (např. jen podle package)
  • Kasička
  • Repository mazat jak kvůli chybám, tak kvůli jistotě, že všechno poběží.
  • Firemní repository je důležité (zálohovat)
  • reprodukovatelnost buildů
  • % Občas nutnost smazat lokální repository
  • Špatné závislosti - pustím si "mvn site" a pak pomocí exclusions je opravím
  • Pozor při aktualizaci knihoven – ale to platí obecně
  • Napsali jsme si celkem 2 pluginy - svn-info a run:run (tohle mi schází)
  • Kompilujeme testy, ale nepouštíme (na to máme vlastní profil) – škoda, že nelze při volání mvn test ten profil aktivovat
  • Někteří lidé ignorují Maven a kompilují v eclipse - u jednoprojektového to jde
  • Výhradně používáme mvn jetty:run nebo mvn tomcat:run
  • mvnrepository.com je můj kamarád
  • Generované stránky – chce to důsledně informace zpracovávat - jsou ignorované