SlideShare una empresa de Scribd logo
1 de 61
Descargar para leer sin conexión
Productividad máxima con Grails y Java
“Because you're worth much more” way
 Daniel Latorre – Jordi Monné – Martín Pérez / Jobsket S.L.




          Haga clic para modificar el estilo de subtítulo del patrón




2/21/10
Sobre Nosotros
●   Martin Pérez: Javero desde hace 10 años.
    Ultimos años como senior architect/contractor
    en la industria financiera en Irlanda.
●   Daniel Latorre: Programador Java, Groovy,
    Rails, Php. Google Summer of code donde
    contribuyó a Grails.
●   Jordi Monné: Nuestro Spring expert. Javero
    profesional. ex-JavaConGanas
2/21/10
Índice
●   Acerca de Jobsket
●   Jobsket y Grails: Una historia de amor y odio
●   Integrando Grails y Java
●   Lo que nos gusta más de Grails




2/21/10
2/21/10
DEMO



2/21/10
¿Y todo esto por qué os lo contamos?
●   Porque somos sólo tres personas.
●   Que hemos hecho una aplicación técnicamente superior a
    la mayoría de sitios web de empleo.
●   Que hemos podido realizar innovaciones que nuestros
    clientes no se creen cuando las ven.
●   Que tenemos un producto sólido que actualizamos
    frecuentemente en producción, casi cada semana.
●   Y porque seguramente Grails tenga algo que ver.


2/21/10
Lucene


  Arquitectura
                                                                      Index
                                                            Lucene   LuceneLucene
                                                             Index    Index Index

                                    Scripts



                                        OS                                                            Infojobs
                                    Integration   Storage       Search




                                                                                   Crawlers
Customer              Controllers
Website




                                                                           Stats
              Views


                                                                                              Infoempleo
   Customer
   Website
                                        Spring Framework
                                                                                                    RedTrabaja
Customer
Website
                                                                                                Tecnoempleo
                                    GORM                    Hibernate



                                    Spain         Ireland        Master




    2/21/10
Cifras
●   Tomcat + Grails 1.0.5   ●   60.000 lineas de código
●   3 Instancias de MySQL   ●   70% Java
●   Un índice de Compass    ●   20 Crawling threads
●   10 índices de Lucene    ●   350 GSPs
●   1Gb Heap. 1 Major GC
    cada 24 horas.




2/21/10
2/21/10
¿Por qué Grails?
●   2008. Startup. Inseguridad. ¿Funcionará?
    ●   Al menos escojamos algo nuevo para aprender
    ●   Pero tiene que ser algo con lo que estemos familiarizados
    ●   Y que más o menos se vea que las cosas van por ahí
●   ¿RoR? : No tenemos ni idea de Ruby
●   WebFlow: Lo mismo de siempre
●   ¿Grails? Venga, probamos.

2/21/10
Escenario
●   Tres personas core Java.
●   Legacy de algún otro proyecto en Java.
●   Sistemas complejos ya desarrollados en Java.
●   Montones de librerías ya existentes en Java
    que podríamos reutilizar.
●   Así que vamos con Grails


2/21/10
Las cosas no fueron tan bonitas
●   Grails todavía en betas
●   Tentados a echar marcha atrás
●   Muy buggy hasta la versión 1.0.3
●   Muchos plugins que no funcionaban
●   Soporte en IDEs inexistente no sólo en cuanto
    a sintaxis sino usabilidad (crash cada 30mins)


2/21/10
Las cosas no fueron tan bonitas
●   Quartz Plugin. Problemas con la sincronización
    de sesiones.
●   GORM y Grails están pensados para utilizar una
    única conexión de BD.
    ●   Servicios que acceden a diferentes BDs = problema
    ●   Algún plugin pero no funcionaba bien




2/21/10
Pero por otra parte
●   Plataforma enormemente sencilla e intuitiva.
●   La integración con Spring estaba muy bien.
●   Adicción a:
    ●   La plataforma de testing
    ●   La partición en environments
    ●   La cantidad de plugins. Algunos funcionaban bastante
        bien :) (ahora son mucho más estables)
    ●   La comunidad

2/21/10
¿Comunidad?




2/21/10
Así que seguimos con Grails
●   Pero. Casi todo nuestro código está en Java
●   Sólo utilizamos Groovy en:
    ●   Controllers
    ●   TagLibs
    ●   Tests
    ●   Filters
●   Maximizar la productividad: Nuestro
    conocimiento en Java + Plataforma Grails
2/21/10
Grails y Java
●   Groovy no es excusa para no usar Grails.
●   No es que no nos guste Groovy, pero:
    ●   Es difícil encontrar perfiles en Groovy.
    ●   Las empresas tienen mucho talento en Java.
    ●   Hay muchas librerías ya en Java.
    ●   El soporte de herramientas es muy malo.
●   Sin embargo hemos encontrado que Groovy es
    muy bueno para algunas cosas.
2/21/10
¿Me interesa para mi empresa?
●   Muy productivo
●   Reaprovechamiento de nuestro legacy Java
●   Fácil partición de equipos:
    ●   Los que le gusta lo dinámico
    ●   Las viejas glorias de Java
●   El núcleo en Java y la parte dinámica en
    Groovy. A nosotros nos ha funcionado bien.

2/21/10
2/21/10
Integración de Grails y Java
●   Integramos Grails con
    ●   Hibernate, Spring, Lucene, Compass, Maven, Hudson, ...
●   No utilizar Groovy en los servicios no implica
    perder productividad
●   La clave, la plataforma Grails




2/21/10
Integración de Grails y Java
●   Integración con Spring
●   Capa de servicio completamente en Java
●   Configuración típica en resources.xml
    ●   Perdemos la posibilidad de enlazar dependencias en
        runtime
●   Sencilla y transparente
    ●   Exactamente igual que cualquier otro proyecto no
        Grails

2/21/10
Integración de Grails y Java
 ●   Integración con Spring
 ●    grails-app/conf/spring/resources.xml
<beans xmlns....>

  <import resources=”crawlers.xml”/>

  <bean id="jobOffersService" class="com.jobsket.services.JobOfferService">

     <property name="configuration" ref="freemarkerMailConfiguration" />

     <!-- otras dependencias -->

  </bean>

