Aplicación en Grails que se reinicia sin parar

Hace un rato me ha ocurrido algo muy curioso con grails. He parado el servidor y al volver a ejecutar grails run-app una vez que terminaba de arrancar se ponía a recompilar unas clases y volvía a arrancar en un bucle infinito.

Server running. Browse to http://localhost:8080/
  [groovyc] Compiling 1 source file to /home/ivan/workspace-sts/myApp/target/classes
  [groovyc] Compiling 1 source file to /home/ivan/workspace-sts/myApp/target/classes
   [delete] Deleting directory /home/ivan/.grails/1.3.7/projects/myApp/tomcat
Running Grails application..
2011-10-17 16:42:19,231 [main] INFO  spring.BeanBuilder  - [RuntimeConfiguration] Configuring data source for environment: DEVELOPMENT

He ejecutado varias veces grails-clean por si se había quedado algo raro pero seguía sin funcionar. Al final, la solución es arrancar con grails run-app –verboseCompile (cuidado que son dos guiones) para obtener información adicional. Así, una vez arrancado muestra las clases que intenta recompilar (en negrita):

Server running. Browse to http://localhost:8080/
  [groovyc] Compiling 1 source file to /home/ivan/workspace-sts/myApp/target/classes
  [groovyc] /home/ivan/workspace-sts/myApp/src/groovy/com/auth/MySuccessHandler.groovy
  [groovyc] Compiling 1 source file to /home/ivan/workspace-sts/myApp/target/classes
  [groovyc] /home/ivan/workspace-sts/myApp/src/groovy/com/auth/MySuccessHandler.groovy
   [delete] Deleting directory /home/ivan/.grails/1.3.7/projects/myApp/tomcat
Running Grails application..

Era una clase de una prueba anterior, así que la he borrado y todo se ha solucionado 🙂

Anuncios

Redireccionar después del login con spring-security-core

En un proyecto personal estoy utilizando Grails junto con spring security core para la autenticación de los usuarios.
Cuando intentamos acceder a una url que hemos configurado para permitir el acceso sólo a usuarios autenticados, el plugin nos redirige a la vista de login. Una vez autenticados nos redirecciona a la url a la que queríamos acceder inicialmente. Pero ¿qué ocurre si queremos redireccionar siempre a una url concreta?.

La solución pasa por añadir en la vista auth.gsp lo que marco en negrita:

<form action='${postUrl}?spring-security-redirect=/url-a-redireccionar'
method='POST' id='loginForm' class='cssform' autocomplete='off'>

Y eso es todo. Después de autenticarse, el usuario es redireccionado a la url elegida.

Configurar Redmine en una sub-URL

Redmine por defecto está preparado para ser servido desde http://redmine.midominio.com (o similar). Puede que nos interese instalarlo en http://www.midominio.com/redmine. Después de mirar varios tutoriales, foros y probar mil opciones, logré dar con la solución:

  • Instalar mod_passenger para apache
    # apt-get install libapache2-mod-passenger
  • Habilitar el módulo
    # aenmod passenger
  • Añadir al virtual host las dos últimas líneas
         
    <VirtualHost *:80>
         ServerName subdominio.midominio.com
         DocumentRoot /home/user/application/
    
         ErrorLog /var/log/apache2/application.log
         LogLevel warn
         CustomLog /var/log/apache2/application-access.log combined
         DirectoryIndex index.php
    
         # Para servir el redmine
         RailsBaseURI /redmine
         RailsEnv production
    </VirtualHost>
    
  • Crear un enlace simbólico desde DocumentRoot/redmine a la ruta de instalación de redmine
    # ln -s /home/user/redmine-1.1.1/public /home/user/application/redmine
  • Reiniciar apache y listo, ya podemos acceder a redmine desde http://www.midominio.com/redmine
  • Error al sincronizar un repositorio desde Redmine

    Redmine tiene una opción muy útil para obtener todos los cambios de un repositorio (subversion, mercurial,…) y poder ver de una forma rápida y sencilla quien ha subido los últimos cambios, mostrar las diferencias entre revisiones, archivos,… todo desde la interfaz gráfica.

    Hemos tenido un problema porque al entrar en la vista Repository de un proyecto obteníamos un error 500. Lanzando el proceso de actualizacioń a mano vemos claramente el error:

    root@redmine:~# /usr/bin/ruby1.8 /srv/redmine/redmine-1.1.0/script/runner "Repository.fetch_changesets" -e production
    /srv/redmine/redmine-1.1.0/vendor/rails/railties/lib/commands/runner.rb:48: /srv/redmine/redmine-1.1.0/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `log': PGError: ERROR:  secuencia de bytes no válida para codificación «UTF8»: 0xe1735f (ActiveRecord::StatementInvalid)
    HINT:  Este error también puede ocurrir si la secuencia de bytes no coinciden con la codificación esperada por el servidor, lo cual es controlado por el parámetro «client_encoding».
    : INSERT INTO "changes" ("changeset_id", "action", "branch", "path", "revision", "from_path", "from_revision") VALUES(7738, E'A', NULL, E'/doc/webdesign/prototipos/historia/131_-_ver_m�s_tejedor.html', NULL, NULL, NULL) RETURNING "id"
    ...
    (más trazas de error)
    ...
    	from /srv/redmine/redmine-1.1.0/app/models/changeset.rb:171:in `create_change'
    ...
    (más trazas de error)
    ...

    Viendo el error que he marcado en negrita nos damos cuenta de que los diseñadores han subido un archivo con la palabra “más” con alguna codificación no válida. Analizando la traza de error llegamos al archivo changeset.rb y en la línea 171 tenemos:

      # Creates a new Change from it's common parameters
      def create_change(change)
        Change.create(:changeset => self,
                      :action => change[:action],
                      :path => change[:path],
                      :from_path => change[:from_path],
                      :from_revision => change[:from_revision])
      end

    La solución pasa simplemente por convertir el valor que se almacena en path a utf8 antes de crear el objeto:

      # Creates a new Change from it's common parameters
      def create_change(change)
        Change.create(:changeset => self,
                      :action => change[:action],
                      :path => self.class.to_utf8(change[:path]),
                      :from_path => change[:from_path],
                      :from_revision => change[:from_revision])
      end

    Y listo, lanzando de nuevo el proceso de carga de los cambios en los repositorios ya no obtenemos el error 🙂