Hola Mundo Maven

Después de haber tocado temas más o menos "pesados" en el desarrollo web, en esta ocasión voy contar el típico "Hello World Maven" de consola. Quizá sea la forma más sencilla de empezar aunque maven no está pensado para cosas así de sencilla
Esta vez no utilizaré maven como herramienta separada para crear el proyecto. Si no tienes un entorno de desarrollo funcionando, en esta entrada puedes encontrar cómo configurar un entorno más ambicioso del que necesitas para este primer "hola mundo". En pocas palabras: un jdk y eclipse con el plugin de maven.
Abrimos el eclipse File, new y seleccionamos "other" ( al final, abajo del todo). Nos aparecerá una ventana de "wizards". Puesto que lo que queremos es un proyecto gestionado por maven, es lo que escribimos arriba. Nos aparecen tres:"Checkout Maven projects...", "Maven module" y "Maven Project". Seleccionamos el último y click en "Next", Marcamos para que lo cree en el Workspace actual , Use default Workspace Location, y "Next". Ahora seleccionamos el catálogo internal y en el filter escribimos "quickstart". Seleccionamos el primero de "org.apache.maven.archetypes", llamado "maven-archetype-quickstart" y  click en "Next".
En la siguiente pantalla debemos rellenar el identificador de grupo al que pertenece "home.pruebas", nombre del artefacto "jellou" y package lo relleno con "home.pruebas.main". Versión dejo la 0.0.1-Snapshot y por último hago click en Finish.
Una vez realizado estos pasos ya deberíamos tener un proyecto, con formato de aplicación de consola con el tradicional saludo.
Si observamos la estructura del proyecto y de paquetes veremos que en "home.pruebas.main" tenemos una clase "App.java" con un método main. Podemos ejecutarlo desde el eclipse seleccionando dicha clase, haciendo click con el botón derecho y seleccionando "Run As... Java Application". En la consola veremos que aparece un "Hello World!".
Pero la gracia de todo esto es gestionarlo con maven. Si selecciono el proyecto y pruebo ejecutar un ciclo normal para probarlo, esto es: borrar lo generado, compilarlo y ejecutarlo observaré que me falla,
me indica que no encuentra la clase con el main.
Pero primero ¿cómo se indica que borre, compile y ejecute? Seleccionamos el proyecto y con el botón derecho seleccionamos "Run As " y seleccionamos "Run Configurations". A la izquierda de la pantalla deberíamos tener seleccionada una nueva Configuración de "Maven Build". En la parte derecha arríba un nombre, por ejemplo "Runjellou" para ese "configuración" y debajo tenemos una serie de pestañas. La principal, es la que aparece "Main". En "Base directory" lo más cómodo es tener ${project_loc} que hace que al ejecutar esta configuración automáticamente se seleciona el proyecto en el que estamos. En goals escribimos "clean compile exec:java". Es fácil inferir que esa es la sintaxis para que haga lo que comentaba.
Si una vez escrita esta configución finalizamos pulsando el botón "Run" la salida de la consola nos indicará lo que apuntaba antes: "The parameters 'mainClass' for goal org.codehaus.mojo:exec-maven-plugin:1.2.1:java are missing or invalid".
La mejor manera de que se sepa qué clase tiene el main y por tanto el punto de entrada de la ejecución es indicarselo en el archivo manifest que se encuentra dentro de cualquiera jar. 
Por ver un caso un poquito más complicado, vamos a hacer que se le pase un parámetro al método main que quede algo como esto:

 public static void main( String[] args )
    {
        System.out.println( "Hola mundo Maven " + args[0]);
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println( "Adios Mundo Maven" );  
    }
Creo que se ve bastante claro cual es la modificación. Al main llega como parámetro un array de String, "args". Toma el primer String y lo concatena con "Hola Mundo Maven". Luego hace una espera de 5000 milisegundos y escribe la despedida.

Ahora tenemos que indicarle al oportuno plugin de maven que esta clase, la que contiene el main es el punto de entrada.
Para ello debemos añadir al pom.xml el apartado build y a este el apartado plugins y a este el plugin y configurarlo
Quedaría este pom :

<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>

    <groupId>home.pruebas</groupId>
    <artifactId>jellou</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>jellou</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>home.pruebas.main.App</mainClass>
                    <arguments>
                        <argument>Andrés</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Si probamos a ejecutar el goal  "clean compile exec:java" veremos que  ademas de ejecutarse le estamos pasando el parámetro señalado, en este caso "Andrés".
Destacar que en la configuración de este plugin indicamos la clase con el main a ejecutar, como se ve se le indica con la ruta completa del paquete y que le estamos pasando un argumento.

                 <configuration>
                    <mainClass>home.pruebas.main.App</mainClass>
                    <arguments>
                        <argument>Andrés</argument>
                    </arguments>
                </configuration>

Vale, ya lo sabemos ejecutar desde el eclipse, pero queremos más. Queremos poder ejecutarlo desde el propio sistema operativo. Queremos crear un jar, en el cual el archivo "manifest" señale cual es la clase con el main que se debe ejecutar.
Añadimos al pom otro plugin:

           <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <executions>
                    <execution>
                        <id>default-jar</id>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>home.pruebas.main.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>


Si ejecutamos la configuracion package veremos que nos genera un archivo "jellou-0.0.1-SNAPSHOT.jar" en la carpeta "target". La configuración para indicarle cual es la clase con el main es muy similar a la del plugin para ejecutarlo.

Dicho jar lo podemos ejecutar desde linea de comando como cualquier jar :

C:\work\workshop\jellou\target>java -jar jellou-0.0.1-SNAPSHOT.jar Pocoyo
Hola mundo Maven Pocoyo
Adios Mundo Maven

En este caso lo hemos ejecutado desde windows  con "java -jar elnombredeljar.jar parámetro". Ejecutarlo desde linux sería exactamente igual. La palabra "Pocoyo" se ha utilizado como parámetro que se pasa por linea de comandos al método main.

Nota. Con el main, tal y como lo he dejado, si no se le pasa parámetro alguno se produce una excepción cuando se ejecuta  "System.out.println( "Hola mundo Maven " + args[0]);" ya que se intenta acceder a un elemento de un array que no existe.

Comentarios