icono_twiter icono LinkedIn icono Facebook Icono Xing
Roberto Canales Mora

Creador y propietario de AdictosAlTrabajo.com, Director General de Autentia S.L., Ingeniero Técnico de Telecomunicaciones y Executive MBA por el Instituto de Empresa 2007.
Twitter:

Autor de los Libros: Planifica tu éxito: de aprendiz a empresario y Informática profesional, las reglas no escritas para triunfar en la empresa

Puedes consultar mi CV y alguna de mis primeras aplicaciones (de los 90) aquí

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2011-07-18

Tutorial visitado 4.489 veces Descargar en PDF
Framework Scala liftweb

Framework Scala liftweb

En el último tutorial os conté un poquito de Scala: http://www.adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=scala. Ahora vamos a dar un pasito más intentando construir una aplicación Web y para ello probaré el framework Lift para ver que nos aporta. Vamos a ver lo siguiente:

  • Como instalar Lift para Scala y trabajar desde la linea de comando.

  • Como instalar el plugin de Maven para eclipse m2e y los arquetipos de Lift para scala. Con esto crearemos el esqueleto básico de un proyecto lift y lo usaremos dentro de Eclipse compilando y ejecutando con Maven.

  • Interpretar el ejemplo Blank de Lift: nuestras primeras paginitas sobre el arquetipo.

Instalación de Lift

Antes de nada nos deberemos dar un paseo por su Web para ver los recursos disponibles http://liftweb.net/.

img1

Descargamos la última versión. Estad atentos a la que os descargáis porque luego os puede dar algún quebradero de cabeza con los generadores de código y la documentación/ejemplos.

img2

El modo más sencillo de trabajar es copiar un directorio (basic o blank) y copiarlo con otro nombre. Así partimos de algo que funciona y no perdemos el original.

img3

Vamos a seguir las instrucciones del propio manual de Lift http://simply.liftweb.net/index-13.1.html#toc-Section-13.1

Descargamos y descomprimidos, ejecutamos el comando sbt. Yo estoy en Mac y sin problemas. Eso si, recordar el ./stb

img4

Después ejecutamos el comando update en linea de comando.

img5

Y por último, ejecutamos el comando jetty:run.

Por desgracia, no acaba de funcionar correctamente y da un error de memoria

java.lang.OutOfMemoryError: PermGen space.

Bueno, esto es sencillo de solucionar. Vamos a cambiar los parámetros de arranque de la máquina virtual Java.

img6

Vamos a nuestro directorio de trabajo en este caso liff_autentia.

img7

Y editamos el fichero sbt y añadimos las entradas de tamaño.

img8

java -Xmx712M -Xss2M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -Xmx512M -Xss2M -jar `dirname $0`/sbt-launcher.jar "$@"

Volvemos a lanzar jetty:run

Ahora solamente tenemos que ir a http://localhost:8080/ y vemos el resultado de nuestro proyecto básico.

img9

Podremos modificar el código y actualizar la aplicación Web usando el comando ~prepare-webapp.

Trabajando con Lift para Scala desde Eclipse con Maven

Bueno, trabajar desde la linea puede estar bien pero casi que prefiero trabajar en eclipse.

Podríamos importar el proyecto simplemente y configurarlo pero creo que si queremos afrontar proyectos a nivel profesional en el ecosistema Java es fundamental trabajar con Maven.

Como curiosidad en Mac ya viene instalado Maven. Si pulsamos mvn -version podemos comprobar la versión actual instalada.

img10

Lo primero que haremos será descargar el plugin de Maven para eclipse, en este caso (que hay varios) el m2e.

Vamos al menú de ayuda, a instalar nuevo software. Insertamos la url del plugin http://m2eclipse.sonatype.org/sites/m2e

img11

Después de aceptar, ya lo tenemos funcionando.

Ahora vamos a crear un nuevo proyecto de tipo Maven

img12

Elegimos el workspace o entorno de trabajo por defecto y pulsamos continuar

img13

Nos aparece un menú para elegir el arquetipo deseado. Empezará por lift. Como inicialmente no lo tendremos deberemos añadirlo.

img14

En el botón configure nos aparece el menú de preferencias. Pulsaremos el botón Add Remote Catalog (añadir catalogo remoto). En la captura de la pantalla veréis como tiene que quedar: Yo le he puesto Remore: Scala

img15

Vamos a añadir la url donde se encuentran los arquetipos de Scala/Lift

http://scala-tools.org/repo-releases

img16

Ojito que tenéis que esperar un poquito a que se baje e indexe la información de los arquetipos.

Aquí ahora viene un punto crítico: fijaos bien en las versiones porque a mi me ha tocado repetirlo varias veces hasta que me ha funcionado. Tienen que ser compatibles las versiones de Scala, del plugin de eclipse, de Lift, de la máquina virtual java y de los arquetipos.

Elijo la versión net.liftweb lift-archetype-blank_2.8.1 2.3. Ojo que en el catálogo tengo seleccionado Nexus Indexer y como aparecen muchas opciones filtro por aquellos que tienen la palabra lift.

img17

El la parte inferior derecha podemos ver el avance.

img18

Seguimos con la creación de nuestro proyecto donde le doy el GroupId Autentia y el ArtifactId AutentiaScalaLift

img19

Durante un rato (también lo podemos ver en la barra inferior derecha) se descargan las dependencias y se configura nuestro proyecto blank.

Es muy posible que aparezcan errores en el árbol de proyecto dentro de Eclipse (el icono al lado de los fuentes de Scala)

