[Geoserver-devel] Intermittent GeoServer catalog problems related to layer addition/deletion

Hello,

I am running a customized GeoNode instance (which I know complicates things) that has been exhibiting a serious but intermittent problem when a layer is added or removed in the GeoServer 2.1 catalog: many layers suddenly become inaccessible via WMS/WFS with NullPointerExceptions thrown in the log (see Exception #1 below). In the GeoServer admin interface, all layers still appear in the list, but each problematic layer’s ‘Edit’ page throws a similar exception (see #2 below). Restarting geoserver’s Tomcat container resolves the issue until it happens again. The problem has increased in frequency as the site’s traffic has increased. Could this be a concurrency issue related to the catalog cache?

Exception #1:

19 Jul 09:49:14 ERROR [wms.capabilities] - An error occurred trying to determine if the layer is geometryless
java.lang.NullPointerException
	at org.geoserver.catalog.impl.DefaultCatalogFacade.getResource(DefaultCatalogFacade.java:288)
	at org.geoserver.catalog.impl.CatalogImpl.getResource(CatalogImpl.java:410)
	at org.geoserver.catalog.impl.CatalogImpl.getFeatureType(CatalogImpl.java:504)
	at org.geoserver.catalog.ResourcePool$FeatureTypeCache.removeLRU(ResourcePool.java:1359)
	at org.apache.commons.collections.map.LRUMap.addMapping(LRUMap.java:255)
	at org.apache.commons.collections.map.AbstractHashedMap.put(AbstractHashedMap.java:283)
	at org.geoserver.catalog.ResourcePool.getFeatureType(ResourcePool.java:676)
	at org.geoserver.catalog.ResourcePool.getFeatureType(ResourcePool.java:588)
	at org.geoserver.catalog.impl.FeatureTypeInfoImpl.getFeatureType(FeatureTypeInfoImpl.java:86)
	at sun.reflect.GeneratedMethodAccessor234.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.geoserver.catalog.impl.ModificationProxy.invoke(ModificationProxy.java:144)
	at $Proxy10.getFeatureType(Unknown Source)
	at org.geoserver.wms.capabilities.GetCapabilitiesTransformer$CapabilitiesTranslator.handleLayerTree(GetCapabilitiesTransformer.java:717)
	at org.geoserver.wms.capabilities.GetCapabilitiesTransformer$CapabilitiesTranslator.handleLayers(GetCapabilitiesTransformer.java:609)
	at org.geoserver.wms.capabilities.GetCapabilitiesTransformer$CapabilitiesTranslator.handleCapability(GetCapabilitiesTransformer.java:381)
	at org.geoserver.wms.capabilities.GetCapabilitiesTransformer$CapabilitiesTranslator.encode(GetCapabilitiesTransformer.java:251)
	at org.geotools.xml.transform.TransformerBase$XMLReaderSupport.parse(TransformerBase.java:715)
	at org.apache.xalan.transformer.TransformerIdentityImpl.transform(TransformerIdentityImpl.java:484)
	at org.geotools.xml.transform.TransformerBase$Task.run(TransformerBase.java:297)
	at org.geotools.xml.transform.TransformerBase.transform(TransformerBase.java:130)
	at org.geotools.xml.transform.TransformerBase.transform(TransformerBase.java:109)
	at org.geoserver.wms.capabilities.GetCapabilitiesResponse.write(GetCapabilitiesResponse.java:122)
	at org.geoserver.ows.Dispatcher.response(Dispatcher.java:757)
	at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:238)	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ThreadLocalsCleanupFilter.java:23)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:74)
	at org.geoserver.filters.SpringDelegatingFilter.doFilter(SpringDelegatingFilter.java:45)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.platform.AdvancedDispatchFilter.doFilter(AdvancedDispatchFilter.java:49)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.vfny.geoserver.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:394)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.geonode.security.GeoNodeAnonymousProcessingFilter.doFilter(GeoNodeAnonymousProcessingFilter.java:94)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.ui.basicauth.BasicProcessingFilter.doFilterHttp(BasicProcessingFilter.java:174)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.geonode.security.GeoNodeCookieProcessingFilter.doFilter(GeoNodeCookieProcessingFilter.java:107)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:185)
	at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:71)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.ReverseProxyFilter.doFilter(ReverseProxyFilter.java:183)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:41)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)	at java.lang.Thread.run(Thread.java:662)





Exception #2:

