Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 340767

Summary: Fail to generate concurrent reports containing CRLF and <BR>
Product: z_Archived Reporter: Nicolas Lecroart <nlecroar26>
Component: BIRTAssignee: Birt-ReportEngine-inbox <Birt-ReportEngine-inbox>
Status: VERIFIED FIXED QA Contact: Xiaoying Gu <bluesoldier>
Severity: normal    
Priority: P3 CC: bluesoldier, hustlg
Version: 2.6.2   
Target Milestone: 3.7.0 M7   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Simplified report demonstrating the problem none

Description Nicolas Lecroart CLA 2011-03-23 10:31:28 EDT
Created attachment 191753 [details]
Simplified report demonstrating the problem

Hello,

We use the BIRT 2.5.2 runtime in a J2EE web application (running in OC4J on Windows) to generate and serve reports.
One of our reports is failing when several users try to generate it in parallel.
Depending on the situation, it fails with NullPointerException or StringIndexOutOfBoundsException (see stacktraces below) but always in some part of the code which is related to text areas.
Our report is quite long and uses a custom data source so I created a simplified report that reproduces the problem (see attachment).
The simplified report can be executed in a JUnit test for example and it contains multiline text elements with content types html and plain. 
The plain text data contains CRLFs (\r\n) and the html data contains <BR> tags.
For the problem to occur, you must run multiple occurences of the report in parallel.
I tried upgrading to BIRT 2.6.2 but it fails in a similar way.

Failure 1:
##########

com.xyz.report.server.ReportException: Failed to run report
	at com.xyz.report.server.birt.BIRTEngine.doRunAndRender(BIRTEngine.java:333)
	at com.xyz.report.server.birt.BIRTEngine.runReport(BIRTEngine.java:214)
	at com.xyz.report.server.birt.BIRTEngine.runReport(BIRTEngine.java:180)
	at com.xyz.report.server.birt.async.AsyncReportBean$1.write(AsyncReportBean.java:239)
	at com.xyz.report.server.birt.async.repository.DAOReportRepository.writeReportFile(DAOReportRepository.java:144)
	at com.xyz.report.server.birt.async.AsyncReportBean.runReport(AsyncReportBean.java:242)
	at com.xyz.report.server.birt.async.AsyncReportBean.ejbTimeout(AsyncReportBean.java:146)
	at com.evermind.server.ejb.interceptor.joinpoint.EJBTimeoutJoinPoint.invoke(EJBTimeoutJoinPoint.java:20)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.interceptor.system.DMSInterceptor.invoke(DMSInterceptor.java:52)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.interceptor.system.SetContextActionInterceptor.invoke(SetContextActionInterceptor.java:44)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.interceptor.system.TxBeanManagedInterceptor.invoke(TxBeanManagedInterceptor.java:53)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.InvocationContextPool.invoke(InvocationContextPool.java:55)
	at com.evermind.server.ejb.StatelessSessionEJBObject.OC4J_invokeMethod(StatelessSessionEJBObject.java:87)
	at com.evermind.server.ejb.StatelessSessionEJBHome.invokeTimer(StatelessSessionEJBHome.java:38)
	at com.evermind.server.ejb.EJBContainer.invokeTimer(EJBContainer.java:1709)
	at oracle.ias.container.scheduler.TimerTask$TimerAppInfo.invokeTimer(TimerTask.java:275)
	at oracle.ias.container.scheduler.TimerTask.runBeanTimer(TimerTask.java:84)
	at oracle.ias.container.scheduler.TimerTask.run(TimerTask.java:207)
	at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
	at java.lang.Thread.run(Thread.java:619)
Caused by: org.eclipse.birt.report.engine.api.EngineException: Error happened while running the report.
	at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:196)
	at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
	at com.xyz.report.server.birt.BIRTEngine.doRunAndRender(BIRTEngine.java:326)
	... 23 more
Caused by: java.lang.NullPointerException
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextCompositor.getNextTextArea(TextCompositor.java:181)
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextCompositor.getNextArea(TextCompositor.java:126)
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextAreaLayout.layoutChildren(TextAreaLayout.java:182)
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextAreaLayout.layout(TextAreaLayout.java:173)
	at org.eclipse.birt.report.engine.nLayout.area.impl.BlockTextArea.layout(BlockTextArea.java:71)
	at org.eclipse.birt.report.engine.nLayout.LayoutEngine.startContent(LayoutEngine.java:488)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterAdapter.startText(ContentEmitterAdapter.java:147)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterAdapter.startData(ContentEmitterAdapter.java:163)
	at org.eclipse.birt.report.engine.emitter.CompositeContentEmitter.startData(CompositeContentEmitter.java:258)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterUtil.startContent(ContentEmitterUtil.java:71)
	at org.eclipse.birt.report.engine.emitter.BufferedReportEmitter.flush(BufferedReportEmitter.java:65)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLayoutEmitter.flushRow(HTMLTableLayoutEmitter.java:347)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLayoutEmitter.flush(HTMLTableLayoutEmitter.java:310)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLayoutEmitter.endRow(HTMLTableLayoutEmitter.java:632)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterUtil.endContent(ContentEmitterUtil.java:111)
	at org.eclipse.birt.report.engine.layout.html.buffer.AbstractNode.end(AbstractNode.java:69)
	at org.eclipse.birt.report.engine.layout.html.buffer.HTMLPageBuffer.endRow(HTMLPageBuffer.java:196)
	at org.eclipse.birt.report.engine.layout.html.buffer.HTMLPageBuffer.endContainer(HTMLPageBuffer.java:140)
	at org.eclipse.birt.report.engine.layout.html.buffer.TableBreakBuffer.endContainer(TableBreakBuffer.java:360)
	at org.eclipse.birt.report.engine.layout.html.HTMLStackingLM.end(HTMLStackingLM.java:42)
	at org.eclipse.birt.report.engine.layout.html.HTMLAbstractLM.layout(HTMLAbstractLM.java:141)
	at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:48)
	at org.eclipse.birt.report.engine.layout.html.HTMLStackingLM.layoutChildren(HTMLStackingLM.java:26)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLM.layoutChildren(HTMLTableLM.java:132)
	at org.eclipse.birt.report.engine.layout.html.HTMLAbstractLM.layout(HTMLAbstractLM.java:140)
	at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:48)
	at org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:90)
	at org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutEngine.layout(HTMLReportLayoutEngine.java:99)
	at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:180)
	... 25 more
	
Failure 2:
##########

com.xyz.report.server.ReportException: Failed to run report
	at com.xyz.report.server.birt.BIRTEngine.doRunAndRender(BIRTEngine.java:333)
	at com.xyz.report.server.birt.BIRTEngine.runReport(BIRTEngine.java:214)
	at com.xyz.report.server.birt.BIRTEngine.runReport(BIRTEngine.java:180)
	at com.xyz.report.server.birt.async.AsyncReportBean$1.write(AsyncReportBean.java:239)
	at com.xyz.report.server.birt.async.repository.DAOReportRepository.writeReportFile(DAOReportRepository.java:144)
	at com.xyz.report.server.birt.async.AsyncReportBean.runReport(AsyncReportBean.java:242)
	at com.xyz.report.server.birt.async.AsyncReportBean.ejbTimeout(AsyncReportBean.java:146)
	at com.evermind.server.ejb.interceptor.joinpoint.EJBTimeoutJoinPoint.invoke(EJBTimeoutJoinPoint.java:20)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.interceptor.system.DMSInterceptor.invoke(DMSInterceptor.java:52)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.interceptor.system.SetContextActionInterceptor.invoke(SetContextActionInterceptor.java:44)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.interceptor.system.TxBeanManagedInterceptor.invoke(TxBeanManagedInterceptor.java:53)
	at com.evermind.server.ejb.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:119)
	at com.evermind.server.ejb.InvocationContextPool.invoke(InvocationContextPool.java:55)
	at com.evermind.server.ejb.StatelessSessionEJBObject.OC4J_invokeMethod(StatelessSessionEJBObject.java:87)
	at com.evermind.server.ejb.StatelessSessionEJBHome.invokeTimer(StatelessSessionEJBHome.java:38)
	at com.evermind.server.ejb.EJBContainer.invokeTimer(EJBContainer.java:1709)
	at oracle.ias.container.scheduler.TimerTask$TimerAppInfo.invokeTimer(TimerTask.java:275)
	at oracle.ias.container.scheduler.TimerTask.runBeanTimer(TimerTask.java:84)
	at oracle.ias.container.scheduler.TimerTask.run(TimerTask.java:207)
	at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:303)
	at java.lang.Thread.run(Thread.java:619)
Caused by: org.eclipse.birt.report.engine.api.EngineException: Error happened while running the report.
	at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:196)
	at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.run(RunAndRenderTask.java:77)
	at com.xyz.report.server.birt.BIRTEngine.doRunAndRender(BIRTEngine.java:326)
	... 23 more
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 365
	at java.lang.String.substring(String.java:1934)
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextArea.calculateText(TextArea.java:133)
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextArea.getText(TextArea.java:196)
	at org.eclipse.birt.report.engine.emitter.pdf.PDFRender.drawTextAt(PDFRender.java:187)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.drawText(PageDeviceRender.java:904)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitText(PageDeviceRender.java:156)
	at org.eclipse.birt.report.engine.emitter.pdf.PDFRender.visitText(PDFRender.java:92)
	at org.eclipse.birt.report.engine.nLayout.area.impl.TextArea.accept(TextArea.java:234)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:184)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitChildren(PageDeviceRender.java:195)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.addPage(PageDeviceRender.java:540)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitPage(PageDeviceRender.java:505)
	at org.eclipse.birt.report.engine.layout.emitter.PageDeviceRender.visitContainer(PageDeviceRender.java:179)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.accept(ContainerArea.java:274)
	at org.eclipse.birt.report.engine.layout.emitter.PageEmitter.startPage(PageEmitter.java:51)
	at org.eclipse.birt.report.engine.nLayout.LayoutEngine.outputPage(LayoutEngine.java:823)
	at org.eclipse.birt.report.engine.nLayout.area.impl.PageArea.outputPage(PageArea.java:696)
	at org.eclipse.birt.report.engine.nLayout.area.impl.PageArea.close(PageArea.java:676)
	at org.eclipse.birt.report.engine.nLayout.area.impl.RootArea.autoPageBreak(RootArea.java:67)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.ContainerArea.autoPageBreak(ContainerArea.java:136)
	at org.eclipse.birt.report.engine.nLayout.area.impl.BlockTextArea.update(BlockTextArea.java:191)
	at org.eclipse.birt.report.engine.nLayout.area.impl.BlockContainerArea.close(BlockContainerArea.java:126)
	at org.eclipse.birt.report.engine.nLayout.area.impl.BlockTextArea.close(BlockTextArea.java:103)
	at org.eclipse.birt.report.engine.nLayout.area.impl.BlockTextArea.layout(BlockTextArea.java:74)
	at org.eclipse.birt.report.engine.nLayout.LayoutEngine.startContent(LayoutEngine.java:488)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterAdapter.startText(ContentEmitterAdapter.java:147)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterAdapter.startData(ContentEmitterAdapter.java:163)
	at org.eclipse.birt.report.engine.emitter.CompositeContentEmitter.startData(CompositeContentEmitter.java:258)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterUtil.startContent(ContentEmitterUtil.java:71)
	at org.eclipse.birt.report.engine.emitter.BufferedReportEmitter.flush(BufferedReportEmitter.java:65)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLayoutEmitter.flushRow(HTMLTableLayoutEmitter.java:347)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLayoutEmitter.flush(HTMLTableLayoutEmitter.java:310)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLayoutEmitter.endRow(HTMLTableLayoutEmitter.java:632)
	at org.eclipse.birt.report.engine.emitter.ContentEmitterUtil.endContent(ContentEmitterUtil.java:111)
	at org.eclipse.birt.report.engine.layout.html.buffer.AbstractNode.end(AbstractNode.java:69)
	at org.eclipse.birt.report.engine.layout.html.buffer.HTMLPageBuffer.endRow(HTMLPageBuffer.java:196)
	at org.eclipse.birt.report.engine.layout.html.buffer.HTMLPageBuffer.endContainer(HTMLPageBuffer.java:140)
	at org.eclipse.birt.report.engine.layout.html.buffer.TableBreakBuffer.endContainer(TableBreakBuffer.java:360)
	at org.eclipse.birt.report.engine.layout.html.HTMLStackingLM.end(HTMLStackingLM.java:42)
	at org.eclipse.birt.report.engine.layout.html.HTMLAbstractLM.layout(HTMLAbstractLM.java:141)
	at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:48)
	at org.eclipse.birt.report.engine.layout.html.HTMLStackingLM.layoutChildren(HTMLStackingLM.java:26)
	at org.eclipse.birt.report.engine.layout.html.HTMLTableLM.layoutChildren(HTMLTableLM.java:132)
	at org.eclipse.birt.report.engine.layout.html.HTMLAbstractLM.layout(HTMLAbstractLM.java:140)
	at org.eclipse.birt.report.engine.layout.html.HTMLBlockStackingLM.layoutNodes(HTMLBlockStackingLM.java:48)
	at org.eclipse.birt.report.engine.layout.html.HTMLPageLM.layout(HTMLPageLM.java:90)
	at org.eclipse.birt.report.engine.layout.html.HTMLReportLayoutEngine.layout(HTMLReportLayoutEngine.java:99)
	at org.eclipse.birt.report.engine.api.impl.RunAndRenderTask.doRun(RunAndRenderTask.java:180)
	... 25 more
	
Example code to quickly test concurrent reports in a JUnit test:

 public void testConcurrency() throws Exception {
       int threadCount = 4;
       List<Runnable> runnables = new ArrayList<Runnable>();
       for (int i = 0; i < threadCount; i++) {
           runnables.add(createRunnable(i));
       }
       runConcurrent(runnables);
    }

   private Runnable createRunnable(final int pIndex) {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    final String testName = "testConcurrency_" + pIndex;
                    runReport(testName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }

    private void runConcurrent(List<Runnable> pRunnables) {
        try {
            ExecutorService executor = Executors.newFixedThreadPool(pRunnables.size());
            for (Runnable runnable : pRunnables) {
                executor.execute(runnable);
            }
            executor.shutdown();
            executor.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
Comment 1 Gang Liu CLA 2011-04-14 03:46:21 EDT
fixed.
Comment 2 Xiaoying Gu CLA 2011-04-18 05:59:42 EDT
Verified in 3.7.0.v20110418