[GLASSFISH-16070] NullPointerException in JstlBaseTLV.validate Created: 22/Feb/11  Updated: 16/Dec/11  Resolved: 12/Dec/11

Status: Resolved
Project: glassfish
Component/s: web_container
Affects Version/s: 3.1_b43
Fix Version/s: 3.1.2_b15

Type: Bug Priority: Major
Reporter: Scott Oaks Assignee: kchung
Resolution: Fixed Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: 3_1-next, 3_1_1-scrubbed, 3_1_2-review

 Description   

When we start multiple application requests against a server that has just started (and so has not initialized the apps yet), we sometimes get the exception at the end of this description.

When that occurs, the application never initializes correctly; all requests to the app throw that error. But if the first request to the application works, then we never get this error. Clearly there is some race condition here for some initialization that needs to be tracked down.

The 1.2 version of this code on Apache doesn't match the line numbers in the GF code. But I see that the 1.2 Apache code is not thread safe; I don't know how many validators there might be in this case, but that seems like a likely candidate.

Here is the full exception:

[#|2011-02-21T23:47:01.661-0800|SEVERE|glassfish3.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=206;_ThreadName=Thread-1;|java.lang.NullPointerException
at org.apache.taglibs.standard.tlv.JstlBaseTLV.validate(JstlBaseTLV.java:196)
at org.apache.taglibs.standard.tlv.JstlCoreTLV.validate(JstlCoreTLV.java:134)
at org.apache.jasper.compiler.TagLibraryInfoImpl.validate(TagLibraryInfoImpl.java:949)
at org.apache.jasper.compiler.Validator.validateXmlView(Validator.java:1921)
at org.apache.jasper.compiler.Validator.validate(Validator.java:1888)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:223)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451)
at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:625)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:787)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:649)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:483)
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:454)
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:350)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:300)
at com.sun.eng.jtpcw.command.ShoppingCartCommand.execute(ShoppingCartCommand.java:110)
at com.sun.eng.jtpcw.servlet.ControlServlet.processRequest(ControlServlet.java:89)
at com.sun.eng.jtpcw.servlet.ControlServlet.doGet(ControlServlet.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:735)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:662)

#]


 Comments   
Comment by m_jenkins [ 01/Apr/11 ]

This also affects Glassfish v2.1 - we just hit it for the first time in our Production environment:

[#|2011-04-01T16:46:40.420+0200|WARNING|sun-appserver2.1|javax.enterprise.system.stream.err|_ThreadID=29;_ThreadName=httpSSLWorkerThread-8080-1;_RequestID=4fe77695-5664-431a-9ce3-f18376f58473;|java.lang.NullPointerException
at org.apache.taglibs.standard.tlv.JstlBaseTLV.validate(JstlBaseTLV.java:196)
at org.apache.taglibs.standard.tlv.JstlFmtTLV.validate(JstlFmtTLV.java:134)
(rest very similar to the above)

Comment by patbos [ 03/Apr/11 ]

Have the same problem.
Workaround is to precompile applications when deploying.
asadmin deploy --precompile=true webapp.war

Comment by kchung [ 24/May/11 ]

The method org.apache.taglibs.standard.tlv.JstlBaseTLV.validate is synchronized, so I don't see how it is not thread safe. It is also possible that an argument passed to it is null.

Would appreciate a small war file and instructions to reproduce the problem.

Comment by kchung [ 02/Jun/11 ]

Deferred to 3.1-next, as the problem does not happen often.

Comment by sbailliez [ 13/Jul/11 ]

It is happening in our environment too in production.

It is actually not really synchronized correctly since the init method does not use synchronization when it resets the variables, so technically messageVector could well be reset in between initialization at line 170 and check for size() == 0 at line 196

Caused by: java.lang.NullPointerException
	at org.apache.taglibs.standard.tlv.JstlBaseTLV.validate(JstlBaseTLV.java:196)
	at org.apache.taglibs.standard.tlv.JstlFmtTLV.validate(JstlFmtTLV.java:134)
	at org.apache.jasper.compiler.TagLibraryInfoImpl.validate(TagLibraryInfoImpl.java:913)
	at org.apache.jasper.compiler.Validator.validateXmlView(Validator.java:1891)
	at org.apache.jasper.compiler.Validator.validate(Validator.java:1859)
	at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:210)
Comment by scatari [ 06/Dec/11 ]

Please re-evaluate this issue for 3.1.2.

Comment by kchung [ 06/Dec/11 ]

So synchronizing the init method should fix this issue?

Without a test case and instructions for reproducing it, I have no way of verifying the validity of the fix.

Comment by kchung [ 12/Dec/11 ]

I've made init a synchronized method. If the issue not fixed, please reopen it, with a test case.

Comment by dominic_mcginnis [ 16/Dec/11 ]

Synchronizing on the init() method will not resolve this as that still doesn't prevent a thread from manipulating the messageVector while it's in use by another thread. The issue is that one thread is setting the messageVector to null, via the init(), while another is trying to utilize it via validate(). To protect from this the object needs to be locked while it's being utilized. That means within the validate() function you'll want to add the synchro block as below:

synchronized(messageVector)

{ messageVector = new Vector(); ... if(messageVector.size() == 0) ... }
Generated at Fri Jul 31 10:09:41 UTC 2015 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.