Archivo de la etiqueta: Java

Truco: Spring 3.1 y error con persistence-unit de test.

Estaba recordando Spring, siguiendo un tutorial de Francisco Grimaldo, cuando me he encontrado con un curioso error.

Tras implementar un Unit Test para la recuperación de datos de la base de datos, la ejecución ha empezado a darme el siguiente error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [test-context.xml]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Conflicting persistence unit definitions for name ‘springappPU’: file:/H:/Users/Manuel/Documents/workspace-sts-3.1.0.RELEASE/webMeet/target/classes, file:/H:/Users/Manuel/Documents/workspace-sts-3.1.0.RELEASE/webMeet/target/test-classes
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1486)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:922)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)

Tras comprobar si había metido la pata en alguno de los pasos y darle muchas vueltas, sin encontrar dónde estaba el error, he terminado encontrando una solución en (como no) Stackoverflow.

La solución, por si os sirve a alguno de ayuda, pasa por renombrar la persistence-unit usada por los Unit Test de nombre:

test/resources/META-INF/persistence.xml

<persistence-unit name="springappPUtest" transaction-type="RESOURCE_LOCAL">
	</persistence-unit>

test/resources/test-context.xml

<property name="persistenceUnitName" value="springappPUtest"></property>

Y luego unificar en el mismo persistence.xml ambos ficheros.

main/resources/META-INF/persistence.xml

	<persistence-unit name="springappPU" transaction-type="RESOURCE_LOCAL">
	</persistence-unit>

	<persistence-unit name="springappPUtest" transaction-type="RESOURCE_LOCAL">
	</persistence-unit>

No es la solución más óptima, pero al menos permite que el Unit Test se ejecute.

Solucionar el error: ‘MAX_FRAMES_PER_TRACE limit’

Trabajando con Spring Roo y STS, es posible que llegado el momento os encontréis de bruces con este error:

28-feb-2012 10:08:12 com.springsource.insight.intercept.trace.SimpleFra meBuilder enter
GRAVE: Frame stack exceeded MAX_FRAMES_PER_TRACE limit or has been aborted limit: 3000 frameCount: 3000 aborted: false
28-feb-2012 10:08:12 com.springsource.insight.intercept.trace.SimpleFra meBuilder enter
GRAVE: Frame stack exceeded MAX_FRAMES_PER_TRACE limit or has been aborted limit: 3000 frameCount: 1 aborted: true
28-feb-2012 10:08:12 com.springsource.insight.intercept.trace.SimpleFra meBuilder enter
GRAVE: Frame stack exceeded MAX_FRAMES_PER_TRACE limit or has been aborted limit: 3000 frameCount: 1 aborted: true
28-feb-2012 10:08:12 com.vaadin.Application terminalError
GRAVE: Terminal error:
java.lang.IllegalStateException: Imbalanced frame stack! (exit() called too many times)

Este error surge por las limitaciones de Spring Insight, la máquina virtual con el servidor de desarrollo integrado en STS, que con la configuración por defecto nos genera este error en cuanto empecemos a desarrollar una aplicación que realice muchas operaciones sobre una base de datos.

Para solucionarlo, tan sencillo como añadir en la configuración de ejecución «Run -> Run Configurations -> VMware vFabric tc Server Developer Edition v2.6» el siguiente argumento al arranque de la máquina: «-Dinsight-max-frames=200000»

Tras añadir la opción, paramos el servidor y al volverlo a iniciar y lanzar nuestro proceso, ya no debería darnos el error. En el caso del ejemplo, con el valor incrementado a 200.000 nuestro proceso no volvió a fallar en local.

Java: Crear un ejecutable para tu aplicación.

En ocasiones, aunque JAVA tenga carácter multiplataforma es posible que necesitemos crear un Ejecutable para Windows, un .exe, para nuestra aplicación JAVA.

Sea por exigencia de nuestro cliente, o por el mero hecho de querer hacer una distribución estándar para un entorno Windows.

El programa que vamos a utilizar se llama JSmooth, y es un programa gratuito que teneis disponible en Sourceforge.net, y en su página teneis disponibles manuales en HTML y PDF,.

En primer lugar, debemos de descargarnos el programa e instalarlo en nuestra máquina. Tras ello lo ejecutamos y llegamos a la primera página:

Skeleton.

Pincharemos sobre los iconos de la izquierda para ir a ‘Skeleton‘, donde debemos de indicar para qué tipo de aplicación queremos crear un ejecutable, teniendo para ello un desplegable con varias opciones. Cada opción, una vez seleccionada, cuenta con una descripción del tipo de aplicación.
En nuestro caso, seleccionamos el tipo ‘Windowed Wrapper‘ que es el que más se ajusta a la aplicación Swing que tenemos.

En la parte inferior de la pantalla, vemos algunas opciones. La primera de ellas es el mensaje que queremos que se muestre cuando no se pueda encontrar un JDK instalado en la máquina cliente. Asociada a esta primera, la opción url nos permite indicar a qué url llevar al usuario si selecciona descargar un JDK.
Por defecto la url es la que SUN tiene para JAVA con la descarga directa del último JDK o JRE.

La siguente opción es si queremos que el proceso JAVA, que se lanzará para nuestra aplicación, se ejecute dentro del proceso .exe o como un proceso aparte. En nuestro caso seleccionamos que lo lance dentro del .exe.

A continuación, tenemos la opción ‘Single Instance‘, que nos servirá para indicar si queremos o no que solo se permita una instancia de nuestra aplicación ejecutándose a la vez. La marcamos porque nos interesa que solo se permita una instancia.

Las dos siguientes son propias del JSmooth, y en nuestro caso no nos interesan.

Executable.

Pasamos al siguiente paso pulsando sobre ‘Executable‘.

Aquí, le indicamos el nombre del .exe (y en qué directorio nos lo generará) que querremos que tenga nuestra aplicación.
Le podremos asociar un icono al ejecutable, y decirle cuál será el directorio de trabajo de la aplicación una vez lanzada. Le asociamos un icono, y dejamos el campo en blanco para no obligar a nuestra aplicación a tener un directorio de trabajo pre-fijado.

Application.

Pasamos al siguente paso pulsando sobre el icono ‘Application‘, y en la siguiente pantalla pasamos a configurar la clase principal de nuestra aplicación y los distintos argumentos que podemos pasarle a la misma, o a la Máquina Virtual de JAVA.

Para seleccionar la ‘Main Class‘, primero cargaremos en la sección Classpath el fichero .jar que contiene nuestra aplicación, y luego pulsaremos sobre el botón a la derecha del campo […] para seleccionar entre todas las clases del JAR la que nos interesa.

Si no tenemos argumentos que pasar a nuestra aplicación, dejamos el siguiente campo en blanco.

También podemos elegir que se incluya un JAR dentro del .exe, que será extraido al directorio de trabajo cuando lancemos la aplicación.

Y en Classpath incluiremos todos los .jar que necesite nuestra aplicación (en la siguiente entrega veremos cómo distribuirlos con el instalador).

JVM Selection.

Pasamos a la siguiente sección, y aquí podemos indicar cuál es la versión mínima, y máxima, con la que se puede ejecutar nuestra aplicación. En nuestro caso, he puesto como mínima la 1.5, y como máxima la 1.6.

Podemos indicar, si así lo queremos, que se use un JRE (Java Runtime Environment) que se distribuya con nuestra aplicación.
Aquí, lo que he hecho ha sido copiar el directorio jre del JDK que estoy usando al directorio donde voy a tener el .exe, y referenciarlo con ‘./jre’, para que lo busque más adelante en el directorio de trabajo.

La siguiente opción sirve para ordenar cómo se buscará un JRE en el sistema donde se intente ejecutar la aplicación. En nuestro caso lo dejamos tal cuál.

JVM Configuration.

Y llegamos a la última sección, donde indicaremos algunas opciones para la máquina virtual de JAVA.

Las primeras, la memoria máxima y mínima que usará la aplicación en el cliente.

Y en el cuadro inferior podremos introducir más opciones mediante la introducción de pares ‘Clave-Valor’.

Build.

Una vez hecho esto, podremos pulsar sobre el icono de la rueda dentada para que se compile el proyecto y nos genere el .exe de nuestra aplicación.