```
org.apache.wicket.WicketRuntimeException: Error attaching this container for rendering: [MarkupContainer [Component id = attributePanel]]
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1765)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.markup.repeater.AbstractRepeater.onBeforeRender(AbstractRepeater.java:151)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.extensions.markup.html.tabs.TabbedPanel.onBeforeRender(TabbedPanel.java:244)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.markup.html.form.Form.onBeforeRender(Form.java:2056)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1753)
	at org.apache.wicket.Component.onBeforeRender(Component.java:3946)
	at org.apache.wicket.Page.onBeforeRender(Page.java:1531)
	at org.apache.wicket.Component.internalBeforeRender(Component.java:1071)
	at org.apache.wicket.Component.beforeRender(Component.java:1105)
	at org.apache.wicket.Component.prepareForRender(Component.java:2292)
	at org.apache.wicket.Page.prepareForRender(Page.java:1521)
	at org.apache.wicket.Component.prepareForRender(Component.java:2329)
	at org.apache.wicket.Page.renderPage(Page.java:892)
	at org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:261)
	at org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:105)
	at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1258)
	at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329)
	at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1436)
	at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
	at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:484)
	at org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:138)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:158)
	at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
	at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ThreadLocalsCleanupFilter.java:23)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(SpringDelegatingFilter.java:74)
	at org.geoserver.filters.SpringDelegatingFilter.doFilter(SpringDelegatingFilter.java:45)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.platform.AdvancedDispatchFilter.doFilter(AdvancedDispatchFilter.java:49)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.vfny.geoserver.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:394)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
	at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.geonode.security.GeoNodeAnonymousProcessingFilter.doFilter(GeoNodeAnonymousProcessingFilter.java:94)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:278)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.ui.basicauth.BasicProcessingFilter.doFilterHttp(BasicProcessingFilter.java:174)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.geonode.security.GeoNodeCookieProcessingFilter.doFilter(GeoNodeCookieProcessingFilter.java:107)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
	at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
	at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:406)
	at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:185)
	at org.springframework.security.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:99)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.LoggingFilter.doFilter(LoggingFilter.java:71)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.ReverseProxyFilter.doFilter(ReverseProxyFilter.java:183)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.geoserver.filters.GZIPFilter.doFilter(GZIPFilter.java:41)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)	at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NullPointerException
```

On Thu, Jul 21, 2011 at 9:41 PM, Bertrand, Matt
<mbertrand@anonymised.com> wrote:

Hello,
I am running a customized GeoNode instance (which I know complicates things)
that has been exhibiting a serious but intermittent problem when a layer is
added or removed in the GeoServer 2.1 catalog: many layers suddenly become
inaccessible via WMS/WFS with NullPointerExceptions thrown in the log (see
Exception #1 below). In the GeoServer admin interface, all layers still
appear in the list, but each problematic layer's 'Edit' page throws a
similar exception (see #2 below). Restarting geoserver's Tomcat container
resolves the issue until it happens again. The problem has increased in
frequency as the site's traffic has increased. Could this be a concurrency
issue related to the catalog cache?
Exception #1:

19 Jul 09:49:14 ERROR [wms.capabilities] - An error occurred trying to
determine if the layer is geometryless
java.lang.NullPointerException
  at
org.geoserver.catalog.impl.DefaultCatalogFacade.getResource(DefaultCatalogFacade.java:288)

Never seen it, but I see how this could happen. The two blocks of relevant code:

    public <T extends ResourceInfo> T getResource(String id, Class<T> clazz) {
        List l = lookup(clazz, resources);
        for (Iterator i = l.iterator(); i.hasNext():wink: {
            ResourceInfo resource = (ResourceInfo) i.next();
            if (id.equals(resource.getId())) {
                return ModificationProxy.create((T) resource, clazz );
            }
        }

        return null;
    }

    List lookup(Class clazz, MultiHashMap map) {
        ArrayList result = new ArrayList();
        for (Iterator k = map.keySet().iterator(); k.hasNext():wink: {
            Class key = (Class) k.next();
            if (clazz.isAssignableFrom(key)) {
                result.addAll(map.getCollection(key));
            }
        }

        return result;
    }

The list returned by lookup will contain a null value if the map contents
are modified (entry removed I guess) while scanning over its contents.
A concurrent data structure should be used instead imho (probably
a combination of two concurrent structures, multimap cannot be replaced
with just one).
Or, alternatively, wrap everything with read/write locks

Cheers
Andrea

--
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------