Blog de Antonio Manuel Muñiz

Desarrollo, Ingeniería y Calidad del Software

Archivos por Etiqueta: Maven

Sonar PDF Plugin 0.1

Ya hablaba de esto hace algún tiempo, y después de varios meses de trabajo hemos publicado la primera versión (0.1) de Sonar PDF Plugin.

En esta primera versión se ha optado por envolver la lógica de generación del reporte en un plugin para Maven, el cual está disponible en el repositorio central de Maven.

El reporte actual contiene:

  • Información general del proyecto (nombre, descripción, version, módulos)
  • Dashboard (indicadores proporcionados por Sonar, similar al dashboard que muestra Sonar en su interfaz web)
  • Violaciones de reglas por categorías
  • Reglas más violadas
  • Ficheros que más violan las reglas
  • Todo lo anterior para cada módulo que compone el proyecto (si existe alguno)

Ya hay algunas mejoras reflejadas en JIRA para la versión 0.2, seguiremos trabajando.

Anuncios

Curiosidades y peculiaridades de Maven y Java

Seguro que todos nos hemos encontrado con ciertas peculiaridades de las herramientas que usamos día a día, pero encontrarse con dos (de las buenas) en un solo día, eso no tiene precio ;) sobre todo cuando el tema te quita medio día.

Son sólo detalles, pero si se dan las condiciones precisas… puede ser un quebradero de cabeza.

Cuando hay dos clases con el mismo FQN (Fully Qualified Name) en el classpath, ¿cuál de las dos se carga? Pues la respuesta es que depende, con Java 1.5 puede ser una, y con Java 1.6 puede ser otra. Resulta que tenía en mi classpath tres versiones de commons-collections (fruto de descontrol con las dependencias transitivas). Si ejecutaba los tests con Java 1.5 todo iba bien, se estaba usando commons-collections-3.1 (que era la versión que yo tanía en mi POM). Pero si usaba Java 1.6 resulta que se cargaba commons-collections-2.1.1 y uno de los métodos que se llamaba por reflexión no existía en esta versión pero sí en la 3.1. La solución, estudiar de donde viene esa dependencia transitiva y excluirla en el POM para que no haya diferentes versiones de un mismo artefacto.

¿Por qué no me aparecen los enlaces a los módulos hijos en el Maven Site? Mi proyecto tenía la estructura típica de un proyecto Maven multimódulo. Configuré los ficheros site.xml para que en el Maven site se pueda navegar mediante enlaces desde el proyecto padre a los hijos y viceversa. Resulta que los enlaces no aparecen. El problema resultó ser que en los POM de los módulos hijos tenía una etiqueta <url> y su contenido era el mismo que en el POM padre, quitando este nodo en los POM de los hijos… problema resuelto. Cuanto menos, curioso.

En fin, el primero de los problemas lo detecté rápido mirando las dependencias transitivas de mi proyecto con Q4E. El segundo fué más bien suerte y gracias alguna incidencia en Codehaus que hablaba de la influencia en el site de la etiqueta <url>.

Javascript como un módulo Maven

¿Es posible aislar todo el código javascript de nuestra aplicación web en un proyecto a parte?

Si, lo es. Con javascript-maven-tools, en concreto con javascript-maven-plugin. Este plugin nos permite tratar con proyectos de tipo javascript, es decir, esto sería válido:

...
<dependencies>
    ...
    <dependency>
        <gruopId>example.javascript</groupId>
        <artifactId>my-javascript</artifactId>
        <version>1.0.0</version>
        <type>javascript</type>
    </dependency>
    ...
</dependencies>
...

Este plugin habilita el uso del tipo “javascript” en nuestras dependencias. Sólo debemos configurarlo:

<build>
    <plugin>
        <groupId>org.codehaus.mojo.javascript</groupId>
        <artifactId>javascript-maven-plugin</artifactId>
        <version>1.0-alpha-1-SNAPSHOT</version>
        <extensions>true</extensions>
        <executions>
            <execution>
                <id>js-copy-deps</id>
                <goals>
                    <goal>war-package</goal>
                </goals>
                <phase>package</phase>
            </execution>
        </executions>
    </plugin>
</build>

¿Y el artefacto javascript, cómo se crea?

Pues definiendo un proyecto maven de tipo “javascript”. Es decir, el “packaging” será de tipo “javascript” en el POM:

<packaging>javascript</packaging>

Y definiremos la siguiente extensión:

...
<build>
    <extensions>
        <extension>
            <groupId>org.codehaus.mojo.javascript</groupId>
            <artifactId>javascript-maven-plugin</artifactId>
            <version>1.0-alpha-1-SNAPSHOT</version>
         </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo.javascript</groupId>
            <artifactId>javascript-maven-plugin</artifactId>
            <version>1.0-alpha-1-SNAPSHOT</version>
            <extensions>true</extensions>
         </plugin>
     </plugins>
</build>
...

Maven tratará nuestro proyecto como un projecto más, y tenemos a nuestra disposición toda la potencia de la gestión de dependencias de Maven.

Para configurar el comportamiento del plugin debemos indicarle un proporcionar un par de parámetros, basta con incluir las propiedades en el POM:

