java spring google-app-engine spring-aop

java - El uso de Spring AOP en App Engine causa StackOverflowError



google-app-engine spring-aop (3)

Tenemos una aplicación ejecutándose en App Engine y usando Spring framework. Recientemente, hemos agregado algunas características nuevas que se basan en AOP. Decidimos usar el estilo @AspectJ, por lo tanto, agregamos <aop:aspectj-autoproxy> en nuestra configuración basada en XML e implementamos los aspectos respectivos. Todo funciona bien en el servidor de desarrollo, sin embargo, cuando se implementa en el entorno de la nube obtenemos java.lang.StackOverflowError cada vez que se inicializa la aplicación.

El bean que no se puede crear y causa el error es una clase de configuración anotada con la anotación @Configuration . Parece que básicamente cualquier configuración Bean puede causar el error.

A continuación puede ver el seguimiento de la pila correspondiente.

org.springframework.web.context.ContextLoader initWebApplicationContext: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name ''objectifyConfig'' defined in URL [jar:file:/base/data/home/apps/{app-id}/8.372375422460842231/WEB-INF/lib/{app-name}-1.0-SNAPSHOT.jar!/{path-to-class}/ObjectifyConfig.class]: Initialization of bean failed; nested exception is java.lang.StackOverflowError at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548) at org.mortbay.jetty.servlet.Context.startContext(Context.java:136) at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250) at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517) at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50) at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:219) at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:194) at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:134) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:446) at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435) at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442) at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306) at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298) at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439) at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:251) at java.lang.Thread.run(Thread.java:724) Caused by: java.lang.StackOverflowError at java.util.concurrent.ConcurrentSkipListSet.contains(ConcurrentSkipListSet.java:214) at sun.misc.URLClassPath$LoaderSearchCursor.nextLoader(URLClassPath.java:598) at sun.misc.URLClassPath.getLoader(URLClassPath.java:365) at sun.misc.URLClassPath.findResource(URLClassPath.java:213) at java.net.URLClassLoader$2.run(URLClassLoader.java:551) at java.net.URLClassLoader$2.run(URLClassLoader.java:549) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findResource(URLClassLoader.java:548) at com.google.apphosting.runtime.security.UserClassLoader.findResource(UserClassLoader.java:723) at java.lang.ClassLoader.getResource(ClassLoader.java:1142) at com.google.apphosting.runtime.security.UserClassLoader$3.run(UserClassLoader.java:757) at com.google.apphosting.runtime.security.UserClassLoader$3.run(UserClassLoader.java:751) at java.security.AccessController.doPrivileged(Native Method) at com.google.apphosting.runtime.security.UserClassLoader.findResource(UserClassLoader.java:751) at java.lang.ClassLoader.getResource(ClassLoader.java:1142) at com.google.apphosting.runtime.security.UserClassLoader$3.run(UserClassLoader.java:757) at com.google.apphosting.runtime.security.UserClassLoader$3.run(UserClassLoader.java:751) at java.security.AccessController.doPrivileged(Native Method) at com.google.apphosting.runtime.security.UserClassLoader.findResource(UserClassLoader.java:751) at java.lang.ClassLoader.getResource(ClassLoader.java:1142) at com.google.apphosting.runtime.security.UserClassLoader$3.run(UserClassLoader.java:757) at com.google.apphosting.runtime.security.UserClassLoader$3.run(UserClassLoader.java:751) at java.security.AccessController.doPrivileged(Native Method) at com.google.apphosting.runtime.security.UserClassLoader.findResource(UserClassLoader.java:751) at java.lang.ClassLoader.getResource(ClassLoader.java:1142) ...

Actualización: pongo el problema en el rastreador de problemas de App Engine junto con la aplicación de muestra que demuestra el problema. Por favor, siga el enlace para ver detalles.


Un desbordamiento de pila generalmente indica un bucle infinito. Con aspectj podrías tener esto en el siguiente caso:

Class Logger { @Autowired ConfigService conf; //... used for logging intercepted methods } Class ConfigServiceImpl implements ConfigService { //... this is used to retrieve config }

Si ahora usa expresiones aspectj que dicen: Quiero registrar mi configServiceImpl, entonces también tendrá un bucle infinito cuando use configService:

  • interceptado por el registrador
  • configservice inyectado en el registrador intenta recuperar la configuración de registro ...
  • ==> ese servicio de configuración es interceptado por el registrador y la historia se repite

No puedo explicar por qué está funcionando en su configuración local y no en el motor de la aplicación. O por qué es solo cuando está usando @Configuration, pero creo que debería mirar en la dirección de una "dependencia circular" como esta.


Parece que el problema se ha resuelto en App Engine versión 1.9.7. Ver más detalles aquí .