Conceptos y proyectos Maven
Plugins, Goals, Coordenadas...
Tenemos varias maneras de crear un proyecto con Maven. La que no falla es la de la consola.
mvn archetype:create -DgroupId=info.pello.maven.xsd -DartifactId=validadorXsd -DpackageName=info.pello.maven
El parámetros archetype:create es lo que Maven llama goal; algo similar a los targets de ant. Un arquetipo para entendernos
es un modelo, o por decirlo más simple es un tipo. Para ser más precisos, archetype es un plugin de maven y create el goal.
Un plugin puede tener distintos goal.
La orden anterior nos crea un toda la estructura de directorios de maven, descrita en un post anterior. Como se puede
adivinar en los parámetros (proporcionados con -D al estilo java), coinciden con los que se ponen en un fichero pom.xml
básico. El directorio del proyecto coincidirá con el nombre de artifactId.
Si queremos compilar, testear, crear un jar, etc.. ejecutariamos
mvn install
Ojo! en ese caso install NO ES un plugin sino una fase del ciclo de vida (lifecycle) de Maven. La gestión un proyecto
con Maven es un ciclo de vida completo, y en este caso el install no es más que una fase concreta de ese ciclo. Hay una fase
llamada package que se encarga de empaquetar todo el software. Las fases lo que llevan consigo son determinadas tareas
y así por ejemplo la fase package utilizará entre otras el goal/tarea jar:jar. (plugin jar, goal jar). Vamos, que la fase es algo más general
y un goal una tarea concreta que puede formar parte de una fase.
En el caso de Mvn install
Al fichero pom.xml podemos ir añadiendo más cosas como las dependencias para que ejecute test unitarios. Aparte del
fichero pom.xml del proyecto Maven también llevará a cabo las tareas ficheros POM superiores si los hay o un fichero POM
general que trae la distribución de Maven.
Si utilizamos un IDE como netbeans o eclipse (desde la versión Kepler) podremos crear directamente proyectos Maven.
Espacio Maven
Algo curioso en Maven es que se considera una especie de lugar multidimensional lleno de artefactos. Y para localizar
algo en un sistema así ¿qué utilizamos? Pues está claro, unas coordenadas.. Los identificadores nos proveen de esas
coordenadas y son cruciales ya que puede que reutilicemos artefactos de un proyecto a otro y para eso necesitamos
localizarlos. Las coordenadas serían:
groupId:artifactId:packaging:version
por ejemplo: si en el pom tenemos:
<groupId>info.pello.maven</groupId>
<artifactId>xsdvalidator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>info.pello.maven.xsd</name>
Las coordenadas serían:
info.pello.maven:xsdvalidator:jar:0.0.1-SNAPSHOT
Los repositorios
Maven se va descargando lo que necesita según las necesidades del proyecto. Una vez bajado no necesitará volver
a bajarse algo, pero las primeras veces veremos que se baja ciento y la madre de paquetes ya estemos en la consola
o con el eclipse. Existe un repositorio central y oficial de Maven, más el repositorio local que se va creando conforme
nos bajamos cosas o desarrollamos proyectos.
La gestión de la dependencia
Esto es la crema. Uno de los quebraderos de cabeza al desarrollar con java, aunque uses un IDE estupendo es que
necesitas bajarte la librería j_la_madre_que_te_trajo.jar y el paquete j_tu_padre_que_tal_mea.jar. Ese trabajo sucio
es algo que maven hace por ti, y lo que es mejor, si existen dependencias extra (transitivas) te las resuelve.
Si en el fichero pom.xml hemos indicado alguna dependencia como junit, Maven se encargará.
Un validador de XML Schema
Como ejemplo he creado un proyecto muy simple, un validador de ficheros XSD. Lo del validador no es más que un churro
con un main. Se puede hacer mucho más bonito y tal pero la cosa ahora era ver todo dentro de un proyecto Maven.
En este caso he utilizado eclipse, y la verdad es que se ha portado bien. Al crear un proyecto Maven efectivamente es
un proyecto Maven y se puede hacer install, build, etc... y por supuesto ejecutarlo.
Puedes verlo/bajártelo en :
http://code.google.com/p/erps-2dam-4vientos/source/browse/#svn%2Ftrunk%2Fxsdvalidator
¿Qué es XML Schema? Es otro tema que lo iniciaré en otro post, básicamente te permite definir tipos de documento
XML, vamos algo así como un DTD pero muchísimo mejor.
En este caso el Schema es el siguiente:
<?xml version="1.0"?>
<!--
hello.xsd a very simple XSD sample with just one elements
-->
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="greet" type="xs:string" />
</xs:schema>
Y el XML correspondiente:
<?xml version="1.0" encoding="UTF-8"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<greet
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='hello.xsd'>
Hello XSD
</greet>
Y por último la clase java que toma los dos ficheros y nos dice si el XML es válido:
package info.pello.mvn.xsd;
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.xml.sax.SAXException;
import java.io.File;
/**
* XSD file validator sample in a project using Maven:
* To execute goto maven dir and:
* java -cp target/xsdvalidator-0.0.1-SNAPSHOT.jar info.pello.mvn.xsd.XSDValidator
* @author Pello Altadill
* @greetz you, for reading this.
*/
public class XSDValidator {
/**
* @param args
*/
public static void main(String [] args) {
// First we load both the schema and the xml to validate
// sorry for the hardcoded file locations...
Source schemaFile = new StreamSource(new File("src/main/resources/hello.xsd"));
Source xmlFile = new StreamSource(new File("src/main/resources/hello.xml"));
try{
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.validate(xmlFile);
System.out.println(xmlFile.getSystemId() + " file is VALID XML");
} catch (SAXException saxe) {
System.out.println(xmlFile.getSystemId() + " file is NOT VALID");
System.out.println("Message: " + saxe.getLocalizedMessage());
} catch (Exception e) {
System.out.println("Message: " + e.getMessage());
}
}
}