
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