</beans>



 2/21/10
Integración de Grails y Java
    ●    Integración con Spring
    ●    grails-app/controllers/JobOffersController.groovy
    class JobOffersController = {

     def jobOffersService                      ID del bean de Spring

     def index = {

         def jobs = jobOffersService.lastJobOffers();

         jobs.sort{it.date}

         [jobs:jobs]

     }

}
    2/21/10
Integración de Grails y Java
    ●    Integración con Spring
    ●    grails-app/controllers/JobOffersController.groovy
    class JobOffersController = {

     def jobOffersService
                                                        Método del servicio inyectado
     def index = {

         def jobs = jobOffersService.lastJobOffers();

         jobs.sort{it.date}

         [jobs:jobs]

     }

}
    2/21/10
Integración de Grails y Java
    ●    Integración con Spring
    ●    grails-app/controllers/JobOffersController.groovy
    class JobOffersController = {

     def jobOffersService

     def index = {

         def jobs = jobOffersService.lastJobOffers();

         jobs.sort{it.date}           Groovy :)

         [jobs:jobs]

     }

}
    2/21/10
Integración de Grails y Java
●




●   Integración con Hibernate
●   Modelo mixto
    ●   GORM en algunos casos
    ●   Hibernate con HibernateDaoSupport en otros
    ●   Se mezclan perfectamente
●   Necesitabamos múltiples DataSources
    ●   El plugin no nos funcionaba demasiado bien



2/21/10
Integración de Grails y Java
●




●       Integración con Hibernate
●       Configuración para GORM
 dataSource {

        pooled = true

        driverClassName = "com.mysql.jdbc.Driver"

        username = "tu_usuario"

        password = "tu_password"

    }




2/21/10
Integración de Grails y Java
 ●




 ●    Integración con Hibernate
 ●    Configuración no GORM
<bean id="masterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"

     depends-on="mysqlJDBCDriver"

     destroy-method="close">

       <property name="jdbcUrl" value="jdbc:mysql://${master.db.server}:3306/jobsket_master"/>

       <property name="user" value="tu_usuario"/>

       <property name="password" value="tu_password"/>

</bean>




 2/21/10
Integración de Grails y Java
 ●




 ●      Integración con Hibernate
 ●      Mappings en *.hbm.xml sea para GORM o sin GORM
<hibernate-mapping package="com.jobsket.core.model">

 <class name="Role" table="roles">

     <id name="id" type="integer">

        <column name="id" />

        <generator class="identity" />

     </id>

     <property name="name" type="string" not-null="true" length="64" />

  ...

 </class>



 2/21/10
Integración de Grails y Java
●




●   Integración Spring-Groovy
●   Reutilización de variables *.groovy en la configuración Spring
●   Configuración dinámica
    ●   Setear variables en función del environment
    ●   Condicionales




2/21/10
Integración de Grails y Java
●




●     Integración Spring-Groovy
●     Fichero Spring XML
    <bean id="masterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"

       depends-on="mysqlJDBCDriver"

       destroy-method="close">

       <property name="jdbcUrl" value="jdbc:mysql://${master.db.server}:3306/jobsket_master"/>

       <property name="user" value="tu_usuario"/>

       <property name="password" value="tu_password"/>

    </bean>




2/21/10
Integración de Grails y Java
●




●     Integración Spring-Groovy
●     grails-app/conf/Config.groovy
development {                                          1 = variable según environment
                                                       2 = variable según condición
    master.db.server=”localhost" (1)

}

production {

    locale = System.getProperty("jobsket.locale")

    If (locale.equals("es")) { crawlers.ip=crawlers_es } else { crawlers.ip=crawlers_ie } (2)

    master.db.server=db_production (1)

}

2/21/10
Integración de Grails y Java
●   Integración con Spring Web Flow
    ●   Ideal para crear flujos entre páginas
    ●   Reserva billete de avión, formulario de pago, ...
●   Plugin Grails WebFlow
●   Facilidad de uso con su DSL
●   Añadir o quitar flujos sin reiniciar, genial



2/21/10
Integración de Grails y Java




2/21/10
Integración de Grails y Java




2/21/10
Integración de Grails y Java
 ●    Integración con Spring Web Flow
