16 mai, 2009

Introducere în Apache Maven 2, Partea 3 - Project Object Model (POM)

Project Object Model (modelul obiect al proiectului) este un fişier XML, numit pom.xml, în care este definită structura proiectului, este configurat build-ul şi sînt definite relaţiile dintre proiecte. Un proiect Maven este caracterizat prin prezenţa fişierului pom.xml. Cînd Maven rulează, el consultă pom.xml pentru informaţii despre proiect. POM răspunde la astfel de întrebări ca: Ce fel de tip de proiect este acesta? Care este numele proiectului? Există careva personalizări pentru acest proiect?

Informaţia din POM este împărţită în 4 categorii:

  • Informaţia generală despre proiect - aceasta include numele proiectului, URL-ul proiectului, compania dezvoltatoare, lista de developeri şi colaboratori, licenţă proiectului.
  • Setările pentru build - În această secţiune se conţin toate personalizările proiectului. Se poate schimba locaţia fişierelor sursă, a testelor, se pot adăuga noi plugin-uri, se pot ataşa noi goal-uri (scopuri, obiective) ale plugin-urilor la ciclul de viaţă al proiectului, se pot personaliza parametrii pentru generarea paginii web a proiectului.
  • Mediul de build - constă din profiluri care pot fi activate pentru a fi utilizate în diferite medii (environment-uri). De exemplu, în timpul dezvoltării (development) se poate de ales de a face deploy pe un server de dezvoltare, iar în producţie de a face deploy pe un server de producţie.
  • Relaţiile POM-ului - Un proiect rareori este singur. De cele mai multe ori el depinde de alte proiecte, moşteneşte setări din POM-ul proiectului părinte, îşi defineşte propriile coordonate şi poate include şi sub-module.

Dacă dvs. doriţi să dezvoltaţi un proiect simplu, care produce un JAR, din sursele aflate în src/main/java, şi doriţi să rulaţi testele JUnit din src/test/java, atunci nu aveţi nevoie să personalizaţi nimic. Tot de ce aveţi nevoie în acest caz este cel mai simplu POM posibil, arătat mai jos:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.company.example</groupId>
    <artifactId>simple-project</artifactId>
    <version>1</version>
</project>

Dacă puneţi careva cod sursă în subdirectorul src/main/java şi rulaţi mvn install atunci în directorul target veţi avea generat fişierul simple-project-1.jar. [Click mai jos pentru a citi articolul în întregime]

Toate POM-urile proiectelor Maven extind acelaşi Super POM, care defineşte un set de valori şi setări implicite împărtăşite de toate proiectele. Super POM-ul este o parte din instalarea Maven, şi poate fi găsit în fişierul maven-2.1.0-uber.jar în ${M2_HOME}/lib. Dacă vă uitaţi în acest fişier JAR, veţi găsi un fişier numit pom-4.0.0.xml în pachetul org.apache.maven.project.

Deoarece POM-urile pot moşteni configurarea de la alte POM-uri, întotdeauna trebuie să ne gîndim la POM din punct de vedere al asocierii Super POM-ului cu POM-ul părinte şi în final cu POM-ul proiectului propriu zis. Maven începe cu Super POM şi apoi suprascrie configurarea implicită a acestuia cu unul sau mai multe POM-uri părinte. Apoi suprascrie configurarea primită cu POM-ul proiectului propriu zis. În final se ajunge la un POM efectiv, care este un amestec de diverse POM-uri. Dacă doriţi să vedeţi POM-ul efectiv al proiectului atunci puteţi să rulaţi goal-ul effective-pom al plugin-ului de ajutor Maven:

$ mvn help:effective-pom

După executarea acestei comenzi, ar trebui să vedeţi un POM mai mare, care expune pe lîngă ceea ce aţi definit dvs. explicit în POM, şi setările implicite de Maven (deoarece le va moşteni din Super POM). Plugin-urile şi goal-urile din Maven vor fi explicate în continuare într-un articol separat.


Coordonatele Maven

