#Bitbucket y repositorios #Maven

Generalmente cuando se hace algún tipo de libreria en Java se empaqueta en un artefacto .jar, para gestionar el ciclo de construcción de una aplicación (entre ellas la gestión de dependencias) se puede usar Maven u otra herramienta similar (ant, ivy, gradle).

Ahora bien para publicar los artefactos al equipo y dejarlos disponibles se puede usar un ftp, dav o un gestor completo como Artifactory o Nexus, sin embargo con soluciones como Bitbucket o Github es buena idea mantener todo junto (más aún si Bitbucket permite repositorios privados tanto en Mercurial como en Git).

Para ello simplemente tenemos que configurar en el pom.xml de nuestro proyecto para que haga un deploy local del artefacto y luego publicarlo en bitbucket (git) mediante el ciclo commit , push. Finalmente cuando se necesite usar la dependencia en otro proyecto solo hay que agregar la configuración de repositorios para descargar la dependencia. Por ahora un pom.xml de ejemplo:

<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>org.simmetrics</groupId>
  <artifactId>simmetrics</artifactId>
  <version>1.6.2</version>
  <packaging>jar</packaging>

  <name>simmetrics</name>
  <description>SimMetrics is a Similarity Metric Library, based on previous work by http://sourceforge.net/projects/simmetrics/</description>
  <url>https://bitbucket.org/Nickmancol/simmetrics</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <altDeploymentRepository>releases::default::${project.baseUri}/mavenRepo/releases/</altDeploymentRepository>
  </properties>
  
  <developers>
    <developer>
      <id>@Nickmancol</id>
      <name>Nicolas Bohorquez Gutierrez</name>
      <email>nicolas.bg@gmail.com</email>
      <timezone>America/Bogota</timezone>
    </developer>
  </developers>

  <scm>
    <connection>scm:hg:http://bitbucket.org/Nickmancol/simmetrics</connection>
    <developerConnection>scm:hg:http://bitbucket.org/Nickmancol/simmetrics</developerConnection>
    <url>http://bitbucket.org/Nickmancol/simmetrics</url>
  </scm>
  
  <distributionManagement>
	  <repository>
      <id>releases</id>
      <url>https://bitbucket.org/Nickmancol/simmetrics/raw/tip/mavenRepo/releases/</url>
	  </repository>
	  <snapshotRepository>
	  	<id>snapshots</id>
      <url>https://bitbucket.org/Nickmancol/simmetrics/raw/tip/mavenRepo/snapshots/</url>
	  </snapshotRepository>
  </distributionManagement>

	<build>
    <plugins>
    	<plugin>
	      <groupId>org.apache.maven.plugins</groupId>
	      <artifactId>maven-compiler-plugin</artifactId>
	      <version>2.3.2</version>
	      <configuration>
	        <source>1.5</source>
	        <target>1.5</target>
	      </configuration>
	    </plugin>
	    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <executions>
          <execution>
            <id>attach-javadocs</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
		</plugins>
  </build>
	
	<profiles>
		<profile>
			<id>deploy-snapshot</id>
			<properties>
				<altDeploymentRepository>snapshots::default::${project.baseUri}/mavenRepo/snapshots</altDeploymentRepository>
			</properties>
		</profile>
	</profiles>
	
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
    </dependency>
  </dependencies>
</project>

Corresponde a un proyecto para actualizar una librería para el cálculo de similitud entre dos cadenas de texto usando diferentes métricas, originalmente publicada en sourceforge (CVS) sin mantenimiento desde hace 5 años.

En las lineas 34 a 43 se declaran los repositorios para distribución del artefacto. En la linea 16 se declara la propiedad altDeploymentRepository que sobreescribe la publicación del artefacto en el repositorio por una ruta local directorio del proyecto/mavenRepo/releases cuando se ejecuta la tarea de maven deploy. Finalmente en las lineas 82 a 89 se declara un profile para sobreescribir la propiedad altDeploymentRepository cuando se hace deploy de un snapshot.

Anuncios

Recursos estáticos en #grails

Cuando se necesita usar un recurso estático en una clase java generalmente se usa un llamado a getResource*:

Class.getResourceAsStream("/ruta/archivo") //null
ClassLoader.getResourceAsStream("/ruta/archivo") //null
ClassLoader.getResource("/ruta/archivo").openStream() //null
this.class.getResource("/ruta/archivo") //esta debería funcionar
Thread.currentThread().contextClassLoader.getResourceAsStream("/ruta/archivo") //debería funcionar

en grails nuestros recursos estáticos deben encontrarse en la ruta src/java para que se encuentren disponibles tanto para todos los entornos (incluidas pruebas unitarios), sin embargo, el uso de las alternativas anteriores no aprovecha la interfaz de Spring org.springframework.core.io.Resource que nos varias ventajas sobre la carga normal de recursos.

Para hacerlo existen varias formas, entre ellas:

ApplicationHolder.application.parentContext.getResource("classpath:$filePath") //deprecated desde 2.0
new UrlResource( StaticResourceLoader.getResource("/ruta/archivo")) //mi preferida

La última opcion hace uso de la clase StaticResourceLoader disponible desde la versión 1.2 de grails y tiene como ventajas extra el evitar usar clases deprecated y permitir ser usada en test unitarios sin tener que hacer ningun mock.

Acelerando la gestión de dependencias en #grails

Un asunto con el desarrollo de grails es la gestión de dependencias, cada vez que se ejecuta un comando (grails run-app, grails test-app, grails install-plugin xxx) el entorno verifica las dependencias (librerias, plugins, etc) declaradas para el proyecto.

En nuestros proyectos grails este periodo de tiempo tomaba de 30 a 90 segundos!!! lo cual es más que suficiente para permitir más que una leve distracción (a.k.a solo leo este articulo y listo…) así que optamos por instalar una instancia de Artifactory para tener un repositorio maven local que almacenara las dependencias sin tener que ir a hacer el chequeo a los repositorios centrales.

Eso bajó los tiempos a 10-12 segundos puesto que aún era necesario el uso del repositorio centralizado de plugins de grails que usaba (si, hasta marzo de 2012) Subversion.

Sin embargo, desde hace unos pocos días gracias JFrog los plugins se han migrado a un repositorio estándar y en nuestra instancia de Artifactory solo tuvimos que agregar un nuevo repositorio externo apuntando a http://grails.org/plugins para dejar unicamente configurados en los proyectos (BuildConfig.groovy) nuestro repositorio Artifactory:

repositories {
        /*grailsPlugins()
        grailsCentral()*/

        grailsHome()
        mavenLocal()
        mavenRepo "http://x.x.x.x:8081/artifactory/libs-release" 
        mavenRepo "http://x.x.x.x:8081/artifactory/plugins-release" 
        
        //
        /*mavenCentral()
        mavenRepo "http://snapshots.repository.codehaus.org"
        mavenRepo "http://repository.codehaus.org"
        mavenRepo "http://download.java.net/maven/2/"
        mavenRepo "http://repository.jboss.com/maven2/"*/
    }

Lo que nos permite bajar los tiempos de verificación de dependencias a 3-4 segundos!!!!. Gracias a Germán Franco por toda la ayuda en la instalación y gestión de servidores de Alephsa.