Bug 52042 - Possible NullPointerException in DefaultInstanceManager#processAnnotations
Summary: Possible NullPointerException in DefaultInstanceManager#processAnnotations
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 7.0.22
Hardware: PC All
: P2 critical (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-10-17 14:39 UTC by Gurkan Erdogdu
Modified: 2011-10-19 09:32 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gurkan Erdogdu 2011-10-17 14:39:00 UTC
NullPointerException exception is thrown randomly from "DefaultInstanceManager#processAnnotations" method on the following lines,

 List<AnnotationCacheEntry> annotations;
            synchronized (annotationCache) {
                annotations = annotationCache.get(clazz).get();
            }

            //Null Pointer Exception is thrown, because annotations is NULL
            for (AnnotationCacheEntry entry : annotations) {


For example, I have a JSF Managed Bean 

public class X extends Y{
}

Open JSF page that contains managed bean X. Randomly opening the same page throws NullPointerException because for superclass Y "annotations = annotationCache.get(clazz).get();" returns null.

Using WeakHashMap on "annotationCache" field may be the reason of exception.
Comment 1 Mark Thomas 2011-10-17 15:07:33 UTC
That code snippet could refer to several places in the DefaultInstanceManager. Please provide the full stack trace.

I don't think the use of WeakReferences is the problem since there should be a strong reference present to prevent the collection of the weak reference until the point where the web app is reloaded.

We have seen issues where annotations weren't scanned because objects weren't created through the instance manager. That is another possible explanation.
Comment 2 Gurkan Erdogdu 2011-10-17 16:03:03 UTC
Here is the full stack trace

java.lang.NullPointerException
	at org.apache.catalina.core.DefaultInstanceManager.processAnnotations(DefaultInstanceManager.java:460)
	at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:146)
	at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:139)
	at org.apache.myfaces.config.annotation.Tomcat7AnnotationLifecycleProvider.postConstruct(Tomcat7AnnotationLifecycleProvider.java:90)
	at org.apache.myfaces.config.ManagedBeanBuilder.buildManagedBean(ManagedBeanBuilder.java:211)
	at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.createManagedBean(ManagedBeanResolver.java:332)
	at org.apache.myfaces.el.unified.resolver.ManagedBeanResolver.getValue(ManagedBeanResolver.java:295)
	at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:67)
	at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
	at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:65)
	at org.apache.myfaces.el.convert.VariableResolverToELResolver.getValue(VariableResolverToELResolver.java:116)
	at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:67)
	at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142)
	at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:71)
	at org.apache.el.parser.AstValue.getValue(AstValue.java:147)
	at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
	at com.sun.facelets.el.TagValueExpression.getValue(TagValueExpression.java:71)
	at org.apache.myfaces.application.ApplicationImpl.createComponent(ApplicationImpl.java:433)
	at com.sun.facelets.tag.jsf.ComponentHandler.createComponent(ComponentHandler.java:224)
	at com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:139)
	at com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHandler.java:314)
	at com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:169)
	at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
	at com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHandler.java:314)
	at com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:169)
	at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
	at com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHandler.java:314)
	at com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:169)
	at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
	at com.sun.facelets.tag.jsf.ComponentHandler.applyNextHandler(ComponentHandler.java:314)
	at com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:169)
	at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
	at com.sun.facelets.tag.ui.DefineHandler.applyDefinition(DefineHandler.java:64)
	at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:131)
	at com.sun.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:337)
	at com.sun.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:307)
	at com.sun.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:68)
	at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
	at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
	at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47)
	at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
	at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:248)
	at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:294)
	at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:273)
	at com.sun.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:140)
	at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:113)
	at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
	at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25)
	at com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95)
	at com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:524)
	at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:567)
	at org.ajax4jsf.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:100)
	at org.ajax4jsf.application.AjaxViewHandler.renderView(AjaxViewHandler.java:176)
	at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:85)
	at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
	at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
	at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:388)
	at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Comment 3 Mark Thomas 2011-10-17 16:40:14 UTC
OK. Looks like the problem isn't the WeakReference but that the fields of a class which are cached using soft references. There is a chance that a GC run could clear the soft references which would then make the weak references eligible for GC too.

It looks like we'll need to revisit the annotation cache implementation.
Comment 4 Mark Thomas 2011-10-18 13:25:31 UTC
This error is actually most likely triggered by a simple threading bug.

However, there are differences between how the cache is intended to behave and how it is actually implemented. Reconciling these differences is not trivial. I'm currently working on a fix.
Comment 5 Mark Thomas 2011-10-19 09:32:43 UTC
Thanks for the report. I have fixed this and the additional errors I discovered while investigating this issue. The fix has been applied to trunk (8.0.x) and 7.0.x and will be included in 7.0.23 onwards.