Cînd Maven execută un goal, fiecare goal are acces la informaţia definită în POM-ul proiectului. Cînd goal-ul jar:jar crează un fişier JAR, el accesează POM-ul pentru a găsi care trebuie sa fie numele fişierului JAR. Cînd goal-ul compiler:compile compilează sursele în byte-cod, el la fel accesează POM-ul pentru a vedea dacă nu sînt careva parametri definiţi pentru goal-ul compile. Toate goal-urile sînt executate în contextul POM-ului. Goal-urile nu sînt altceva decît nişte acţiuni pe care noi dorim să le aplicăm asupra unui proiect, iar proiectul este definit printr-un POM. POM-ul îi dă nume proiectului, îl înzestrează cu un set unic de identificatori (coordonate) şi stabileşte relaţii între acest proiect şi alte proiecte prin intermediul dependenţelor şi părinţilor.

Coordonatele Maven definesc un set de identificatori care pot fi folosiţi pentru a identifica un proiect, o dependenţă sau un plugin într-un POM Maven. Daţi să examinăm următorul POM simplu:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.company.project</groupId>
  <artifactId>simple</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>simple</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

În POM-ul de mai sus am evidenţiat (rîndurile 6, 7, 8, 9) coordonatele Maven pentru acest proiect: groupId, artifactId, version şi packaging. Aceşti identificatori combinaţi împreună, plus încă unul classifier, care nu este menţionat în acest POM, reprezintă coordonatele unui un proiect în Maven. La fel ca şi în oricare alt sistem de coordonate, în Maven, coordonatele reprezintă o adresă pentru un anumit punct din "spaţiu". Maven face referinţă la un proiect prin coordonatele sale în cazul în care un proiect se referă la un alt proiect, fie ca dependenţă, plugin sau o referinţă către proiectul părinte. Coordonatele Maven sînt adesea scrise utilizând un 2 puncte(:) ca delimitator în următorul format: groupId:artifactId:packaging:version. În exemplul de POM de mai sus, coordonatele pentru proiect sînt org.company:simple:jar:1.0-SNAPSHOT.

Mai jos vom examina fiecare identificator în parte:

  • groupId - Grupul, compania, echipa, organizaţia, proiectul, sau un oricare alt grup. Convenţia pentru identificatoarele de grup este că ele încep cu numele invers al domen-ului organizaţiei care creează proiectului. De exemplu org.apache.maven este baza pentru toate groupId ale artifactelor produse de proiectul Apache Maven. Identificatoarele de grup, sînt transpuse în locaţii în repozitoriul Maven, de exemplu, org.apache.maven poate fi găsit în /org/apache/maven.
  • artifactId - este identificatorul principal al proiectului. Este un identificator unic în cadrul groupId care reprezintă un singur proiect. Nu pot exista două proiecte cu aceleaşi groupId şi artifactId. În timp ce "." (punct) este frecvent utilizat în groupId, aici ar trebui să se evite utilizarea lui. Acest lucru poate cauza probleme la analiza numelor.
  • version - versiunea proiectului. Proiectele care au fost puse în circulaţie deja (released), au o versiune fixă. În Maven versiunile sînt formate din următoarele părţi: versiunea majoră, versiunea minoră, versiunea incrementală şi calificativul. Într-o versiune, aceste părţi corespund următorului format:
    <major version>.<minor version>.<incremental version>-<qualifier>
    De exemplu, versiunea "1.3.5-beta-01" are o versiune majoră de 1, versiunea minoră 3, versiunea incrementală 5 şi un calificativ beta-01. Calificativul există pentru a reprezenta release-urile: alfa şi beta. Versiunile Maven pot de asemenea să conţină şi următorul şir de literali:
    • SNAPSHOT - ceea ce semnifică faptul că un proiect este în prezent în curs de dezvoltare activ. Există posibilitatea de a configura Maven pentru a descărca periodic cea mai recentă versiune snapshot din repozitoriu. În cazul în care o versiune conţine şirul de caractere SNAPSHOT, atunci Maven va înlocui acest şir cu valoarea datei şi orei convertite la UTC (Coordinated Universal Time) atunci cînd se instalează sau se pune în circulaţie acest component. De exemplu, 1.4-SNAPSHOT se va transforma în 1.4-20090501-112507-1 dacă i-ar fi fost făcut deploy la 11:25 la 1 mai 2009 UTC.
    • LATEST - se referă la cea mai recentă versiune snapshot sau la cea mai recentă versiune lansată (released) a unui anumit artifact din repozitoriu.
    • RELEASE - se referă la cea mai recentă versiune care nu este snapshot a unui anumit artifact din repozitoriu.