def registerFlow = {

  recruiterDetails {

      on("next") { ... }.to "payment"

      on("cancel").to "cancel"

  }

  payment {

       on("nextCreditcardTab") { ... }.to "confirm"

       on("nextBankTransferTab") { ... }.to "confirm"

 }


 2/21/10
Integración de Grails y Java
 ●    Integración con Spring Web Flow
def registerFlow = {

  recruiterDetails {

      on("next") { ... }.to "payment"       click en next
      on("cancel").to "cancel"

  }

  payment {

       on("nextCreditcardTab") { ... }.to "confirm"

       on("nextBankTransferTab") { ... }.to "confirm"

 }


 2/21/10
Integración de Grails y Java
●   Integración con Compass
    ●   Proyecto para integrar búsquedas full-text
●   Plug-in Searchable
    ●   No lo utilizamos
    ●   Nuestras clases de modelo són Java
●   Integración como en cualquier otro proyecto Java




2/21/10
Integración de Grails y Java
 ●   Integración con Compass
 ●   @Searchable en las entidades a indexar/buscar
 ●   Configuración en grails-app/conf/compass/compass.cfg.xml
 ●   CompassService.java
   CompassConfiguration configuration = new CompassAnnotationsConfiguration().
configure("/compass/compass.cfg.xml")

     compass = configuration.buildCompass();




 2/21/10
Integración de Grails y Java
●   Integración con Hudson
    ●   Servidor de Integración Continua
●   Hudson con plugin de Grails
●   Hudson sin plugin de Grails
    ●   Nuestra elección (ninguna razón especial)
    ●   Muy fácil de configurar para trabajar con Grails




2/21/10
Integración de Grails y Java




2/21/10
Integración de Grails y Java




2/21/10
Integración de Grails y Java
●   Integración con Maven
    ●   Herramienta para gestionar y construir proyectos Java
●   Utilizamos el plugin para Maven
●   Se combina bien con los goals por defecto
    ●   mvn clean, mvn compile
●   Añade nuevos goals
    ●   mvn grails:run-app, grails:list-plugins

2/21/10
Integración de Grails y Java
●   Integración con Maven
●   Administración de dependencias con pom.xml
    <dependencies>

    <dependency>

      <groupId>org.grails</groupId>

     <artifactId>grails-crud</artifactId>

      <version>1.1</version>

     </dependency>

    </dependencies>




2/21/10
2/21/10
Lo que más nos gusta
●   Plugins
●   Taglibs
●   Testing
●   El dinamismo de Groovy




2/21/10
Plugins
   ●   Image tools
   ●   Avatar
   ●   Twitter
   ●   Webtest
   ●   JSecurity
   ●   Grails UI (basado en Yahoo UI)




2/21/10
Componentes de Grails UI




2/21/10
Grails UI
●   Pros:
    ●   Componentes precocinados sencillos de utilizar.
    ●   Aspecto adaptable(vía css)
    ●   Se cargan sólo las dependencias js necesarias
●   Contras:
    ●   Genera código js junto al html
    ●   Dificultad para añadir/adaptar algunos comportamientos a
        los componentes.


2/21/10
Taglibs
●   Reutilizar lógica de presentación
    ●   Mucho más simple que con JSP(closure en una clase
        groovy)
    ●   Repetimos menos código en los controllers y es más
        potente que templates GSP
    ●   Posibilidad de hacer tests
    ●   Es posible reutilizarlos desde controllers y otros tags




2/21/10
Testing
●   Uno de los puntos fuertes de Grails.
●   Cubre todos los tipos de tests:
    ●   Unitarios
    ●   Integración
    ●   Funcionales(vía plugins)
●   Plugins para testing(Spock, dbUnit, Code
    Coverage, Easyb, Webtest...)


2/21/10
Tests de integración
●   Hacer tests de integración es complejo.
    ●   Hay que preparar los sistemas, las bases de datos, los
        ficheros.
    ●   Hay que gestionar la inicialización de recursos. Inicializar
        Spring, Hibernate, preparar y rellenar las bases de datos...
    ●   Mucha gente termina haciendo su framework.




2/21/10
Test de un Service
  class CvServiceTests extends GroovyTestCase {
                                                  Beans inyectados desde Spring
      def cvService

      void testFindById() {

          def cv = new CV(id:1,name:"Dani")
          cvService.save(cv)                          Accesos reales a BD

          cv = cvService.findById(1)

          assertNotNull cv
          assertEquals "Dani", cv.name
      }
  }




2/21/10
Tests para los Controllers
   ●   Es posible hacer tanto tests unitarios como de integración.
   ●   Ejecutar acciones y comprobar el estado del controlador.
   ●   Utiliza Spring Mock (MockHttpServletRequest,
       MockHttpServletResponse y MockHttpSession).




2/21/10
Test de un Controller
  class JobOfferControllerTests extends GroovyTestCase {
                                                  Beans inyectados desde Spring
    def jobOffersService

      void testCreateJobOffer() {

          def controller = new JobOffersController()
          controller.jobOffersService = jobOffersService
          controller.params.title = "Groovy Developer"
          controller.params.city = "Madrid"
                                                              Ejecuta la action
          controller.save()
          assertEquals "/joboffer/index", controller.response.redirectedUrl

          def jobOffers = jobOffersService.findAllJobOffers()         Comprueba la BD
          assertEquals 1, jobOffers.size()
          assertEquals "Madrid", jobOffers[0].city
      }
  }




2/21/10
Test Funcionales (Webtest)
class AuthWebtest extends grails.util.WebTest {
    def testLogin(){
        invoke       '/login'
        verifyText 'Entra en Jobsket'
        setInputField(name:'login',value:"dani")
        setInputField(name:'password',value:"dani")
        clickButton 'Entra'
        verifyText 'Publica tu CV'
    }
}


   ●   Alternativas: Functional Testing, Selenium, Webdriver...




2/21/10
Groovy: Añadir métodos
●    Código más limpio
    StringBuilder.metaClass.appendNotNull = { str ->
      if(str){
        append(str)
      }
    }
    ...
    def sb = new StringBuilder()
    sb.appendNotNull(unaCadena)
    sb.appendNotNull(otraCadena)
    ...
    if(unaCadena){
      sb.append(unaCadena)
    }
    if(otraCadena){
      sb.append(otraCadena)
    }




2/21/10
Groovy: Modificar métodos
●    Sin necesidad de extender una clase para un
     mock puntual
    cvService.metaClass.getOriginalInputStream = { int id->
      return new MockMultipartFile("test.pdf", new byte[0])
                                  .getInputStream()
    }




2/21/10
Groovy: Closures
●   Modificar un tag estándar de Grails
 def applicationTaglib =
 ctx.getBean("org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib")

 def createLinkJobsket = { attrs, body-> ...}
 createLinkJobsket.delegate = applicationTaglib
 createLinkJobsket.resolveStrategy = Closure.DELEGATE_FIRST
 applicationTaglib.createLink = createLinkJobsket




2/21/10
GRACIAS



2/21/10
QA




2/21/10

Más contenido relacionado

La actualidad más candente

La actualidad más candente (19)

Desarrollo en 4G(Groovy, Grails, Git, GoogleAppEngine)
Desarrollo en 4G(Groovy, Grails, Git, GoogleAppEngine)Desarrollo en 4G(Groovy, Grails, Git, GoogleAppEngine)
Desarrollo en 4G(Groovy, Grails, Git, GoogleAppEngine)
 
Testeando aplicaciones Kubernetes: escalabilidad y tolerancia a fallos
Testeando aplicaciones Kubernetes: escalabilidad y tolerancia a fallosTesteando aplicaciones Kubernetes: escalabilidad y tolerancia a fallos
Testeando aplicaciones Kubernetes: escalabilidad y tolerancia a fallos
 
Introducción a groovy & grails
Introducción a groovy & grailsIntroducción a groovy & grails
Introducción a groovy & grails
 
Cross development - React para desarrolladores de asp.net
Cross development - React para desarrolladores de asp.netCross development - React para desarrolladores de asp.net
Cross development - React para desarrolladores de asp.net
 
Introducción a Angular
Introducción a AngularIntroducción a Angular
Introducción a Angular
 
Gwt II - trabajando con gwt
Gwt II - trabajando con gwtGwt II - trabajando con gwt
Gwt II - trabajando con gwt
 
Introducción a Groovy
Introducción a GroovyIntroducción a Groovy
Introducción a Groovy
 
Javascript + Angular Sesion 2
Javascript + Angular Sesion 2Javascript + Angular Sesion 2
Javascript + Angular Sesion 2
 
Grails barcamp 2013
Grails barcamp 2013Grails barcamp 2013
Grails barcamp 2013
 
Gwt seminario java_hispano_manolocarrasco
Gwt seminario java_hispano_manolocarrascoGwt seminario java_hispano_manolocarrasco
Gwt seminario java_hispano_manolocarrasco
 
Creación de Plataformas
Creación de PlataformasCreación de Plataformas
Creación de Plataformas
 
El universo JavaScript en Drupal 7
El universo JavaScript en Drupal 7El universo JavaScript en Drupal 7
El universo JavaScript en Drupal 7
 
Taller Grails
Taller GrailsTaller Grails
Taller Grails
 
Grails en SG08
Grails en SG08Grails en SG08
Grails en SG08
 
Gwt I - entendiendo gwt
Gwt I - entendiendo gwtGwt I - entendiendo gwt
Gwt I - entendiendo gwt
 
Gwt III - Avanzado
Gwt III - AvanzadoGwt III - Avanzado
Gwt III - Avanzado
 
Sobre GrooScript
Sobre GrooScriptSobre GrooScript
Sobre GrooScript
 
Angular 6
Angular 6Angular 6
Angular 6
 
Grails
GrailsGrails
Grails
 

Destacado

Partenaires BERARD
Partenaires BERARDPartenaires BERARD
Partenaires BERARDEdgar Lenoir
 
Transcription médicale comment faire le bon choix
Transcription médicale comment faire le bon choixTranscription médicale comment faire le bon choix
Transcription médicale comment faire le bon choixAsterOffice
 
Vieux malakoff-archives-municipales
Vieux malakoff-archives-municipalesVieux malakoff-archives-municipales
Vieux malakoff-archives-municipalesarmand176
 
Ame gallery mobilier par antoine mercier -le bureau de freyja-
Ame gallery mobilier par antoine mercier -le bureau de freyja-Ame gallery mobilier par antoine mercier -le bureau de freyja-
Ame gallery mobilier par antoine mercier -le bureau de freyja-Antoine Mercier-ame
 
Formation doctorants-janvier 2015
Formation doctorants-janvier 2015Formation doctorants-janvier 2015
Formation doctorants-janvier 2015violaineg
 
Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo
Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo
Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo Neocamino
 
Conférence Internationale sur la Biodiversité et le Changement Climatique : d...
Conférence Internationale sur la Biodiversité et le Changement Climatique : d...Conférence Internationale sur la Biodiversité et le Changement Climatique : d...
Conférence Internationale sur la Biodiversité et le Changement Climatique : d...WKTL-Agency
 
Turquoise beads
Turquoise beadsTurquoise beads
Turquoise beadsIshu Gems
 
Présentation sessions d'information
Présentation sessions d'informationPrésentation sessions d'information
Présentation sessions d'informationprojetliane
 
Web campus; Vie étudiante2.0
Web campus; Vie étudiante2.0Web campus; Vie étudiante2.0
Web campus; Vie étudiante2.0Mélanie Lesgards
 
E learning cardiologie
E learning cardiologieE learning cardiologie
E learning cardiologieDurandPaul
 
Palatul achilleion grecia
Palatul achilleion greciaPalatul achilleion grecia
Palatul achilleion greciaMircea Tivadar
 

Destacado (20)

Partenaires BERARD
Partenaires BERARDPartenaires BERARD
Partenaires BERARD
 
Transcription médicale comment faire le bon choix
Transcription médicale comment faire le bon choixTranscription médicale comment faire le bon choix
Transcription médicale comment faire le bon choix
 
Vieux malakoff-archives-municipales
Vieux malakoff-archives-municipalesVieux malakoff-archives-municipales
Vieux malakoff-archives-municipales
 
O pantanal -_vu
O pantanal -_vuO pantanal -_vu
O pantanal -_vu
 
Ame gallery mobilier par antoine mercier -le bureau de freyja-
Ame gallery mobilier par antoine mercier -le bureau de freyja-Ame gallery mobilier par antoine mercier -le bureau de freyja-
Ame gallery mobilier par antoine mercier -le bureau de freyja-
 
Ent
EntEnt
Ent
 
Google Analytics
Google AnalyticsGoogle Analytics
Google Analytics
 
Síntesis didáctica junio 2014
Síntesis didáctica junio 2014Síntesis didáctica junio 2014
Síntesis didáctica junio 2014
 
Formation doctorants-janvier 2015
Formation doctorants-janvier 2015Formation doctorants-janvier 2015
Formation doctorants-janvier 2015
 
Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo
Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo
Entrepreneurs et réseaux sociaux - Master Class #2 ClubDojo
 
Conférence Internationale sur la Biodiversité et le Changement Climatique : d...
Conférence Internationale sur la Biodiversité et le Changement Climatique : d...Conférence Internationale sur la Biodiversité et le Changement Climatique : d...
Conférence Internationale sur la Biodiversité et le Changement Climatique : d...
 
Turquoise beads
Turquoise beadsTurquoise beads
Turquoise beads
 
Présentation sessions d'information
Présentation sessions d'informationPrésentation sessions d'information
Présentation sessions d'information
 
Plaquette foncier Dreal Ardèche 2013
Plaquette foncier Dreal Ardèche 2013Plaquette foncier Dreal Ardèche 2013
Plaquette foncier Dreal Ardèche 2013
 
Presentacion sanluisfinal[1]
Presentacion sanluisfinal[1]Presentacion sanluisfinal[1]
Presentacion sanluisfinal[1]
 
Courant et litteraire
Courant et litteraireCourant et litteraire
Courant et litteraire
 
Web campus; Vie étudiante2.0
Web campus; Vie étudiante2.0Web campus; Vie étudiante2.0
Web campus; Vie étudiante2.0
 
Carte de visite
Carte de visiteCarte de visite
Carte de visite
 
E learning cardiologie
E learning cardiologieE learning cardiologie
E learning cardiologie
 
Palatul achilleion grecia
Palatul achilleion greciaPalatul achilleion grecia
Palatul achilleion grecia
 

Similar a Jobsket Spring 2GX Madrid

Grails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - SistemasGrails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - SistemasCarlos Camacho
 
Los mejores trucos y prácticas para configurar drupal
Los mejores trucos y prácticas para configurar drupalLos mejores trucos y prácticas para configurar drupal
Los mejores trucos y prácticas para configurar drupalSiteGround España
 
Template paper-2015
Template paper-2015Template paper-2015
Template paper-2015facinger2
 
Programación basada en componentes para Programadores Python
Programación basada en componentes para Programadores PythonProgramación basada en componentes para Programadores Python
Programación basada en componentes para Programadores PythonCovantec R.L.
 
Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011
Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011
Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011Fátima Casaú Pérez
 
Rendimiento Java Script - Programador PHP
Rendimiento  Java Script - Programador PHPRendimiento  Java Script - Programador PHP
Rendimiento Java Script - Programador PHPJuan Belón Pérez
 
Los reinos de finizens - Nuestro stark tecnológico
Los reinos de finizens - Nuestro stark tecnológicoLos reinos de finizens - Nuestro stark tecnológico
Los reinos de finizens - Nuestro stark tecnológicoFinizens
 
Vaadin y Grails Barcamp 2013
Vaadin y Grails Barcamp 2013Vaadin y Grails Barcamp 2013
Vaadin y Grails Barcamp 2013Carlos Camacho
 
Html5, Rest, JSON, Angular JS y Java EE 7 - Aplicaciones Web Modernas y Esca...
Html5, Rest, JSON, Angular JS y Java EE 7  - Aplicaciones Web Modernas y Esca...Html5, Rest, JSON, Angular JS y Java EE 7  - Aplicaciones Web Modernas y Esca...
Html5, Rest, JSON, Angular JS y Java EE 7 - Aplicaciones Web Modernas y Esca...Eudris Cabrera
 
¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?Jorge Franco Leza
 
VLCTechFest - Simplificando Controladores: Una introducción a Action-Domain ...
VLCTechFest -  Simplificando Controladores: Una introducción a Action-Domain ...VLCTechFest -  Simplificando Controladores: Una introducción a Action-Domain ...
VLCTechFest - Simplificando Controladores: Una introducción a Action-Domain ...Miguel Ángel Sánchez Chordi
 
Jsf Java Server Faces
Jsf   Java Server FacesJsf   Java Server Faces
Jsf Java Server Facescok12v
 
Desarrollo de aplicaciones multiplataforma 2/2
Desarrollo de aplicaciones multiplataforma 2/2Desarrollo de aplicaciones multiplataforma 2/2
Desarrollo de aplicaciones multiplataforma 2/2Ignacio Muñoz Vicente
 
5 c arquitecturas_aplicaciones_web
5 c arquitecturas_aplicaciones_web5 c arquitecturas_aplicaciones_web
5 c arquitecturas_aplicaciones_webJuy JLopez
 
ReConnect 2015 - ASP.NET 5: MVC 6 y EF 7
ReConnect 2015  - ASP.NET 5: MVC 6 y EF 7ReConnect 2015  - ASP.NET 5: MVC 6 y EF 7
ReConnect 2015 - ASP.NET 5: MVC 6 y EF 7Luis Ruiz Pavón
 
Timerepublik
TimerepublikTimerepublik
Timerepublikbetabeers
 
Orquestando Pipelines de Datosen AWS con Step Function y AWS Glue
Orquestando Pipelines de Datosen AWS con Step Function y AWS GlueOrquestando Pipelines de Datosen AWS con Step Function y AWS Glue
Orquestando Pipelines de Datosen AWS con Step Function y AWS GlueGlobant
 

Similar a Jobsket Spring 2GX Madrid (20)

Integrando AngularJS y drupal
Integrando AngularJS y drupalIntegrando AngularJS y drupal
Integrando AngularJS y drupal
 
Grails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - SistemasGrails 2013 - PUCMM - Santiago - Sistemas
Grails 2013 - PUCMM - Santiago - Sistemas
 
Los mejores trucos y prácticas para configurar drupal
Los mejores trucos y prácticas para configurar drupalLos mejores trucos y prácticas para configurar drupal
Los mejores trucos y prácticas para configurar drupal
 
Template paper-2015
Template paper-2015Template paper-2015
Template paper-2015
 
Programación basada en componentes para Programadores Python
Programación basada en componentes para Programadores PythonProgramación basada en componentes para Programadores Python
Programación basada en componentes para Programadores Python
 
Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011
Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011
Taller Testing en Grails con Grails y Geb (WebDriver) - Springio I/O 2011
 
Rendimiento Java Script - Programador PHP
Rendimiento  Java Script - Programador PHPRendimiento  Java Script - Programador PHP
Rendimiento Java Script - Programador PHP
 
Los reinos de finizens - Nuestro stark tecnológico
Los reinos de finizens - Nuestro stark tecnológicoLos reinos de finizens - Nuestro stark tecnológico
Los reinos de finizens - Nuestro stark tecnológico
 
Vaadin y Grails Barcamp 2013
Vaadin y Grails Barcamp 2013Vaadin y Grails Barcamp 2013
Vaadin y Grails Barcamp 2013
 
Html5, Rest, JSON, Angular JS y Java EE 7 - Aplicaciones Web Modernas y Esca...
Html5, Rest, JSON, Angular JS y Java EE 7  - Aplicaciones Web Modernas y Esca...Html5, Rest, JSON, Angular JS y Java EE 7  - Aplicaciones Web Modernas y Esca...
Html5, Rest, JSON, Angular JS y Java EE 7 - Aplicaciones Web Modernas y Esca...
 
¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?¿Grails + DDD + Eventsourcing + CQRS?
¿Grails + DDD + Eventsourcing + CQRS?
 
VLCTechFest - Simplificando Controladores: Una introducción a Action-Domain ...
VLCTechFest -  Simplificando Controladores: Una introducción a Action-Domain ...VLCTechFest -  Simplificando Controladores: Una introducción a Action-Domain ...
VLCTechFest - Simplificando Controladores: Una introducción a Action-Domain ...
 
Jsf Java Server Faces
Jsf   Java Server FacesJsf   Java Server Faces
Jsf Java Server Faces
 
202204-Modernizando aplicaciones legacy
202204-Modernizando aplicaciones legacy202204-Modernizando aplicaciones legacy
202204-Modernizando aplicaciones legacy
 
Desarrollo de aplicaciones multiplataforma 2/2
Desarrollo de aplicaciones multiplataforma 2/2Desarrollo de aplicaciones multiplataforma 2/2
Desarrollo de aplicaciones multiplataforma 2/2
 
5 c arquitecturas_aplicaciones_web
5 c arquitecturas_aplicaciones_web5 c arquitecturas_aplicaciones_web
5 c arquitecturas_aplicaciones_web
 
ReConnect 2015 - ASP.NET 5: MVC 6 y EF 7
ReConnect 2015  - ASP.NET 5: MVC 6 y EF 7ReConnect 2015  - ASP.NET 5: MVC 6 y EF 7
ReConnect 2015 - ASP.NET 5: MVC 6 y EF 7
 
Timerepublik
TimerepublikTimerepublik
Timerepublik
 
Orquestando Pipelines de Datosen AWS con Step Function y AWS Glue
Orquestando Pipelines de Datosen AWS con Step Function y AWS GlueOrquestando Pipelines de Datosen AWS con Step Function y AWS Glue
Orquestando Pipelines de Datosen AWS con Step Function y AWS Glue
 
Aprendiendo GWT
Aprendiendo GWTAprendiendo GWT
Aprendiendo GWT
 

Último

Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfvladimiroflores1
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.FlorenciaCattelani
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxMiguelAtencio10
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estossgonzalezp1
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITMaricarmen Sánchez Ruiz
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanamcerpam
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...JohnRamos830530
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxAlan779941
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfAnnimoUno1
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21mariacbr99
 

Último (11)

Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 

Jobsket Spring 2GX Madrid

  • 1. Productividad máxima con Grails y Java “Because you're worth much more” way Daniel Latorre – Jordi Monné – Martín Pérez / Jobsket S.L. Haga clic para modificar el estilo de subtítulo del patrón 2/21/10
  • 2. Sobre Nosotros ● Martin Pérez: Javero desde hace 10 años. Ultimos años como senior architect/contractor en la industria financiera en Irlanda. ● Daniel Latorre: Programador Java, Groovy, Rails, Php. Google Summer of code donde contribuyó a Grails. ● Jordi Monné: Nuestro Spring expert. Javero profesional. ex-JavaConGanas 2/21/10
  • 3. Índice ● Acerca de Jobsket ● Jobsket y Grails: Una historia de amor y odio ● Integrando Grails y Java ● Lo que nos gusta más de Grails 2/21/10
  • 6. ¿Y todo esto por qué os lo contamos? ● Porque somos sólo tres personas. ● Que hemos hecho una aplicación técnicamente superior a la mayoría de sitios web de empleo. ● Que hemos podido realizar innovaciones que nuestros clientes no se creen cuando las ven. ● Que tenemos un producto sólido que actualizamos frecuentemente en producción, casi cada semana. ● Y porque seguramente Grails tenga algo que ver. 2/21/10
  • 7. Lucene Arquitectura Index Lucene LuceneLucene Index Index Index Scripts OS Infojobs Integration Storage Search Crawlers Customer Controllers Website Stats Views Infoempleo Customer Website Spring Framework RedTrabaja Customer Website Tecnoempleo GORM Hibernate Spain Ireland Master 2/21/10
  • 8. Cifras ● Tomcat + Grails 1.0.5 ● 60.000 lineas de código ● 3 Instancias de MySQL ● 70% Java ● Un índice de Compass ● 20 Crawling threads ● 10 índices de Lucene ● 350 GSPs ● 1Gb Heap. 1 Major GC cada 24 horas. 2/21/10
  • 10. ¿Por qué Grails? ● 2008. Startup. Inseguridad. ¿Funcionará? ● Al menos escojamos algo nuevo para aprender ● Pero tiene que ser algo con lo que estemos familiarizados ● Y que más o menos se vea que las cosas van por ahí ● ¿RoR? : No tenemos ni idea de Ruby ● WebFlow: Lo mismo de siempre ● ¿Grails? Venga, probamos. 2/21/10
  • 11. Escenario ● Tres personas core Java. ● Legacy de algún otro proyecto en Java. ● Sistemas complejos ya desarrollados en Java. ● Montones de librerías ya existentes en Java que podríamos reutilizar. ● Así que vamos con Grails 2/21/10
  • 12. Las cosas no fueron tan bonitas ● Grails todavía en betas ● Tentados a echar marcha atrás ● Muy buggy hasta la versión 1.0.3 ● Muchos plugins que no funcionaban ● Soporte en IDEs inexistente no sólo en cuanto a sintaxis sino usabilidad (crash cada 30mins) 2/21/10
  • 13. Las cosas no fueron tan bonitas ● Quartz Plugin. Problemas con la sincronización de sesiones. ● GORM y Grails están pensados para utilizar una única conexión de BD. ● Servicios que acceden a diferentes BDs = problema ● Algún plugin pero no funcionaba bien 2/21/10
  • 14. Pero por otra parte ● Plataforma enormemente sencilla e intuitiva. ● La integración con Spring estaba muy bien. ● Adicción a: ● La plataforma de testing ● La partición en environments ● La cantidad de plugins. Algunos funcionaban bastante bien :) (ahora son mucho más estables) ● La comunidad 2/21/10
  • 16. Así que seguimos con Grails ● Pero. Casi todo nuestro código está en Java ● Sólo utilizamos Groovy en: ● Controllers ● TagLibs ● Tests ● Filters ● Maximizar la productividad: Nuestro conocimiento en Java + Plataforma Grails 2/21/10
  • 17. Grails y Java ● Groovy no es excusa para no usar Grails. ● No es que no nos guste Groovy, pero: ● Es difícil encontrar perfiles en Groovy. ● Las empresas tienen mucho talento en Java. ● Hay muchas librerías ya en Java. ● El soporte de herramientas es muy malo. ● Sin embargo hemos encontrado que Groovy es muy bueno para algunas cosas. 2/21/10
  • 18. ¿Me interesa para mi empresa? ● Muy productivo ● Reaprovechamiento de nuestro legacy Java ● Fácil partición de equipos: ● Los que le gusta lo dinámico ● Las viejas glorias de Java ● El núcleo en Java y la parte dinámica en Groovy. A nosotros nos ha funcionado bien. 2/21/10
  • 20. Integración de Grails y Java ● Integramos Grails con ● Hibernate, Spring, Lucene, Compass, Maven, Hudson, ... ● No utilizar Groovy en los servicios no implica perder productividad ● La clave, la plataforma Grails 2/21/10
  • 21. Integración de Grails y Java ● Integración con Spring ● Capa de servicio completamente en Java ● Configuración típica en resources.xml ● Perdemos la posibilidad de enlazar dependencias en runtime ● Sencilla y transparente ● Exactamente igual que cualquier otro proyecto no Grails 2/21/10
  • 22. Integración de Grails y Java ● Integración con Spring ● grails-app/conf/spring/resources.xml <beans xmlns....> <import resources=”crawlers.xml”/> <bean id="jobOffersService" class="com.jobsket.services.JobOfferService"> <property name="configuration" ref="freemarkerMailConfiguration" /> <!-- otras dependencias --> </bean> </beans> 2/21/10
  • 23. Integración de Grails y Java ● Integración con Spring ● grails-app/controllers/JobOffersController.groovy class JobOffersController = { def jobOffersService ID del bean de Spring def index = { def jobs = jobOffersService.lastJobOffers(); jobs.sort{it.date} [jobs:jobs] } } 2/21/10
  • 24. Integración de Grails y Java ● Integración con Spring ● grails-app/controllers/JobOffersController.groovy class JobOffersController = { def jobOffersService Método del servicio inyectado def index = { def jobs = jobOffersService.lastJobOffers(); jobs.sort{it.date} [jobs:jobs] } } 2/21/10
  • 25. Integración de Grails y Java ● Integración con Spring ● grails-app/controllers/JobOffersController.groovy class JobOffersController = { def jobOffersService def index = { def jobs = jobOffersService.lastJobOffers(); jobs.sort{it.date} Groovy :) [jobs:jobs] } } 2/21/10
  • 26. Integración de Grails y Java ● ● Integración con Hibernate ● Modelo mixto ● GORM en algunos casos ● Hibernate con HibernateDaoSupport en otros ● Se mezclan perfectamente ● Necesitabamos múltiples DataSources ● El plugin no nos funcionaba demasiado bien 2/21/10
  • 27. Integración de Grails y Java ● ● Integración con Hibernate ● Configuración para GORM dataSource { pooled = true driverClassName = "com.mysql.jdbc.Driver" username = "tu_usuario" password = "tu_password" } 2/21/10
  • 28. Integración de Grails y Java ● ● Integración con Hibernate ● Configuración no GORM <bean id="masterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" depends-on="mysqlJDBCDriver" destroy-method="close"> <property name="jdbcUrl" value="jdbc:mysql://${master.db.server}:3306/jobsket_master"/> <property name="user" value="tu_usuario"/> <property name="password" value="tu_password"/> </bean> 2/21/10
  • 29. Integración de Grails y Java ● ● Integración con Hibernate ● Mappings en *.hbm.xml sea para GORM o sin GORM <hibernate-mapping package="com.jobsket.core.model"> <class name="Role" table="roles"> <id name="id" type="integer"> <column name="id" /> <generator class="identity" /> </id> <property name="name" type="string" not-null="true" length="64" /> ... </class> 2/21/10
  • 30. Integración de Grails y Java ● ● Integración Spring-Groovy ● Reutilización de variables *.groovy en la configuración Spring ● Configuración dinámica ● Setear variables en función del environment ● Condicionales 2/21/10
  • 31. Integración de Grails y Java ● ● Integración Spring-Groovy ● Fichero Spring XML <bean id="masterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" depends-on="mysqlJDBCDriver" destroy-method="close"> <property name="jdbcUrl" value="jdbc:mysql://${master.db.server}:3306/jobsket_master"/> <property name="user" value="tu_usuario"/> <property name="password" value="tu_password"/> </bean> 2/21/10
  • 32. Integración de Grails y Java ● ● Integración Spring-Groovy ● grails-app/conf/Config.groovy development { 1 = variable según environment 2 = variable según condición master.db.server=”localhost" (1) } production { locale = System.getProperty("jobsket.locale") If (locale.equals("es")) { crawlers.ip=crawlers_es } else { crawlers.ip=crawlers_ie } (2) master.db.server=db_production (1) } 2/21/10
  • 33. Integración de Grails y Java ● Integración con Spring Web Flow ● Ideal para crear flujos entre páginas ● Reserva billete de avión, formulario de pago, ... ● Plugin Grails WebFlow ● Facilidad de uso con su DSL ● Añadir o quitar flujos sin reiniciar, genial 2/21/10
  • 34. Integración de Grails y Java 2/21/10
  • 35. Integración de Grails y Java 2/21/10
  • 36. Integración de Grails y Java ● Integración con Spring Web Flow def registerFlow = { recruiterDetails { on("next") { ... }.to "payment" on("cancel").to "cancel" } payment { on("nextCreditcardTab") { ... }.to "confirm" on("nextBankTransferTab") { ... }.to "confirm" } 2/21/10
  • 37. Integración de Grails y Java ● Integración con Spring Web Flow def registerFlow = { recruiterDetails { on("next") { ... }.to "payment" click en next on("cancel").to "cancel" } payment { on("nextCreditcardTab") { ... }.to "confirm" on("nextBankTransferTab") { ... }.to "confirm" } 2/21/10
  • 38. Integración de Grails y Java ● Integración con Compass ● Proyecto para integrar búsquedas full-text ● Plug-in Searchable ● No lo utilizamos ● Nuestras clases de modelo són Java ● Integración como en cualquier otro proyecto Java 2/21/10
  • 39. Integración de Grails y Java ● Integración con Compass ● @Searchable en las entidades a indexar/buscar ● Configuración en grails-app/conf/compass/compass.cfg.xml ● CompassService.java CompassConfiguration configuration = new CompassAnnotationsConfiguration(). configure("/compass/compass.cfg.xml") compass = configuration.buildCompass(); 2/21/10
  • 40. Integración de Grails y Java ● Integración con Hudson ● Servidor de Integración Continua ● Hudson con plugin de Grails ● Hudson sin plugin de Grails ● Nuestra elección (ninguna razón especial) ● Muy fácil de configurar para trabajar con Grails 2/21/10
  • 41. Integración de Grails y Java 2/21/10
  • 42. Integración de Grails y Java 2/21/10
  • 43. Integración de Grails y Java ● Integración con Maven ● Herramienta para gestionar y construir proyectos Java ● Utilizamos el plugin para Maven ● Se combina bien con los goals por defecto ● mvn clean, mvn compile ● Añade nuevos goals ● mvn grails:run-app, grails:list-plugins 2/21/10
  • 44. Integración de Grails y Java ● Integración con Maven ● Administración de dependencias con pom.xml <dependencies> <dependency> <groupId>org.grails</groupId> <artifactId>grails-crud</artifactId> <version>1.1</version> </dependency> </dependencies> 2/21/10
  • 46. Lo que más nos gusta ● Plugins ● Taglibs ● Testing ● El dinamismo de Groovy 2/21/10
  • 47. Plugins ● Image tools ● Avatar ● Twitter ● Webtest ● JSecurity ● Grails UI (basado en Yahoo UI) 2/21/10
  • 48. Componentes de Grails UI 2/21/10
  • 49. Grails UI ● Pros: ● Componentes precocinados sencillos de utilizar. ● Aspecto adaptable(vía css) ● Se cargan sólo las dependencias js necesarias ● Contras: ● Genera código js junto al html ● Dificultad para añadir/adaptar algunos comportamientos a los componentes. 2/21/10
  • 50. Taglibs ● Reutilizar lógica de presentación ● Mucho más simple que con JSP(closure en una clase groovy) ● Repetimos menos código en los controllers y es más potente que templates GSP ● Posibilidad de hacer tests ● Es posible reutilizarlos desde controllers y otros tags 2/21/10
  • 51. Testing ● Uno de los puntos fuertes de Grails. ● Cubre todos los tipos de tests: ● Unitarios ● Integración ● Funcionales(vía plugins) ● Plugins para testing(Spock, dbUnit, Code Coverage, Easyb, Webtest...) 2/21/10
  • 52. Tests de integración ● Hacer tests de integración es complejo. ● Hay que preparar los sistemas, las bases de datos, los ficheros. ● Hay que gestionar la inicialización de recursos. Inicializar Spring, Hibernate, preparar y rellenar las bases de datos... ● Mucha gente termina haciendo su framework. 2/21/10
  • 53. Test de un Service class CvServiceTests extends GroovyTestCase { Beans inyectados desde Spring def cvService void testFindById() { def cv = new CV(id:1,name:"Dani") cvService.save(cv) Accesos reales a BD cv = cvService.findById(1) assertNotNull cv assertEquals "Dani", cv.name } } 2/21/10
  • 54. Tests para los Controllers ● Es posible hacer tanto tests unitarios como de integración. ● Ejecutar acciones y comprobar el estado del controlador. ● Utiliza Spring Mock (MockHttpServletRequest, MockHttpServletResponse y MockHttpSession). 2/21/10
  • 55. Test de un Controller class JobOfferControllerTests extends GroovyTestCase { Beans inyectados desde Spring def jobOffersService void testCreateJobOffer() { def controller = new JobOffersController() controller.jobOffersService = jobOffersService controller.params.title = "Groovy Developer" controller.params.city = "Madrid" Ejecuta la action controller.save() assertEquals "/joboffer/index", controller.response.redirectedUrl def jobOffers = jobOffersService.findAllJobOffers() Comprueba la BD assertEquals 1, jobOffers.size() assertEquals "Madrid", jobOffers[0].city } } 2/21/10
  • 56. Test Funcionales (Webtest) class AuthWebtest extends grails.util.WebTest { def testLogin(){ invoke '/login' verifyText 'Entra en Jobsket' setInputField(name:'login',value:"dani") setInputField(name:'password',value:"dani") clickButton 'Entra' verifyText 'Publica tu CV' } } ● Alternativas: Functional Testing, Selenium, Webdriver... 2/21/10
  • 57. Groovy: Añadir métodos ● Código más limpio StringBuilder.metaClass.appendNotNull = { str -> if(str){ append(str) } } ... def sb = new StringBuilder() sb.appendNotNull(unaCadena) sb.appendNotNull(otraCadena) ... if(unaCadena){ sb.append(unaCadena) } if(otraCadena){ sb.append(otraCadena) } 2/21/10
  • 58. Groovy: Modificar métodos ● Sin necesidad de extender una clase para un mock puntual cvService.metaClass.getOriginalInputStream = { int id-> return new MockMultipartFile("test.pdf", new byte[0]) .getInputStream() } 2/21/10
  • 59. Groovy: Closures ● Modificar un tag estándar de Grails def applicationTaglib = ctx.getBean("org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib") def createLinkJobsket = { attrs, body-> ...} createLinkJobsket.delegate = applicationTaglib createLinkJobsket.resolveStrategy = Closure.DELEGATE_FIRST applicationTaglib.createLink = createLinkJobsket 2/21/10