<properties>
    <scripts>public/scripts</scripts>
    <lib></lib>
    <useArtifactId>true</useArtifactId>
</properties>

Eso es todo. Solo un detalle más, el plugin tiene algunos bugs, he reportado un parche a sus desarrolladores, aún no lo han incluido en la versión actual. Siempre podemos descargar el código y parchearlo nosotros mismos ;)

Transformaciones con Maven Assembly Plugin

Uno de los usos más típicos del plugin Assembly de Maven es la generación de un “distribuible” de nuestro proyecto. Mediante el uso de este plugin podemos seleccionar qué partes del proyecto se incluirán en el “distribuible”.

También podemos, por ejemplo, generar una distribución de código fuente del proyecto que no contenga datos relativos a nuestro entorno y sea “compilable” fuera de él.

Pero en realidad lo que podemos conseguir con este plugin es ilimitado, pudiendo definir “transformaciones” de todo tipo:

assembly-graphic

Módulos OpenCMS y Maven

Objetivo: modelar el ciclo de vida de un módulo de OpenCMS con Maven2

Si realizamos una búsqueda rápida en google vemos que las palabras OpenCMS y Maven no aparecen juntas facilmente. La única referencia interesante es el plugin desarrollado por Comundus, pero está orientado a la gestión del proyecto OpenCMS completo, no al desarrollo de módulos de forma aislada. En este post veremos cómo gestionar dependencias, compilar y empaquetar un módulo de OpenCMS con Maven2.

En el proceso de modelado hay una restricción: el código fuente debe ser compatible con el uso del plugin opencmsmoddev para Eclipse. Esto nos obliga a no seguir la estructura típica de un proyecto Maven sino la que requiere dicho plugin. La estructura requerida es la siguiente:

--+ src
--+ system
  |--+ workplace
     |--+ resources
--+ lib
--+ schemas
--+ templates
--+ manifest.xml
--+ pom.xml

Dada esta premisa, necesitamos configurar el P.O.M de una forma un poco especial. En primer lugar debemos indicar donde estan nuestros fuentes y donde poner los compilados:

<sourceDirectory>src</sourceDirectory>
<outputDirectory>classes</outputDirectory>

Además el resultado de realizar un mvn package debe ser un zip desplegable en una instancia de OpenCMS. Para ello utilizaremos el plugin maven-antrun-plugin con la siguiente configuración:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.1</version>
    <executions>
        <execution>
            <id>zip-module</id>
            <goals>
                <goal>run</goal>
            </goals>
            <phase>package</phase>
            <inherited>false</inherited>
            <configuration>
                <tasks>
                    <echo>Packaging OpenCMS Module...</echo>
                    <mkdir dir="target/dist/system/modules/${project.groupId}.${project.artifactId}" />
                    <copy todir="target/dist/system/modules/${project.groupId}.${project.artifactId}/src">
                        <fileset dir="src" />
                    </copy>
                    <copy todir="target/dist/system/modules/${project.groupId}.${project.artifactId}/classes">
                        <fileset dir="classes" />
                    </copy>
                    <copy todir="target/dist/system/modules/${project.groupId}.${project.artifactId}/schemas">
                        <fileset dir="schemas" />
                    </copy>
                    <copy todir="target/dist/system/modules/${project.groupId}.${project.artifactId}/templates">
                        <fileset dir="templates" />
                    </copy>
                    <copy todir="target/dist/system/workplace">
                        <fileset dir="system/workplace" />
                    </copy>
                    <copy file="manifest.xml" todir="target/dist" />
                    <zip destfile="target/${project.groupId}.${project.artifactId}.zip" basedir="target/dist" />
                </tasks>
            </configuration>
        </execution>
    </executions>
</plugin>

Esta tarea genera el zip requerido por OpenCMS a partir de lo que anteriormente hemos puesto en target/dist.

Aprovecharemos la gestión de dependencias que nos ofrece Maven, en principio la única dependencia que necesitamos es la del propio núcleo de OpenCMS. He usado como base OpenCMS 7.0.5, no he encontrado esta dependencia en ningún repositorio de Maven (conocido). Para solventar esto debemos instalarla en nuestro repositorio local e incluir la dependencia correspondiente en el P.O.M:

<dependency>
    <groupId>org.opencms</groupId>
    <artifactId>opencms</artifactId>
    <version>7.0.5</version>
    <scope>provided</scope>
</dependency>

La marcamos como provided ya que en tiempo de ejecución será OpenCMS el que la incluya en el classpath.

OpenCMS requiere que ciertos recursos se coloquen en el directorio src junto a los fuentes, para poder usar filtrado usaremos:

<resources>
    <resource>
        <directory>src</directory>
        <filtering>false</filtering>
        <excludes>
            <exclude>**/*.java</exclude>
        </excludes>
    </resource>
</resources>

Al empaquetar el módulo necesitamos incluir todas sus dependencias (excepto la marcadas con scope provided), para ello usaremos maven-dependency-plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy</id>
            <phase>process-resources</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <excludeScope>provided</excludeScope>
                <outputDirectory>target/dist/system/modules/${project.groupId}.${project.artifactId}/lib</outputDirectory>
                <overWriteReleases>true</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>

Este es el fichero pom.xml completo.