Ahora tenemos que pulsar el botón derecho en el proyecto y en la opción configure (configurar) incluimos Add Scala Nature. Desaparecerán los errores de proyecto.

img20

Ahora vamos al menú run as y pulsamos la opción de configurar (lo podemos hacer tanto en release como en debug).

img21

Pulsamos el botón derecho para añadir una nueva opción para nuestro proyecto.

img22

Le damos el nombre que queramos y le asociamos el comando jetty:run

img23

Pulsamos run y, después de un rato la primera vez para bajarse todas las dependencias y arrancar ...

img24

Ya tenemos nuestra aplicación Blank funcionando.

img25

Si nos fijamos en la librería Java utilizada en nuestro proyecto, estaba trabajando con Java 1.5. Voy a cambiar a Java 1.6 para asegurarme que no tengo ningún conflicto.

Solamente tenemos que pinchar en el botón derecho sobre jre library

img26

Y elegimos la deseada. En este caso la JavaSE 1.6 instalada en MacOs.

img27

Revisión del código generado

En Lift, como en otros frameworks, Podemos devolver respuestas a tres niveles: Páginas html, respuestas de más bajo nivel con Rest y peticiones Ajax/Comet.

En este ejemplo simple solo veremos la respuesta HTML sobre una estructura básica. Podréis ver por en la documentación y arquetipos la estructura de un ejemplo MVC más realista con proyectos grandes.

Este primer ejemplo (Blank) es muy sencillito. Lo mejor que podéis hacer es verlo en detalle en la guía oficial: Exploring Lift

Todo, como siempre en una WebApp java, empieza en el fichero Web.xml. Veis como se inserta el filtro para acaparar todas las peticiones.

img28
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<filter>
  <filter-name>LiftFilter</filter-name>
  <display-name>Lift Filter</display-name>
  <description>The Filter that intercepts lift calls</description>
  <filter-class>net.liftweb.http.LiftFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>LiftFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

Cuando llega una petición se interpreta la solicitada o por defecto se procesa index.html. Vamos a ver antes un fichero auxiliar para entenderlo todo mejor (es parecido al concepto de tiles)

Buscamos en el directorio templates-hidden el fichero default.html.

Tenemos una plantilla xhtml con un cuerpo con 3 etiquetas lift: bind, Menu y msg para ligar el contenido, el menú (uso del mapa de Lift) y los mensajes (de traza o error).

img29
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
		<meta name="description" content="" />
		<meta name="keywords" content="" />
		
		<title>Autentia:AutentiaScalaLift:0.0.1-SNAPSHOT</title>
		<script id="jquery" src="/classpath/jquery.js" type="text/javascript"></script>
	</head>
	<body>
		<lift:bind name="content" />
		<lift:Menu.builder />
		<lift:msgs/>
	</body>
</html>

Podemos ver el código del html para comprobar su resolución.

img30

Si intentáis abrir cualquier fichero y os lo resuelve (muestra con un editor visual o similar) solo tenéis que pulsar el botón derecho y pulsar Open With y elegir el Text Editor.

img31

En <lift:surround with="default" at="content"> estamos diciendo que vamos a procesar en la plantilla default.html la etiqueta content.

Será resuelta la variable <b:time> por una clase java helloWorld que le va a inyectar el valor. Hacemos las declaración de nodo como <lift:helloWorld.howdy>

<lift:surround with="default" at="content">
		<h2>Welcome to your project!</h2>
		<p>
      <lift:helloWorld.howdy>
        <span>Welcome to AutentiaScalaLift at <b:time/></span>
      </lift:helloWorld.howdy>
    </p>
</lift:surround>
img32

Y en nuestro fuente la clase HelloWorld tiene un método howdy donde se vinculan a través de la clase Helpers:

package Autentia.AutentiaScalaLift {
  package snippet {
    import _root_.scala.xml.NodeSeq
    import _root_.net.liftweb.util.Helpers
    import Helpers._
	class HelloWorld {
      def howdy(in: NodeSeq): NodeSeq =
        Helpers.bind("b", in,
"time" -> (new _root_.java.util.Date).toString)
    }
  }
}

El menú se resuelve a través de la clase boot (que realmente es la primera que tendríamos que mirar aunque he preferido mostrarlo el último).

img33
package bootstrap.liftweb
import _root_.net.liftweb.common._
import _root_.net.liftweb.util._
import _root_.net.liftweb.http._
import _root_.net.liftweb.sitemap._
import _root_.net.liftweb.sitemap.Loc._
import Helpers._
/**
 * A class that's instantiated early and run.  It allows the application
 * to modify lift's environment
 */
class Boot {
  def boot {
    // where to search snippet   
	LiftRules.addToPackages("Autentia.AutentiaScalaLift")
    // Build SiteMap
    val entries = Menu(Loc("Home",
	List("index"), "Home")) :: Nil
    LiftRules.setSiteMap(SiteMap(entries:_*))
  }
}

Bueno, ya tenemos el framework lift de Scala funcionando dentro de eclipse y desde los arquetipos, por lo que poco ya nos podemos equivocar al montar la base.

Personalmente creo que antes de decantarme por un framework web voy a mirar alguno más (recordad cuando leáis esto que es Julio de 2011) porque, comparado con otros frameworks Java, me da la sensación de que Lift está en sus comienzos y quiero asegurarme de elegir el más maduro tanto en desarrollo como en facilidades y documentación.

Recursos interesantes:

http://www.assembla.com/spaces/liftweb/wiki/Using_Eclipse_with_Maven

http://www.build47.com/posts/scala-on-lift-setup-for-eclipse/

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL: