DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUGĀ· RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=36173>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED ANDĀ· INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=36173 Summary: AssertionFailure in java.util.GregorianCalendar.computeFields() when sending response Product: Tomcat 5 Version: 5.5.9 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: Connector:HTTP AssignedTo: tomcat-dev@jakarta.apache.org ReportedBy: [EMAIL PROTECTED] We have occasional failed requests on our servers running tomcat 5.0.19 (working under java 1.5.0 with system assertions enabled via -esa option). This also seams to be an issue with newer versions of tomcat up to the current snapshot taken from the CVS repository. The following exception gets thrown: java.lang.AssertionError: cache control: inconsictency, cachedFixedDate=732122, computed=732107, date=2005-06-10T00:00:00.000Z at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2050) at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:1971) at java.util.Calendar.setTimeInMillis(Calendar.java:1066) at java.util.Calendar.setTime(Calendar.java:1032) at java.text.SimpleDateFormat.format(SimpleDateFormat.java:785) at java.text.SimpleDateFormat.format(SimpleDateFormat.java:778) at java.text.DateFormat.format(DateFormat.java:314) at org.apache.tomcat.util.http.FastHttpDateFormat.getCurrentDate(FastHttpDateFormat.java:152) at org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:1529) at org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:926) at org.apache.coyote.Response.action(Response.java:224) at org.apache.coyote.http11.InternalOutputBuffer.doWrite(InternalOutputBuffer.java:605) at org.apache.coyote.Response.doWrite(Response.java:586) at org.apache.coyote.tomcat5.OutputBuffer.realWriteBytes(OutputBuffer.java:411) at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:436) at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:356) at org.apache.coyote.tomcat5.OutputBuffer.writeBytes(OutputBuffer.java:444) at org.apache.coyote.tomcat5.OutputBuffer.write(OutputBuffer.java:431) at org.apache.coyote.tomcat5.CoyoteOutputStream.write(CoyoteOutputStream.java:108) at org.apache.coyote.tomcat5.CoyoteOutputStream.write(CoyoteOutputStream.java:102) at com.scene7.is.ImageServlet.sendResponse(ImageServlet.java:197) at com.scene7.is.ImageServlet.doGet(ImageServlet.java:147) at javax.servlet.http.HttpServlet.service(HttpServlet.java:743) at javax.servlet.http.HttpServlet.service(HttpServlet.java:856) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:257) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:184) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:578) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972) at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:206) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:833) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:732) at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:619) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:688) at java.lang.Thread.run(Thread.java:595) Analysing stack traces and error messages suggests that the reason is internal data corruption in java.uti.GregorianCalendar class caused by accessing it simultaneously from multiple threads. The problem is that org.apache.tomcat.util.http.FastHttpDateFormat that is used for date conversion appears not to be entirely thread safe. This class uses shared instance of java.util.SimpleDateFormat: protected static final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); and there are two methods that use this instance: public static final String getCurrentDate() and public static final String formatDate (long value, DateFormat threadLocalformat) As SympleDateFormat class is documented to be not thread safe both methods synchronize access to it. However the synchronization is done against two different locks, so in case of overlapped calls of these two methods from different threads there is still possibility for data corruption. The exposure ot this is very narrow because getCurrentDate meghod actually uses format instance only ones per second at best, however the following test case is balse to reproduce this providing it is ran with JRE 1.5.0 with system assertions enabled (-esa switch) package org.apache.tomcat.util.http; import java.util.Date; import java.util.Random; public class FastHttpDateFormatTest { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread("getCurrentDate() invoker") { public void run() { while (true) { try { FastHttpDateFormat.getCurrentDate(); } catch (Throwable e) { reportError(e); } } } }; Thread t2 = new Thread("formatDate() invoker") { private Random random = new Random(); public void run() { while (true) { try { FastHttpDateFormat.formatDate(random.nextLong(), null); } catch (Throwable e) { reportError(e); } } } }; t1.start(); t2.start(); } private synchronized static void reportError(Throwable e) { System.out.println(new Date() + " [" + Thread.currentThread().getName() + "]: " + e.getMessage()); System.out.println(e.getMessage()); e.printStackTrace(); } } This problem seams to be easily fixable by putting additional synchronization around access to format instance in FastHttpDateFormat.formatDate(...) method. Here are the diffs: $ diff -u ~/lib/versions/jakarta-tomcat-5.0.19-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/FastHttpDateFormat.java org/apache/tomcat/util/http/FastHttpDateFormat.java --- /home/akrainiouk/lib/versions/jakarta-tomcat-5.0.19-src/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/http/FastHttpDateFormat.java 2004-02-14 02:27:02.000000000 -0800 +++ org/apache/tomcat/util/http/FastHttpDateFormat.java 2005-08-12 14:22:05.000000000 -0700 @@ -182,7 +182,9 @@ } } else { synchronized (formatCache) { - newDate = format.format(dateValue); + synchronized (format) { + newDate = format.format(dateValue); + } updateCache(formatCache, longValue, newDate); } } -- Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]