Trabe ya no escribe aquí. Puedes encontrarnos en nuestra publicación en Medium: medium.com/trabe.

4Trabes Historias de una empresa en 100 metros cuadrados

El blog de Trabe Soluciones

Watchr aplicado: JUnit autotesting con Ant

| | Comentarios

Ingredientes

  1. Watchr
  2. Fichero de configuración de Watchr
  3. Tarea Ant para testear una clase con JUnit

Preparación

Instalamos Watchr en nuestro sistema (es necesario disponer de Ruby en nuestra cocina para preparar esta receta):

1
$ gem install watchr

Preparamos un fichero de configuración de Watchr (watchr.conf) y reservamos:

1
2
3
4
5
6
7
8
9
10
watch( 'src/(.*)\.java' )  do |md|
    file = "#{md[1]}Test"
    test(file) if File.exists?("test/#{file}.java")
end

watch( 'test/(.*Test)\.java' ) { |md| test(md[1]) }

def test(file)
    system("ant -Dtest=#{file.gsub("/",".")} test-file")
end

Es importante elegir los sabores adecuados de expresiones regulares para que Watchr vigile tanto el código fuente como, los ficheros de test.

Después creamos una tarea Ant que testea una clase indicada mediante párametro:

1
$ ant -Dtest=mi.paquete.MiClase test-file

Sazonamos la tarea al gusto. El chef recomienda:

1
2
3
4
5
6
7
<target name="test-file" depends="test-compile">
    <junit>
        <classpath refid="project.classpath.test"/>
        <formatter type="brief" usefile="false"/>
        <test name="${test}"/>
    </junit>
</target>

Mezclamos todo y emplatamos:

1
$ watchr watchr.conf

Algunos chefs, prefieren presentar el plato usando Ant:

1
2
3
4
5
<target name="autotest">
    <exec command="watchr">
        <arg value="watchr.conf"/>
    </exec>
</target>

Esto último es opcional, sólo para aquellos cocineros que quieran manejar todo lo relativo a su proyecto con Ant.

Gestión de dependencias en aplicaciones Play!, versión inicial: Ant + Maven

| | Comentarios

Uno de los cambios derivados de nuestra migración a Play! como framework MVC para aplicaciones web Java, es el uso de Ant como gestor de builds. En Trabe utilizamos Maven habitualmente, ya que nuestros proyectos se adaptan bien a la estructura y ciclo de vida que marca esta herramienta, sin embargo, las aplicaciones Play! y sus módulos definen su propia estructura de directorios y utilizan Ant. Maven está muy bien cuando te ciñes a su estructura de proyecto, pero si haces algo distinto se hace necesario escribir descriptores gigantes y, francamente, el soporte Ant de Play está suficientemente bien como para aceptar el cambio.

Usar Ant en este contexto sólo tiene un problema: Ant no gestiona dependencias. Para solventarlo, como no tenía mucho tiempo para pensármelo, opté inicialmente por combinar Ant y Maven. Esta solución es aplicable a cualquier proyecto que utilice Ant como gestor de builds, no sólo a los proyectos Play!

Para gestionar las dependencias con Maven, lo primero es crear un POM con lo mínimo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.4trabes</groupId>
    <artifactId>awesome</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>4Trabes awesome Play library</name>

    <dependencies>
       <dependency>
            <groupId>org.op4j</groupId>
            <artifactId>op4j</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <configuration>
                    <outputDirectory>lib/</outputDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Mínima información acerca del proyecto, nuestra lista de dependencias (sin preocuparse de los scopes) y, muy importante, la configuración del plugin de dependencias para que copie las librerías en el directorio lib (o en otro lado, a gusto del consumidor).

Ahora es cuestión de añadir a nuestro build.xml una tarea que invoque el goal copy-dependencies del plugin dependency de Maven:

1
2
3
4
5
6
7
<target name="deps">
    <exec executable="mvn">
        <arg value="-f"/>
        <arg value="deps.xml"/>
        <arg value="dependency:copy-dependencies"/>
    </exec>
</target>

Pan comido. Cada vez que ejecutemos ant deps se descargarán las librerías que no tengamos.

Si se trata de un proyecto Play!, es buena idea configurar el plugin de dependencias para que excluya las librerías que vienen de serie con el framework para evitar conflictos. Aquí os dejo las exclusiones para la versión 1.0.2.1 (creo que están todas).

1
2
3
4
5
6
7
8
9
10
<excludeArtifactIds>
    activation,antlr,backport-util-concurrent,bcprov-jdk15,c3p0,
    cglib-nodep,commons-beanutils,commons-codec,commons-fileupload,
    commons-httpclient,commons-lang,commons-logging,core,dom4j,
    ehcache,ejb3-persistence,ezmorph,filters,geronimo-servlet_2.5_spec,
    groovy-all,gson,hibernate,hibernate-core,
    hibernate-commons-annotations,hibernate-entitymanager,hsqldb,
    jamon,jaxen,jsr107cache,jta,junit,log4j,lucene-analyzers,
    lucene-core,mail,oval,snakeyaml,slf4j-api,slf4j-log4j12
</excludeArtifactIds>

Aunque esta solución es válida decidí investigar un poco más y finalmente decidí cambiar Maven2 por Ivy, que me parece más “natural”. Pero eso lo dejo para otro post.

rvm + rails3.0.0.beta + ruby 1.9.1

| | Comentarios

Desde hace unos meses estoy “viviendo en edge”. Para ello estoy usando rvm , que nos permite tener varias versiones de ruby con sus correspondientes gemas.

Tras actualizar a la beta de rails e intentar ejecutar la consola (con el nuevo comando rails console ) me topé con el siguiente error:

1
2
3
4
5
6
7
8
9
$ rails console
/home/andion/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/irb/completion.rb:9:in `require': no such file to load -- readline (LoadError)
	from /home/andion/.rvm/rubies/ruby-1.9.1-p378/lib/ruby/1.9.1/irb/completion.rb:9:in `<top (required)>'
	from /home/andion/.rvm/gems/ruby-1.9.1-p378/gems/railties-3.0.0.beta/lib/rails/commands/console.rb:3:in `require'
	from /home/andion/.rvm/gems/ruby-1.9.1-p378/gems/railties-3.0.0.beta/lib/rails/commands/console.rb:3:in `<top (required)>'
	from /home/andion/.rvm/gems/ruby-1.9.1-p378/gems/railties-3.0.0.beta/lib/rails/commands.rb:32:in `require'
	from /home/andion/.rvm/gems/ruby-1.9.1-p378/gems/railties-3.0.0.beta/lib/rails/commands.rb:32:in `<top (required)>'
	from /home/andion/git/efimera-eopages/script/rails:10:in `require'
	from /home/andion/git/efimera-eopages/script/rails:10:in `<main>'

Cuando me encontré con el problema estaba usando rvm0.1.23, rails3.0.0.beta y ruby1.9.1 pero supongo que la solución será extensible a las siguientes betas de rails (ahora mismo uso rails3 beta 3 y ruby 1.9.2 y todo sigue bien tras el fix)

Revisé algunas soluciones, pero todas estaban orientadas al uso de un ruby de sistema y no a través de rvm, además, la solución que ofrece la web de rvm aunque parecía lógica, tampoco me funcionaba:

1
2
3
$ rvm package install readline
Package 'readline' is unknown.
Usage: 'rvm package {install,uninstall} {openssl,zlib,readline,iconv,ncurses}'

Googleando un poco más si que he visto alguna gente con el mismo problema por aquí y por allá

La solución para mí: una mezcla de las solución que da rvm y la sabiduría popular: reinstalar ruby 1.9.1 con el flag: readline-dir a un directorio válido para rvm:

1
2
$ rvm uninstall 1.9.1
$ rvm install 1.9.1 --with-readline-dir=$rvm_path/.rvm/usr

Edit 06/05/2010

Tras actualizar a Ubuntu Lynx y con rvm 0.1.29 el problema se mantiene, pero la solución que poponen en la web de rvm lo arregla:

1
$ rvm package install readline ; rvm remove 1.9.1 ; rvm install 1.9.1 -C --with-readline-dir=$rvm_path/usr