extraemos lo mejor de java y tomcat desde python

Upload: aprender-libre

Post on 05-Apr-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Extraemos lo mejor de Java y Tomcat desde Python

    1/4

    DESARROLLO Python: Jython

    50 Nmero 52 W W W. L I N U X - M A G A Z I N E . E S

    DESARROLLO Python

    Le hace poco que la razn paraemplear la plataforma Java no era ellenguaje de programacin Java, sino

    su comunidad. Por ms que nos pese, esmucho ms sencillo encontrar trabajos oproyectos en Java que en Python. Pero esesto un problema? El propio creador dePython, Guido Van Rossum, dice quePython es un entorno, no una implementa-cin. En la ltima Pycon (la gran conferen-cia mundial sobre Python), se presentaronponencias sobre distintas implementacio-nes de Python:

    CPython (el ms tradicional) IronPython (.Net) Jython (Java) Unladen Swallow (Un proyecto de Goo-

    gle para optimizar CPython) PyPy (Python programado en Python!) Stackless Python (Python especial para

    desarrollos concurrentes)Hablar de Python refirindose a la imple-mentacin en C, a la que ms acostumbra-dos estamos, es tener una idea bastanteequivocada sobre este lenguaje. Por desgra-

    cia no todas las implementaciones estn alda y es CPython quien fija el estndar alque todas aspiran.

    Jython, ver [1], es una de las implemen-taciones que ms ha calado en el mundo

    empresarial. Tanto IBM como Bea la hanescogido como sistema de scripting en susplataformas. Por desgracia, durante algu-nos aos ha parecido quedarse atrs. Estan-cada en la versin 2.2 desde 2007, muchosla daban por moribunda. Pero Jython esdemasiado importante para que ocurra algoas. En Junio de 2009 apareci su versin2.5, compatible con la misma versin deCPython.

    A lo largo de este ao se ha perfeccio-nado hasta el punto de poder ejecutar pla-taformas como Django o Pylons sin proble-

    mas. De hecho se realizaron 4 ponenciassobre Jython en la Pycon 2009, una demos-tracin del buen estado de salud del pro-yecto. Sun ha vuelto a apostar por l comoentorno de Scripting para Java.

    Echemos un vistazo a Jython 2.5 y a lasnuevas posibilidades que ofrece. Quiz conellas podamos convencer a ms de un com-paero o jefe de que es posible usar Jythonen entornos empresariales como J2EE.

    Instalacin

    Para comenzar a trabajar con Jython nece-sitamos instalarlo. Lo primero es compro-bar que dispongamos de Java en nuestrosistema. Una vez lo hayamos hecho pode-mos descargar el instalador de Jython

    desde el Recurso 1. El instalador no es otracosa sino un fichero JAR de Java. Para ini-ciar el instalador tenemos que ejecutarlocon Java:

    [josemaria@rufus ~]$ java U -jar jython_installer-2.5.0.jar

    Aparecer un programa de instalacincomo el que aparece en la Figura 1. Debere-mos aceptar la licencia y acabaremos en lapantalla que aparece en la Figura 2. En ellapodemos decidir entre distintos tipos de

    instalaciones. La ms llamativa es la empo-trada (embedded), que nos permite dis-poner de Jython, as como de toda la libre-ra de Python como un solo fichero JAR,ideal para aadir Jython a nuestro sistema

    Java.En general es recomendable la instala-

    cin completa, que instalar documenta-

    Extraemos lo mejor de Java y Tomcat desde Python

    Despus de mucho tiempo,

    Jython vuelve al escenario. Su

    versin 2.5 pone al da este intr-

    prete de Python que ha salvado

    del tedio a ms de un progra-

    mador Java.

    POR JOS MARA RUZ

    Figura 1: Instalador de Jython 2.5.

    JYTHON ALA CARGA

  • 7/31/2019 Extraemos lo mejor de Java y Tomcat desde Python

    2/4

    Python: Jython DESARROLLO

    51Nmero 52W W W. L I N U X - M A G A Z I N E . E S

    cin, el cdigo fuente (para algo estamosen el software libre) y las libreras de

    Python en su propio directorio.

    El Intrprete Jython 2.5 pretende ser absolu tamentecompatible con CPython 2.5. Las mayo-res diferencias aparecen en el soporte dedeterminadas libreras de CPython que,al estar programadas en C, no son acce-sibles desde Java. Si arrancamos elintrprete comprobaremos que nosrecibe de forma parecida a como lo haceCPython:

    $ ./jythonJython 2.5.0 U (Release_2_5_0:6476, Jun 16 U 2009, 13:33:26)[Diablo Java HotSpot(TM) Server U VM (The FreeBSD Foundation)] on U java1.6.0_07Type help, copyright, U credits or license for U more information.>>>

    Todo funciona como esperamos que lohaga, podemos disponer de las librerasPython sin ningn problema:

    >>> import datetime>>> datetime.datetime.now()datetime.datetime(2009, 6, 30, U 9, 46, 2, 141999)>>>

    La magia aparece cuando podemos comen-zar a hacer uso de las enormes libreras de

    las que dispone Java:

    >>> System.out.println U (Hola mundo)Hola mundo

    Tomcat y JythonEntremos de lleno en algo realmente intere-

    sante: crear servlets con Jython. En esteejemplo supongo que Tomcat 6.0 est ins-talado y funcionando. Vamos a comenzarcon la configuracin.

    Digamos que tenemos un directorio conla configuracin tpica en un servlet y que,por tanto, contiene el directorio WEB-INF .Un servlet no es ms que una clase Javaque responde a las peticiones realizadascontra una URL en particular. El directorioWEB-INF almacena estas clases en el direc-torio classes , mientras que las librerasnecesarias para que lleven a cabo su tra-bajo se almacenan en el directorio lib. Elfichero de configuracin web.xml , situadodentro de WEB-INF , nos permite definir losservlets que vamos a usar y las rutas en lasque respondern las peticiones.

    Lo primero que debemos hacer es copiarel fichero jython.jar , as como el directoriocon las libreras de Jython Lib , aWEB-INF/lib/ . Si no copiamos el directorio

    Lib no podremos hacer uso de las librerasde Python, slo del intrprete. En estemomento an no podemos emplear

    Jython, para ello es necesario aadir algu-nas entradas en el fichero web.xml :

    PyServlet U org.python.util. U PyServlet1 U

    Con esta configuracin indicamos a Tomcatque asigne a la clase org.python.util.PySer-vlet el nombre PyServlet . Podamos haberescogido cualquier otro nombre, pero parapoder seguir la pista usaremos el mismo de

    la clase PyServelet . Ahora necesitamos aso-ciar este servlet a una ruta o rutas:

    PyServlet U *.py

    Cualquier fichero que acabe en la exten-sin .py ser interpretado por PyServlet .Ahora slo necesitamos reiniciar Tomcat(es el mtodo ms seguro, tambin podr-amos haber reiniciado slo ese servicio).A partir de este momento, cualquier

    fichero Jython ser interpretado. En lugarde poner los ficheros dentro deWEB-INF/classes, los podemos poner

    directamente en la raz de nuestro directo-rio. Por ejemplo, si nuestro directorio es

    Pruebas , podemos crear un fichero lla-mado Pruebas/hola.py con el siguientecontenido:

    01 from java.io import *02 from javax.servlet.http

    importHttpServlet

    0304 class hola (HttpServlet):

    05 def doGet(self,request,response):

    06 self.doPost (request,response)

    07

    Listado 1: Usando las Listas Python01 from java.io import *

    02 from javax.servlet.http import HttpServlet

    03

    04 class hola (HttpServlet):05 def doGet(self,request,response):

    06 self.doPost (request,response)

    07

    08 def doPost(self,request,response):

    09 toClient = response.getWriter()

    10 response.setContentType (text/html)

    11

    12 nombres = [Juan, Alberto,Sonia,

    Francisco]

    13

    14 toClient.println ()15

    16 for nombre in nombres [1:-1]:

    17 toClient.println(Hola %s %

    nombre)

    18

    19 toClient.println()

    Figura 2: Opciones de instalacin.

  • 7/31/2019 Extraemos lo mejor de Java y Tomcat desde Python

    3/4

    DESARROLLO Python: Jython

    52 Nmero 52 W W W. L I N U X - M A G A Z I N E . E S

    import org.antlr.stringtemplate U

    as stfrom javax.servlet.http import U HttpServlet

    class Pagina(HttpServlet):

    def __init__(self):

    self.group = U st.StringTemplateGroup U

    (plantillas, U U

    /webapps/prueba/WEB-INF/ U plantillas)

    Hay que cambiar por laruta en la que se encuentre instaladonuestro Tomcat. Ahora podemos reutili-zar esta clase en nuestro servlet, here-dando de ella en lugar de hacerlo deHttpServlet:

    01 from pagina import Pagina0203 class Saludo (Pagina):

    0405 def doGet(self,request,

    response):06 self.doPost (request,

    response)070809 def doPost(self,request,

    response):10 toClient =

    response.getWriter()11 response.setContentType

    (text/html)12 plantilla = self.group.

    getInstanceOf(pagina)13 lista = [Juan,Ana,

    Vicente]

    14 plantilla.setAttribute(

    contenido, lista)15 toClient.println(plantilla.toString())

    Slo nos queda crear la plantilla pagina.st dentro del directorio plantillas:

    $contenido:{

    Hola $attr$

    }$

    El resultado es el que aparece en la Figura3.

    Procesando ParmetrosUn servlet recibe peticiones de dife-rentes tipos. Cada una de ellas (GET,POST, HEAD,) se redirecciona almtodo correspondiente. As, GET aca-bar ejecutando el mtodo doGet del ser-vlet en cuestin. Al mtodo se le pasan

    dos objetos: request y response . El pri-mero contiene la peticin que el clienteha realizado a la URL, mientras que elsegundo nos permite devolver la infor-macin.

    08 def doPost(self,request,

    response):09 toClient =response.getWriter()

    10 response.setContentType(text/html)

    11 toClient.println (Hola a todos)

    El resultado ser el que podemos ver en laFigura 2. Ya tenemos nuestro primer script

    Jython detrs de un servlet en Tomcat.Podemos modificar el fichero y ver losresultados sin necesidad de reiniciar Tom-cat (todo un alivio para muchos sufridosdesarrolladores Java).

    Empleo de LibrerasHasta el momento no hemos hecho nadaexcesivamente espectacular. La gran armade Jython es la posibilidad de combinarlibreras Java y Python (ver Listado 1). Enel cdigo podemos observar cmo hace-mos uso de algunas de las habilidades dePython. Por ejemplo, extraemos un rango

    de la lista de nombre sin el menor esfuerzo.Combinemos esta capacidad con la

    potencia de una librera Java, como porejemplo StringTemplate (ver Recurso 2).Para ello debemos copiar al directorioWEB-INF/lib los ficheros JAR: antlr-2.7.6.jar stringtemplate.jarCon estos ficheros podemos comenzar aemplear plantillas StringTemplate en nues-tro servlet. Comenzaremos por crear undirectorio llamado plantillas dentro de

    WEB-INF . En l almacenaremos las planti-llas con las que compondremos las pgi-nas. Para simplificar el trabajo crearemosuna clase llamada Pagina que guardaremosen el fichero pagina.py :

    Listado 2: Empleando Parmetros y Redireccin01 from pagina import Pagina

    02

    03 class formulario (Pagina):

    0405 html =

    06

    07

    08

    09

    10

    11

    12

    13

    14 def doGet(self,request,response):

    15 toClient = response.getWriter()16 response.setContentType (text/html)

    17 toClient.println(self.html)

    18

    19 def doPost(self,request,response):

    20 cadena = request.getParameter(cadena)

    21

    response.sendRedirect(response.encodeRedirectURL(c

    adena))

    Figura 3: Saludando desde un Servlet.

  • 7/31/2019 Extraemos lo mejor de Java y Tomcat desde Python

    4/4

    Python: Jython DESARROLLO

    53Nmero 52W W W. L I N U X - M A G A Z I N E . E S

    De request podemos extraer los parme-tros que recibe nuestro servlet. Empleandoel mtodo request.getParameter() podemosrescatar cualquiera de los parmetros quehemos recibido.

    Estudiando el cdigo del apartado ante-rior podemos comprobar cmo abrimos unflujo de datos con response.getWriter() .Todo lo que escribamos en este flujo dedatos ser enviado al cliente que realiz lapeticin. Para ello empleamos el mtodo

    println sobre el flujo de datos junto con lainformacin que queremos enviarle. Tam-bin podemos emplear response para saltara cualquier otra URL mediante el mtodoresponse.sendRedirect() .

    Combinemos estos tres mtodos en elejemplo que aparece en el Listado 2.

    Aadamos la Base de DatosEn el mundo de Java, el sistema ORM(object relational mapper) Hibernate es elestndar mundial (ver Recurso 3), pero esun sistema terriblemente complejo. Una delas respuestas de Python a Hibernate esSQLAlchemy (ver Recurso 4), un ORMdiseado en Python por un usuario avan-zado de Hibernate. Su objetivo es dar todoel poder de Hibernate pero de forma simpley cercana a Python.

    Con la llegada de Jython 2.5 y la Pycon2009, el creador de SQLAlchemy se

    embarc en una sesin de trabajo junto alos desarrolladores de Jython con el obje-tivo de conseguir que la prxima versin deSQLAlchemy, la 0.6, funcione correcta-mente sobre Jython. El resultado fue satis-

    factorio, y ya podemos descargar la versinde desarrollo 0.6 de SQLAlchemy y usarladesde Jython. Para ello es necesario descar-garla empleando subversion :

    $ svn checkout U http://svn.sqlalchemy.org/ U

    sqlalchemy/branches/ U rel_0_6 sa06

    Una vez lo hayamos hecho, deberemoscopiar el directorio sa06/lib/sqlalchemy aWEB-INF/lib/Lib . En teora sera posibleinstalar SQLAlchemy empleando el mtodoestndar jython sa06/setup.py install , perono he tenido xito configurando las rutasde Jython dentro de Tomcat (una pista,mirar los parmetros de configuracin

    python.home y python.path ).An queda un problema por resolver,

    Jython no dispone de los mismos driverspara base de datos que CPython. MientrasCPython emplea el driver psycopg2 , escritoen C, para acceder a la base de datos Pos-tgresql, en Jython no es posible usarlo.

    Java posee una potente librera de accesoa bases de datos: JDBC. Jython aprovechaesta caracterstica de Java gracias a la libre-ra zxJDBC, que envuelve JDBC con el APIde acceso a base de datos de Python. Pode-mos ver todo esto funcionando en el Lis-tado 3. Realizamos la configuracin necesa-

    ria en SQLAlchemy, y para conectar con labase de datos, empleamos una cadena deconexin que comienza con

    postgres+zxjdbc . Esta es una de las mejo-ras de SQLAlchemy 0.6: ahora es posible

    especificar tanto la base de datos con la quevamos a conectar como el driver queemplearemos para ello (en este caso

    zxjdbc ). El resto de configuraciones son lasnormales en SQLAlchemy y en esa norma-lidad es donde reside la gran sorpresa de

    Jython 2.5! El servlet sacar un listado conel nombre y precio de todos los productoscomo si fuese un programa de CPython.

    ConclusinLa versin 2.5 de Jython insufla nueva vidaa los seguidores de Python atrapados en laplataforma Java. Para bien o para mal, Javaforma parte del da a da de muchos segui-dores de Python, y Jython les permiteseguir disfrutando de la programacinPython sin abandonar el entorno en el quetienen que desarrollar su trabajo.

    La combinacin de una plataforma esta-

    ble de desarrollo web, como es Tomcat, conla velocidad de desarrollo y sencillez de

    Jython convierte esta opcin en una intere-sante alternativa para los desarrolladoresPython que buscan una plataforma msestndar y reconocida. I

    RECURSOS

    [1] Web de Jython: http://www.jython.

    org/

    [2] StringTemplate: http://www.

    stringtemplate.org/download.html

    [3] Hibernate: www.hibernate.org

    [4] SQLAlchemy: http://www.

    sqlalchemy.org/download.html

    Listado 3: SQLAlchemy en un Servlet01 from sqlalchemy import

    Column, MetaData,

    create_engine

    02 from sqlalchemy.orm importmapper,sessionmaker

    03 from

    sqlalchemy.ext.declarative

    import declarative_base

    04 from javax.servlet.http import

    HttpServlet

    05 from com.ziclix.python.sql

    import zxJDBC

    06

    07 engine =

    create_engine(postgres+zxjdbc

    ://[email protected]:5432/inventario, echo= False)

    08 Session =

    sessionmaker(bind=engine)

    09 Base = declarative_base()

    10 metadata = Base.metadata

    1112 class Producto(Base):

    13 __tablename__ = productos

    14 id =

    Column(id,primary_key=True)

    15 nombre = Column(nombre)

    16 precio = Column(precio)

    17

    18 class productos (HttpServlet):

    19

    20 def

    doGet(self,request,response):

    21 self.doPost(request,response)

    22

    23 def

    doPost(self,request,response):

    24 toClient =

    response.getWriter()25

    26 ses = Session()

    27 response.setContentType

    (text/html)

    28 lista =

    ses.query(Producto).limit(10).

    all()

    29 ses.close()

    30

    31 for producto in lista:

    32 toClient.println (

    %s

    : %s

    % (producto.nombre,33

    producto.precio))