[Geoserver-devel] [JIRA] (GEOS-11032) Unlucky init order with GeoWebCacheExtension gwcFacade before DiskQuotaMonitor

Jody Garnett created an issue

GeoServer / BugGEOS-11032

Unlucky init order with GeoWebCacheExtension gwcFacade before DiskQuotaMonitor

Issue Type:

BugBug

Affects Versions:

2.23.1

Assignee:

Unassigned

Created:

16/Jun/23 11:03 AM

Priority:

MediumMedium

Reporter:

Jody Garnett

Okay this is a sad error pointing with spring initialization order. We have an extension mechanism designed to allow beans to look up things in the spring application context. If a bean does so during construction the initialization dependency is not visible to spring and thus it cannot ensure the bean is ready for use.

I have a GeoServer with just the magic combination of extensions to result in an unlucky spring initialization order:

GridSetBroker.afterPropertiesSet()
→ GridSetBroker.getConfigurations()
→ GeoWebCacheExtensions.configurations()
→ GeoWebCacheExtensions.extensions()
→ GeoWebCacheExtensions.getBeansNamesOrderedByPriority()
gwcFacade (gs-gwc-2.23-SNAPSHOT.jar | geowebcache-geoserver-context.xml)
DiskQuotaMonitor ( gs-gwc-2.23-SNAPSHOT.jar | geowebcache-diskquota-context.xml )

As shown below:

12:43:48 ERROR  [geowebcache.GeoWebCacheExtensions] - bean lookup error
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gwcFacade' defined in URL [jar:file:/Users/jgarnett/.sdkman/candidates/tomcat/9.0.56/webapps/geoserver/WEB-INF/lib/gs-gwc-2.23-SNAPSHOT.jar!/geowebcache-geoserver-context.xml]: Cannot resolve reference to bean 'DiskQuotaMonitor' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DiskQuotaMonitor' defined in URL [jar:file:/Users/jgarnett/.sdkman/candidates/tomcat/9.0.56/webapps/geoserver/WEB-INF/lib/gs-gwc-2.23-SNAPSHOT.jar!/geowebcache-diskquota-context.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:707)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:198)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:673)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:661)
    at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1302)
    at org.geowebcache.GeoWebCacheExtensions.getBeansNamesOrderedByPriority(GeoWebCacheExtensions.java:157)
    at org.geowebcache.GeoWebCacheExtensions.extensions(GeoWebCacheExtensions.java:102)
    at org.geowebcache.GeoWebCacheExtensions.configurations(GeoWebCacheExtensions.java:205)
    at org.geowebcache.grid.GridSetBroker.getConfigurations(GridSetBroker.java:229)
    at org.geowebcache.grid.GridSetBroker.afterPropertiesSet(GridSetBroker.java:65)

Ideas for resolution:

  • spring bean order may be an option?
  • artificially introduce dependency: A dummy spring bean that can depend on DiskQuotaMonitor before gwcFacade ?
  • Troubleshoot gwcFacade so it does not look up friends in the spring-context until later? It could wait for an event indicating the context is loaded

My unsafe workaround is to randomly additional extensions (in this case geopackage-wfs-ouput ) which changed the spring initialization order just enough that the problem to be avoided.

Add Comment

Add Comment

Get Jira notifications on your phone! Download the Jira Cloud app for Android or iOS


This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100227-sha1:5147d46)

Atlassian logo