Problems with empty html inside Thymeleaf - 6.14

Enonic version: 6.14.0
OS: Linux

Hi guys!

It seems like since Enonic 6.14.0 templates cannot be empty.
For example, if we have a part template like this:

<section data-th-if="${expression}">
    test
</section>

And if an expression is set to false, the template is simply empty and the page crashes and returns an error:

String index out of range: 0 (java.lang.StringIndexOutOfBoundsException)

Is there some new rules how to handle this? Or is this a bug? Earlier(6.13.0) we did not face this error.

Thanks!

1 Like

Hi,

Are you using Page Contributions in this controller? We introduced a change here in 6.14 making it always return arrays, never strings.

Does it crash if you wrap that section with something that is always rendered?

We did all the required changes to make Page Contributions work properly, so it is not the issue with Page Contributions.

Yes, the error is fixed if I wrap it with anything that is always rendered, but is it correct behavior? :slight_smile: Empty blocks(wrappers) would appear in this case. I believe it wasn’t so earlier.

Can you copy the whole stacktrace of the error that appears in the log?

Sure.

ERROR c.e.x.p.i.e.ExceptionRendererImpl - String index out of range: 0
com.enonic.xp.web.WebException: String index out of range: 0
	at com.enonic.xp.web.impl.exception.ExceptionMapperImpl.map(ExceptionMapperImpl.java:32)
	at com.enonic.xp.portal.handler.BasePortalHandler.handleError(BasePortalHandler.java:62)
	at com.enonic.xp.portal.handler.BasePortalHandler.doHandle(BasePortalHandler.java:54)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:66)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.impl.trace.TraceWebFilter.doHandle(TraceWebFilter.java:37)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:66)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.impl.handler.WebDispatcherImpl.dispatch(WebDispatcherImpl.java:50)
	at com.enonic.xp.web.impl.handler.WebDispatcherServlet.doHandle(WebDispatcherServlet.java:135)
	at com.enonic.xp.web.impl.handler.WebDispatcherServlet.service(WebDispatcherServlet.java:63)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at com.enonic.xp.web.impl.dispatch.mapping.ServletDefinitionImpl.service(ServletDefinitionImpl.java:39)
	at com.enonic.xp.web.impl.dispatch.pipeline.ServletPipelineImpl.service(ServletPipelineImpl.java:30)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:45)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.portal.impl.auth.AuthFilter.doHandle(AuthFilter.java:45)
	at com.enonic.xp.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:31)
	at com.enonic.xp.web.filter.BaseWebFilter.doFilter(BaseWebFilter.java:33)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.impl.auth.BasicAuthFilter.doHandle(BasicAuthFilter.java:33)
	at com.enonic.xp.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:31)
	at com.enonic.xp.web.filter.BaseWebFilter.doFilter(BaseWebFilter.java:33)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.impl.context.ContextFilter.lambda$doHandle$0(ContextFilter.java:33)
	at com.enonic.xp.context.ContextImpl.callWith(ContextImpl.java:101)
	at com.enonic.xp.web.impl.context.ContextFilter.doHandle(ContextFilter.java:32)
	at com.enonic.xp.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:31)
	at com.enonic.xp.web.filter.BaseWebFilter.doFilter(BaseWebFilter.java:33)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:26)
	at com.enonic.xp.web.filter.BaseWebFilter.doFilter(BaseWebFilter.java:33)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.impl.dos.DosFilterWrapper.doFilter(DosFilterWrapper.java:64)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterPipelineImpl.filter(FilterPipelineImpl.java:29)
	at com.enonic.xp.web.impl.dispatch.DispatchServletImpl.service(DispatchServletImpl.java:35)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:821)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:365)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1158)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1090)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:199)
	at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:74)
	at com.enonic.xp.web.vhost.impl.VirtualHostFilter.doHandle(VirtualHostFilter.java:50)
	at com.enonic.xp.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:31)
	at com.enonic.xp.web.filter.BaseWebFilter.doFilter(BaseWebFilter.java:33)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.impl.dos.DosFilterWrapper.doFilter(DosFilterWrapper.java:64)
	at com.enonic.xp.web.impl.dispatch.mapping.FilterDefinitionImpl.doFilter(FilterDefinitionImpl.java:40)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterChainImpl.doFilter(FilterChainImpl.java:36)
	at com.enonic.xp.web.impl.dispatch.pipeline.FilterPipelineImpl.filter(FilterPipelineImpl.java:29)
	at com.enonic.xp.web.impl.dispatch.DispatchServletImpl.service(DispatchServletImpl.java:35)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:821)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:437)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1158)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1090)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119)
	at com.codahale.metrics.jetty9.InstrumentedHandler.handle(InstrumentedHandler.java:240)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119)
	at org.eclipse.jetty.server.Server.handle(Server.java:517)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:306)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:261)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
	at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75)
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213)
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 0
	at java.lang.String.charAt(String.java:658)
	at com.enonic.xp.portal.impl.rendering.LiveEditAttributeInjection.skipByteOrderMark(LiveEditAttributeInjection.java:67)
	at com.enonic.xp.portal.impl.rendering.LiveEditAttributeInjection.injectLiveEditAttribute(LiveEditAttributeInjection.java:24)
	at com.enonic.xp.portal.impl.rendering.DescriptorBasedComponentRenderer.doRender(DescriptorBasedComponentRenderer.java:95)
	at com.enonic.xp.portal.impl.rendering.DescriptorBasedComponentRenderer.render(DescriptorBasedComponentRenderer.java:43)
	at com.enonic.xp.portal.impl.rendering.DescriptorBasedComponentRenderer.render(DescriptorBasedComponentRenderer.java:22)
	at com.enonic.xp.portal.impl.postprocess.instruction.ComponentInstruction.renderComponent(ComponentInstruction.java:116)
	at com.enonic.xp.portal.impl.postprocess.instruction.ComponentInstruction.renderComponent(ComponentInstruction.java:102)
	at com.enonic.xp.portal.impl.postprocess.instruction.ComponentInstruction.evaluate(ComponentInstruction.java:72)
	at com.enonic.xp.portal.impl.postprocess.PostProcessEvaluator.executeInstruction(PostProcessEvaluator.java:105)
	at com.enonic.xp.portal.impl.postprocess.PostProcessEvaluator.processInstructions(PostProcessEvaluator.java:86)
	at com.enonic.xp.portal.impl.postprocess.PostProcessEvaluator.evaluateInstructions(PostProcessEvaluator.java:59)
	at com.enonic.xp.portal.impl.postprocess.PostProcessorImpl.processResponseInstructions(PostProcessorImpl.java:69)
	at com.enonic.xp.portal.impl.rendering.PostProcessingRenderer.render(PostProcessingRenderer.java:26)
	at com.enonic.xp.portal.impl.handler.render.PageHandlerWorker.execute(PageHandlerWorker.java:128)
	at com.enonic.xp.portal.impl.handler.render.PageHandler.doHandle(PageHandler.java:62)
	at com.enonic.xp.portal.impl.handler.render.PageHandler.doHandle(PageHandler.java:22)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:66)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.web.handler.BaseWebHandler.handle(BaseWebHandler.java:75)
	at com.enonic.xp.web.impl.handler.WebHandlerChainImpl.handle(WebHandlerChainImpl.java:30)
	at com.enonic.xp.portal.handler.BasePortalHandler.doHandle(BasePortalHandler.java:48)
	... 96 common frames omitted

This is caused by a bug introduced in 6.14, unfortunately.
If the HTML output from a part (or layout) is empy, it will fail during page rendering.

We will fix this isue in 6.14.1, which hopefully will be released at the end of next week.

As a workaround for now you can try with making it an empty tag (section, div, etc) instead of empty string.

Something like this:

<section data-th-if="${expression}">
    test
</section>
<div data-th-if="${!expression}"></div>
2 Likes

OK. Thanks for the information. :slight_smile: