In groovy you can easily access properties by using GString which a really cool feature.
However this trick doesnt work when nested '.' are inside de expression.
In this case you can do the following:
That's all!
miércoles, octubre 09, 2013
viernes, septiembre 27, 2013
Groovy, spring, transactional y un pequeño apunte
Spring hace aveces magia negra, lo cual está muy bien salvo cuando no funciona y tienes que pararte a mirar que coño de hechizos está usando, :D.
El caso es que si tienes problemas con la gestión de transacciones delegadas a las anotaciones de Spring es probable que quieras hacer un test unitario para ver si las conexiones se cierran o no.
Como configurar el test de groovy para que ejecute la política de transacciones que quieras?
Podrían ser 1000 cosas, pero recuerda que el transactionManager solo funciona con métodos públicos.
El caso es que si tienes problemas con la gestión de transacciones delegadas a las anotaciones de Spring es probable que quieras hacer un test unitario para ver si las conexiones se cierran o no.
Como configurar el test de groovy para que ejecute la política de transacciones que quieras?
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = ["classpath:/beans/misBeans1.xml","classpath:/beans/misBeans2.xml"])
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
class SpringConnectionsTest{
static final Logger log=Logger.getLogger(SpringConnectionsTest.class)
@Autowired
ApplicationContext context;
@Before
void setTup(){
....
}
@Test
void testSomething(){
...
}
- Así que basicamente se trata de quitar la herencia al GroovyTestCase que tendría por defecto al ser un test de groovy.
- Indicar los ficheros de beans que se quieren cargar.
- Inyectar el bean (en el ejemplo cogemos el contexto podría ser cualquier bean) con @Autowired.
log4j.logger.org.springframework.transaction=DEBUGCómo podemos ver cuándo se pilla una conexion nueva o se reutiliza una?
log4j.logger.org.springframework.jdbc.datasource.DataSourceUtils=DEBUGMi método no lo engancha, ¿qué pasa?
Podrían ser 1000 cosas, pero recuerda que el transactionManager solo funciona con métodos públicos.
martes, junio 18, 2013
Configurar memoria Tomcat como 'windows service'
Cuando manejamos un Tomcat instalado en un servidor Linux personalizar las opciones de memoria (heap mínima, máxima, permsize, ..) se reduce a meter las variables o bien en las variables de entorno (JAVA_OPTS, CATALINA,OPTS) o bien a modificar el script de arranque directamente.
Sin embargo cuando el servidor es un Windows y el Tomcat está instalado como servicio la cosa difiere un poco de lo habitual, y la verdad, cuesta un poco encontrarlo.
En este caso en la carpeta
hay un ejecutable Tomcat6w.exe que permite lanzar una herramienta para arrancar/parar/reiniciar el servidor y a su vez cambiar la configuración de paramétros del servicio.
Si la arrancamos tiene una pestaña donde se puede configurar todo lo referente a la memoría y resto de parámetros, una imagen vale más que 1000 palabras:
Sin embargo cuando el servidor es un Windows y el Tomcat está instalado como servicio la cosa difiere un poco de lo habitual, y la verdad, cuesta un poco encontrarlo.
En este caso en la carpeta
TOMCAT_HOME\bin
hay un ejecutable Tomcat6w.exe que permite lanzar una herramienta para arrancar/parar/reiniciar el servidor y a su vez cambiar la configuración de paramétros del servicio.
Si la arrancamos tiene una pestaña donde se puede configurar todo lo referente a la memoría y resto de parámetros, una imagen vale más que 1000 palabras:
viernes, marzo 15, 2013
Griffon: flujo creacion mvc
Cuando se crea un MVC a través de una de las variantes de:
es fundamental entender el proceso interno que lleva a la correcta construcción del MVC. El proceso se ejecuta en 3 fases y en cada de ellas se sigue por defecto el orden lógico (modelo, vista y finalmente controlador *), la secuencia es como sigue:

La primera fase invoca al constructor de cada una de las partes, por ejemplo:
La segunda fase invoca a los setters de los objetos según los parámetros que se hayan pasado al invocar el buildMVCGroup, por ejemplo:
Es importante subrayar que sólo se invoca al setter si los nombres entre el argumento y la propiedad coinciden. Finalmente se hace el paso de 'postproducción', llamandose al mvcGroupInit de cada artefacto.
Un truco importante aqui es que el pintado de la pantalla (es decir la ejecución del script PintadorView.groovy en nuestro ejemplo) se realiza en esta última etapa después del mvcGroupInit del modelo (PintadorModel.groovy) lo cual permite hacer uso de bucles limpios en el propio script si fuera necesario algún tipo de calculo añadido sobre el modelo antes de mostrarlo:
Listo! A partir de ahora hacer mvcs no debería tener ningún secreto.
*Nota:
En realidad este orden es así por defecto dado que en la declaración del mvc en el fichero Application.groovy se sigue ese orden, si el orden fuera:
def mvc=buildMVCGroup([arg1:value1,arg2:..],"pintador")
es fundamental entender el proceso interno que lleva a la correcta construcción del MVC. El proceso se ejecuta en 3 fases y en cada de ellas se sigue por defecto el orden lógico (modelo, vista y finalmente controlador *), la secuencia es como sigue:
La primera fase invoca al constructor de cada una de las partes, por ejemplo:
PintadorController(){
...
}
La segunda fase invoca a los setters de los objetos según los parámetros que se hayan pasado al invocar el buildMVCGroup, por ejemplo:
class PintadorModel{
def arg1
...
void setArg1(def cosa){
this.arg1=cosa
}
Es importante subrayar que sólo se invoca al setter si los nombres entre el argumento y la propiedad coinciden. Finalmente se hace el paso de 'postproducción', llamandose al mvcGroupInit de cada artefacto.
void mvcGroupInit(Map args) {
...
}
Un truco importante aqui es que el pintado de la pantalla (es decir la ejecución del script PintadorView.groovy en nuestro ejemplo) se realiza en esta última etapa después del mvcGroupInit del modelo (PintadorModel.groovy) lo cual permite hacer uso de bucles limpios en el propio script si fuera necesario algún tipo de calculo añadido sobre el modelo antes de mostrarlo:
//File: PintadorModel.groovy
class PintadorModel{
def arg1
def objetos
void mvcGroupInit(Map args){
objetos=server.getObjetos(arg1)
}
}
...
//File: PintadorView.groovy
...
vbox(){
model.objetos.each{
label $it
}
}
Listo! A partir de ahora hacer mvcs no debería tener ningún secreto.
*Nota:
En realidad este orden es así por defecto dado que en la declaración del mvc en el fichero Application.groovy se sigue ese orden, si el orden fuera:
mvcGroups {
'pintador' {
model = 'com.mycompany.PintadorModel'
controller = 'com.mycompany.PintadorController'
view = 'com.mycompany.PintadorView' } .... }
el orden de invocación de los artefactos sería ese para cada una de las tres etapas.
martes, marzo 05, 2013
Griffon y el soporte en eclipse
El soporte de griffon desde eclipse es un poco limitado, lo único que hay para mejorar esto es el uso del plugin eclipse-support
En ocasiones (en windows y para jar añadidos al lib directamente) la entrada que hace en el classpath no es correcta (eclipse-support 0.6.3), para arreglarlo hay que sustituir la entrada incorrecta que tendrá la pinta siguiente
por lo siguiente
Nota:
Tengo pendiente actualizar el projecto de griffon a 1.2.0 para ver si efectivamente la version del plugin de hace unos días corrige este bug, :D.
griffon install-plugin eclipse-support
Funciona ok, no rompe y solo hay que hacer 2 consideraciones: Si el eclipse no se entera de las clases y te da avisos entre los markers de compilacion ejecuta desde la línea de comandos el script que refresca el .classpath:
griffon eclipse-update
En ocasiones (en windows y para jar añadidos al lib directamente) la entrada que hace en el classpath no es correcta (eclipse-support 0.6.3), para arreglarlo hay que sustituir la entrada incorrecta que tendrá la pinta siguiente
<classpathentry kind="var" path="C:\\..\\myproject\\lib\\cosa.jar" />
por lo siguiente
<classpathentry kind="lib" path="C:\\..\\myproject\\lib\\cosa.jar" />
Nota:
Tengo pendiente actualizar el projecto de griffon a 1.2.0 para ver si efectivamente la version del plugin de hace unos días corrige este bug, :D.
Suscribirse a:
Entradas (Atom)