flowchart LR
A["Descarregar<br/>dependències"] --> B["Compilar<br/>el codi"]
B --> C["Executar<br/>les proves"]
C --> D["Empaquetar<br/>(.jar)"]
Apèndix C — Projectes Java amb Maven
Quan un programa creix més enllà d’un sol fitxer .java, necessitem organitzar-lo i gestionar-ne les dependències o biblioteques externes.
Aquest annex explica l’estructura estàndard d’un projecte Java i com Maven ens ho automatitza.
C.1 L’estructura estàndard d’un projecte Java
Un projecte Maven segueix una convenció de carpetes coneguda per tothom. Això vol dir que qualsevol persona (o eina) que obri el projecte sap immediatament on és cada cosa.
biblioteca/
├── pom.xml ← Configuració del projecte
└── src/
├── main/
│ ├── java/ ← Codi font de l'aplicació
│ │ └── cat/biblioteca/
│ │ ├── App.java
│ │ ├── model/Llibre.java
│ │ └── dao/LlibreDAO.java
│ └── resources/ ← Fitxers no-codi (config, dades...)
└── test/
└── java/ ← Codi de proves (tests)
Maven parteix del principi “convention over configuration”: si col·loques els fitxers on toca (src/main/java, src/test/java…), no cal configurar res.
Només et desvies de la convenció quan tens una necessitat especial.
Els noms de carpeta sota java/ reflecteixen el paquet (package) de les classes.
Per exemple, cat/biblioteca/model/Llibre.java conté una classe amb package cat.biblioteca.model;.
C.2 Què és Maven?
Maven és una eina de construcció (build tool) per a projectes Java. S’encarrega de tasques repetitives que faríem a mà:
Sense Maven, hauries de baixar manualment cada biblioteca .jar, col·locar-la al lloc correcte, passar-la al compilador… i repetir-ho cada vegada.
Maven ho fa tot a partir d’un únic fitxer de configuració: el pom.xml.
Només has de declarar quina biblioteca vols (i quina versió). Maven la baixa d’un repositori central a Internet, junt amb tot el que aquesta biblioteca necessiti al seu torn (les dependències transitives), i les hi posa disponibles. Res de buscar .jar per la xarxa.
El POM (Project Object Model) és el cor del projecte. És un fitxer XML que descriu què és el projecte i de què depèn.
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Coordenades: identifiquen el projecte de manera única -->
<groupId>cat.biblioteca</groupId>
<artifactId>biblioteca</artifactId>
<version>1.0.0</version>
<!-- Propietats: versió de Java, codificació... -->
<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- Dependències: biblioteques externes -->
<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.46.0.0</version>
</dependency>
</dependencies>
</project>Cada projecte (i cada biblioteca) s’identifica amb tres dades, les*coordenades. Igual que unes coordenades geogràfiques localitzen un punt del mapa, aquestes localitzen un artefacte de manera única al repositori.
| Coordenada | Què és | Exemple |
|---|---|---|
groupId |
L’organització o grup (com un domini a l’inrevés) | org.xerial |
artifactId |
El nom del projecte/biblioteca | sqlite-jdbc |
version |
La versió concreta | 3.46.0.0 |
Quan afegeixes una dependència, escrius les coordenades d’aquesta biblioteca. Les trobaràs a mvnrepository.com o al lloc web de cada projecte.
C.3 El cicle de vida de construcció
Maven organitza la feina en fases que s’executen en ordre. Quan demanes una fase, s’executen totes les anteriors automàticament.
flowchart LR
A["validate"] --> B["compile"]
B --> C["test"]
C --> D["package"]
D --> E["verify"]
E --> F["install"]
| Fase | Ordre mvn ... |
Què fa |
|---|---|---|
compile |
mvn compile |
Compila el codi de src/main/java |
test |
mvn test |
Compila i executa les proves de src/test/java |
package |
mvn package |
Empaqueta el resultat en un .jar (a target/) |
clean |
mvn clean |
Esborra la carpeta target/ (recomença de zero) |
install |
mvn install |
Instal·la el .jar al repositori local per reutilitzar-lo |
La combinació més habitual mentre desenvolupes és:
mvn clean packageNeteja, compila, passa les proves i genera el .jar, tot d’una tirada.
C.4 Executar el projecte amb Maven
El plugin exec-maven-plugin executa la classe main sense sortir de Maven:
mvn compile exec:java -Dexec.mainClass="cat.biblioteca.App"Perquè sigui més còmode, pots fixar la classe principal al pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<mainClass>cat.biblioteca.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>I aleshores n’hi ha prou amb:
mvn compile exec:javaUna altra opció és utilitzar Shade Plugin. Ens crea un únic .jar que porta el nostre codi i totes les biblioteques a dins.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>cat.biblioteca.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>Després de mvn clean package, pots executar l’aplicació a qualsevol màquina amb Java:
java -jar target/biblioteca-1.0.0.jarexec vs shade
exec: còmode mentre desenvolupes (no genera cap fitxer per distribuir).shade: per entregar l’aplicació acabada com un únic.jarque funciona a qualsevol lloc.
C.5 Errors típics
- Fitxers fora de
src/main/java→ Maven no els compila. Respecta la convenció. JAVA_HOMEmal configurat → Maven no troba el JDK.- Versió de dependència inexistent → error en baixar; comprova-la a mvnrepository.com.
java -jard’un.jarnormal falla ambNoClassDefFoundError** → et falta elshadeper incloure les dependències.- Editar el
.jardetarget/a mà →target/és generada; sempre es regenera ambmvn package.
C.6 Mini-exercicis
- Crea un projecte Maven amb l’estructura estàndard i una classe
Appque imprimeixi “Hola, Maven!”. - Afegeix la dependència
sqlite-jdbcalpom.xmli comprova ambmvn compileque es baixa. - Configura el plugin
execi executa l’aplicació ambmvn compile exec:java. - Genera un fat jar amb
shadei executa’l ambjava -jar.
C.7 Resum
- Un projecte Java segueix l’estructura
src/main/java,src/test/java,src/main/resources. - Maven automatitza baixar dependències, compilar, provar i empaquetar, tot des del
pom.xml. - Les coordenades (
groupId/artifactId/version) identifiquen projectes i dependències. - El cicle de vida (
compile→test→package) executa les fases en ordre. - Ús de
execper desenvolupar ishadeper distribuir un.jarautònom.