Para probar esta característica he actualizado la aplicación (ahora con Tapestry 5.2) que utilicé en una entrada anterior, Hola mundo con Tapestry 5 en el Google App Engine, en la que se puede ver la aplicación funcionando en el Google App Engine programada en Java junto con la misma versión con las páginas y componentes programada en Groovy.
Sin embargo, a decir verdad, esto no creo que sea una característica de Apache Tapestry de por si sino más bien de la máquina virtual Java ya que intuyo que la misma técnica se podría aplicar a otros frameworks. La magia consiste en la forma de compilar las clases del projecto, en vez de utilizar la tarea de Ant javac para compilar hay que utilizar groovyc.
<target name="compile"> <path id="compile.lib.path"> <fileset dir="lib" includes="*.jar"/> </path> <path id="groovy.lib.path"> <fileset dir="lib" includes="groovy-all-1.8.0.jar"/> </path> <taskdef name="groovyc" classname="org.codehaus.groovy.ant.Groovyc" classpathref="groovy.lib.path"/> <mkdir dir="build/classes"/> <!-- Compilar las clases (solo java) --> <!-- <javac srcdir="src" destdir="build/classes" source="1.5" classpathref="compile.lib.path" includeAntRuntime="false"/> --> <!-- Compilar las clases java y groovy --> <groovyc srcdir="src" destdir="build/classes" classpathref="compile.lib.path"> <javac source="1.5" debug="on"/> </groovyc> </target>
En este ejemplo del componente Reloj las diferencias con Java no son muchas pero se puede ver que es código Groovy, ya que no utiliza ; para los finales de sentencia y se pueden acceder a las propiedades sin el método get. (como en el caso componentResources.id)
package com.blogspot.elblogdepicodev.tapestry.helloWorld.components import org.apache.tapestry5.Asset import org.apache.tapestry5.ComponentResources import org.apache.tapestry5.MarkupWriter import org.apache.tapestry5.annotations.Environmental import org.apache.tapestry5.annotations.Path import org.apache.tapestry5.annotations.SupportsInformalParameters import org.apache.tapestry5.ioc.annotations.Inject import org.apache.tapestry5.services.javascript.JavaScriptSupport @SupportsInformalParameters public class RelojGroovy { @Inject @Path("classpath:com/blogspot/elblogdepicodev/tapestry/helloWorld/components/Reloj.js") private Asset script @Environmental private JavaScriptSupport javaScriptSupport @Inject private ComponentResources componentResources protected void setupRender() { javaScriptSupport.importJavaScriptLibrary(script) } protected boolean beginRender(MarkupWriter writer) { def id = componentResources.id writer.element("span", "id", id) componentResources.renderInformalParameters(writer) return false } protected boolean afterRender(MarkupWriter writer) { def id = componentResources.id writer.end() javaScriptSupport.addScript("var %s = new Reloj('%s')", id, id) return true } }
Una vez compiladas las clases para la máquina virtual ya no hay diferencia entre las clases compiladas con Java y las clases compiladas con Groovy y por este motivo podemos hacer uso en Tapestry otros lenguajes además de Java. Además de compilar con groovyc lo único especial que deberemos hacer es incluir en la aplicación la librería groovy-all-1.8.0.jar para que las clases groovy funcionen correctamente.
Referencia:
Documentación sobre Apache Tapestry
Hola mundo con Tapestry 5 en el Google App Engine
Codigo fuente ejemplo Hola Mundo con Apache Tapestry 5 en Google App Engine