Packaging-ul (formatul de ambalare) proiectului este de asemenea o componentă importantă în sistemul de coordonate Maven, dar acesta nu face parte din sistemul unic de identificatori ale unui proiect Maven. Setul groupId:artifactId:version face proiectul unic; nu poate exista un proiect cu aceleaşi trei groupId, artifactId, şi version.

  • packaging - tipul proiectului, implicit este jar. Descrie ce format produce proiectul respectiv. Un proiect cu packaging jar, produce un fişier JAR. Un proiect cu packaging war, produce o aplicaţie web.

Şi al patrulea, mai puţin folosit identificator:

  • classifier - se foloseşte atunci cînd este necesar pentru acelaşi proiect de a produce două artifacte separate, din motive tehnice. De exemplu, dacă se doreşte două artifacte JAR, unul compilat cu compilator Java 1.4 şi altul compilat cu compilator Java 6. În acest caz se poate utiliza calificativul pentru a produce două artifacte JAR în aceeaşi combinaţie groupId:artifactId:version.

În cazul în care proiectul este instalat în repozitoriul local Maven, acesta devine imediat disponibil pe plan local pentru orice alt proiect care doreşte să-l folosească. Tot ce trebuie de făcut este de-al adăuga ca pe o dependenţă folosind setul unic de coordonate Maven.


Repozitoriile Maven

Maven vine cu o locaţie implicită a remote repozitoriului http://repo1.maven.org/maven2, care este folosită pentru a descărca plugin-urile Maven de bază şi dependenţele. Maven descarcă plugin-urile şi dependenţele din repozitoriul remote la dvs. pe computer, într-un repozitoriu local. Odată ce Maven a descărcat un artifact din repozitoriul remote, el niciodată nu va mai avea nevoie să-l descarce încă o dată, deoarece Maven se uită întotdeaună mai întîi în repozitoriul local. În Windows XP repozitoriul local este situat în C:\Documents and Settings\USERNAME\.m2\repository, în sistemele din familia Unix el se afla în ~/.m2/repository.

Ce face un repozitoriu să fie un Maven repozitoriu? Un Maven repozitoriu este definit prin structura sa, un repozitoriu este o colecţie de artifacte ale proiectelor, stocate într-o structură şi un format care poate fi uşor înţeles de către Maven. Într-un repozitoriu Maven totul este stocat într-o structură de directoare, care se aseamănă foarte mult cu sistemul de coordonate Maven al unui proiect. Puteţi vedea această structură prin accesarea paginii repozitoriului central Maven http://repo1.maven.org/maven2/. Veţi vedea că un artifact cu coordonatele org.apache.velocity:velocity:1.6.2 este disponibil în sub-directoriul /org/apache/velocity/velocity/1.6.2/ într-un fişier numit velocity-1.6.2.jar. Standardul pentru un repozitoriu Maven este de a stoca un artifact în următoarea locaţie relativ cu directorul rădăcină al repozitoriului:

/<groupId>/<artifactId>/<version>/<artifactId>-<version>.<packaging>

Repozitoriul Maven este atît un cache local pentru artifactele descărcate din repozitoriul remote, cît şi un mecanism care permite proiectelor de a depinde unul de celălalt. Dacă aveţi 2 proiecte, A şi B, unde proiectul B depinde de artifactele produse de proiectul A, atunci Maven va prelua artifactele proiectului A din repozitoriul local atunci cînd va face build proiectului B.

Aici încheiem acest articol. În următorul post vom vorbi despre dependenţele proiectelor în Maven.


Trimiteţi un comentariu

  Blogger template adapted from The Professional Template by Ourblogtemplates.com 2008

Header image adapted from Free Web Page Headers