Stripes

Layout issues after upgrade from 1.5.3

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: Release 1.5.4, Release 1.5.5
  • Fix Version/s: Release 1.5.7
  • Component/s: Tag Library
  • Labels:
    None
  • Environment:
    jetty-6.1.15, Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)

Description

Guys, I have a couple of layout scenarios which stopped working after upgrading to 1.5.4. I have created a couple of test cases demonstrating these issues. I am attaching maven2 project.

1. mvn jetty:run
2. http://localhost:8080/stripes-bug
3. take a look at the output of each test under 1.5.4
4. change the stripes dependency to 1.5.3
5. mvn clean jetty:run
6. observe the difference in the output

  1. example.tar.gz
    29/Dec/10 6:08 PM
    0.9 kB
    Nick Stuart

Activity

Hide
Ben Gunter added a comment - 04/Dec/10 11:31 PM

I have fixed the bug illustrated by the first test in your example app. You can test against the latest snapshot to ensure it works. The second test illustrates a separate bug that will be more difficult to fix.

Show
Ben Gunter added a comment - 04/Dec/10 11:31 PM I have fixed the bug illustrated by the first test in your example app. You can test against the latest snapshot to ensure it works. The second test illustrates a separate bug that will be more difficult to fix.
Hide
David Dundua added a comment - 05/Dec/10 2:01 AM

Ben, thank you for getting to it so quickly. I have just verified that the first test case works against the latest 1.5.5-SNAPSHOT.

Show
David Dundua added a comment - 05/Dec/10 2:01 AM Ben, thank you for getting to it so quickly. I have just verified that the first test case works against the latest 1.5.5-SNAPSHOT.
Hide
Nick Stuart added a comment - 27/Dec/10 12:18 PM

Ben, this is in reply to your comment on STS-791. I'm looking at the latest SVN code for 1.5.5, r1369

It appears this second scenario is loosing the context or the context is not correct when rendering the nested component. Debugging through, everything looks fine running through LayoutComponentRenderer, it goes in and renders the regular components fine, and when it gets to the nested component it enters the loop just fine at line 119 and acts like the other ones Howver, something goes wrong when it goes to include the pageContext at 133: pageContext.include(context.getRenderPage(), false)...

When the other two are rendering I hit the if (isCurrentComponent()) line 107 twice, showing each component in the context and it evals the body when the current component is set correctly. When the nested component goes to get rendered though the current component is never set to it . Instead I just the two 'regular' components from the first layout, and thats it. It's like the second-render tags body is never being evaluated correctly from the page. If the secondary layout has default content in the component, that will in fact get displayed. But if that content is in the regular page, it never gets evaluated

It's all fairly confusing, and guessing it's that way to get the components to render when available and flushing when they can, but it does have the unfortunate side affect of being hard to follow....

Show
Nick Stuart added a comment - 27/Dec/10 12:18 PM Ben, this is in reply to your comment on STS-791. I'm looking at the latest SVN code for 1.5.5, r1369 It appears this second scenario is loosing the context or the context is not correct when rendering the nested component. Debugging through, everything looks fine running through LayoutComponentRenderer, it goes in and renders the regular components fine, and when it gets to the nested component it enters the loop just fine at line 119 and acts like the other ones Howver, something goes wrong when it goes to include the pageContext at 133: pageContext.include(context.getRenderPage(), false)... When the other two are rendering I hit the if (isCurrentComponent()) line 107 twice, showing each component in the context and it evals the body when the current component is set correctly. When the nested component goes to get rendered though the current component is never set to it . Instead I just the two 'regular' components from the first layout, and thats it. It's like the second-render tags body is never being evaluated correctly from the page. If the secondary layout has default content in the component, that will in fact get displayed. But if that content is in the regular page, it never gets evaluated It's all fairly confusing, and guessing it's that way to get the components to render when available and flushing when they can, but it does have the unfortunate side affect of being hard to follow....
Hide
Ben Gunter added a comment - 27/Dec/10 1:05 PM

Believe me, I know how confusing it can get. I've had my mind twisted in knots while working on it.

The basic idea behind how these things work is this. The layout rendering process can only be initiated by executing a render tag. That render tag creates a layout context and silently executes its body one time so that the component tags within it can register themselves with the current context. That is the component registration phase. Then the render tag then executes the definition tag via include. The definition tag executes it body, writing out the body content. When a component tag is encountered within the definition, the component locates a like-named component in the current context, sets the context current component to its name and then executes the page containing the render tag inside of which the located component was registered. This is the component render phase. When the render tag executes during component render phase, components with names not matching the context current component do not execute (no-op) while those that do match write their body content out. Back in the definition tag, if no component is found with the correct name or the component tag that does execute produces no output, then the contents of that component tag (the one within the definition tag) are written out instead. Then the definition tag continues executing.

What is described above is the simplest case, where you have a render that executes a definition that executes a component. However, over the years people have really stretched the capabilities of the layout tags so that they have components within components and renders within components and renders within definitions. It is those kinds of cases that really complicate matters.

In the second example attached to this issue, what we have is a render within a component. The crux of the problem is that during the component render phase, the outer render executes and looks for a component with a name matching a component tag that is not a direct child of the outer render but a child of a render within a component within the outer render. Since none of the components within the outer render match the current component name, they do not execute and thus the render within the child component does not execute so the named component tag within that render does not execute either.

I plan to fix this by tracking not just the render page path and component name but a path to the component tag that includes the render page path and the names of all the components that need to execute to get to the actual component we're trying to execute.

Show
Ben Gunter added a comment - 27/Dec/10 1:05 PM Believe me, I know how confusing it can get. I've had my mind twisted in knots while working on it. The basic idea behind how these things work is this. The layout rendering process can only be initiated by executing a render tag. That render tag creates a layout context and silently executes its body one time so that the component tags within it can register themselves with the current context. That is the component registration phase. Then the render tag then executes the definition tag via include. The definition tag executes it body, writing out the body content. When a component tag is encountered within the definition, the component locates a like-named component in the current context, sets the context current component to its name and then executes the page containing the render tag inside of which the located component was registered. This is the component render phase. When the render tag executes during component render phase, components with names not matching the context current component do not execute (no-op) while those that do match write their body content out. Back in the definition tag, if no component is found with the correct name or the component tag that does execute produces no output, then the contents of that component tag (the one within the definition tag) are written out instead. Then the definition tag continues executing. What is described above is the simplest case, where you have a render that executes a definition that executes a component. However, over the years people have really stretched the capabilities of the layout tags so that they have components within components and renders within components and renders within definitions. It is those kinds of cases that really complicate matters. In the second example attached to this issue, what we have is a render within a component. The crux of the problem is that during the component render phase, the outer render executes and looks for a component with a name matching a component tag that is not a direct child of the outer render but a child of a render within a component within the outer render. Since none of the components within the outer render match the current component name, they do not execute and thus the render within the child component does not execute so the named component tag within that render does not execute either. I plan to fix this by tracking not just the render page path and component name but a path to the component tag that includes the render page path and the names of all the components that need to execute to get to the actual component we're trying to execute.
Hide
Nick Stuart added a comment - 27/Dec/10 3:08 PM

Thanks for the explanation Ben! I think I figured out the lifecycle for the basic case you mentioned above when walking through the code, it's the second part, figuring what's causing the issue to begin with, that I get a bit lost!

And the light bulb just clicked as to what's happening. In this scenario wouldn't there be a possibility of the component containing the inner render tag to be called multiple times, depending on how many components are rendered in the child layouts? The wrapper component would need to be executed first so I can see order being of importance here and also see the problem with delayed execution approach and trying to keep track of everything!

Ugh, never give software to users, first thing we do is break it!

Show
Nick Stuart added a comment - 27/Dec/10 3:08 PM Thanks for the explanation Ben! I think I figured out the lifecycle for the basic case you mentioned above when walking through the code, it's the second part, figuring what's causing the issue to begin with, that I get a bit lost! And the light bulb just clicked as to what's happening. In this scenario wouldn't there be a possibility of the component containing the inner render tag to be called multiple times, depending on how many components are rendered in the child layouts? The wrapper component would need to be executed first so I can see order being of importance here and also see the problem with delayed execution approach and trying to keep track of everything! Ugh, never give software to users, first thing we do is break it!
Hide
Ben Gunter added a comment - 28/Dec/10 10:29 AM

Yes, some components will execute multiple times. That problem is already solved, though. All these tags use a Writer that is capable of writing to output, discarding characters written or buffering them. I'll just have to switch the Writer's silent mode off and on at the right time so that only the current component's output actually goes to the client.

Show
Ben Gunter added a comment - 28/Dec/10 10:29 AM Yes, some components will execute multiple times. That problem is already solved, though. All these tags use a Writer that is capable of writing to output, discarding characters written or buffering them. I'll just have to switch the Writer's silent mode off and on at the right time so that only the current component's output actually goes to the client.
Hide
Ben Gunter added a comment - 28/Dec/10 5:28 PM

I believe this is fixed now. As stated in an earlier comment, the code tracks the list of components that must execute for a specific component to execute. Please test and let me know how it goes.

Show
Ben Gunter added a comment - 28/Dec/10 5:28 PM I believe this is fixed now. As stated in an earlier comment, the code tracks the list of components that must execute for a specific component to execute. Please test and let me know how it goes.
Hide
Nick Stuart added a comment - 29/Dec/10 6:08 PM

Hey Ben, just gave it a shot and almost, but not quite!

It does better in rendering some of the content, but it fails when using <jsp:include> tags. I've attached a simple example where the inner layout doesn't render. The include does but that's it. Not sure what to do here. The odd thing is that when it encounters a <layout-render> in the included file it just stops render that page. Everything before is rendered fine, but when it hits that everything is blank.

The <%@ include %> directive works, but acts a lot different then <jsp:include> and would require a lot of rework here to make that work as we need it to.

Show
Nick Stuart added a comment - 29/Dec/10 6:08 PM Hey Ben, just gave it a shot and almost, but not quite! It does better in rendering some of the content, but it fails when using <jsp:include> tags. I've attached a simple example where the inner layout doesn't render. The include does but that's it. Not sure what to do here. The odd thing is that when it encounters a <layout-render> in the included file it just stops render that page. Everything before is rendered fine, but when it hits that everything is blank. The <%@ include %> directive works, but acts a lot different then <jsp:include> and would require a lot of rework here to make that work as we need it to.
Hide
Nick Stuart added a comment - 29/Dec/10 6:08 PM

Example of <jsp:include> not rendering correctly.

Show
Nick Stuart added a comment - 29/Dec/10 6:08 PM Example of <jsp:include> not rendering correctly.
Hide
David Dundua added a comment - 02/Jan/11 1:10 AM

Added a third test demonstrating a new issue.

Show
David Dundua added a comment - 02/Jan/11 1:10 AM Added a third test demonstrating a new issue.
Hide
David Dundua added a comment - 02/Jan/11 1:10 AM

Ben, both test cases 1 and 2 now work as expected. However, there is another problem now. I have created Test 3 that demonstrates the issue.

Thank you,
David

Show
David Dundua added a comment - 02/Jan/11 1:10 AM Ben, both test cases 1 and 2 now work as expected. However, there is another problem now. I have created Test 3 that demonstrates the issue. Thank you, David
Hide
Ben Gunter added a comment - 02/Jan/11 4:44 PM

David, a fix for your third test case was committed in r1380.

Show
Ben Gunter added a comment - 02/Jan/11 4:44 PM David, a fix for your third test case was committed in r1380.
Hide
Ben Gunter added a comment - 03/Jan/11 1:42 PM

Nick, a fix for your jsp:include problem was committed in r1382.

There were a lot of oddities in the example you attached to this issue that layouts were not intended to support. Mainly, the stripes:layout-definition and stripes:layout-render tags were intended to be the outermost output-producing tag in the file. The files in your example have a lot of HTML scattered all over the place outside of those tags that will mostly get discarded by the layout tags. The way they work now is the way I intend for them to work. Hopefully that works for you.

Show
Ben Gunter added a comment - 03/Jan/11 1:42 PM Nick, a fix for your jsp:include problem was committed in r1382. There were a lot of oddities in the example you attached to this issue that layouts were not intended to support. Mainly, the stripes:layout-definition and stripes:layout-render tags were intended to be the outermost output-producing tag in the file. The files in your example have a lot of HTML scattered all over the place outside of those tags that will mostly get discarded by the layout tags. The way they work now is the way I intend for them to work. Hopefully that works for you.
Hide
David Dundua added a comment - 03/Jan/11 10:57 PM

Ben, Thank you very much. I built the latest from trunk and test case 3 is working now.

Show
David Dundua added a comment - 03/Jan/11 10:57 PM Ben, Thank you very much. I built the latest from trunk and test case 3 is working now.
Hide
Sébastien Lesaint added a comment - 05/Jan/11 7:20 AM

Hi !

I think there is still an issue with layout when using c:import in the chain of inclusion.
I check with rev 1387 of the trunk, hoping the fix for jsp:include would make a difference, but it didn't.

I attached a sample webapp (thanks to David Dundua, I just modifed his sample webapp) illustrating the issue.

Maybe we are not using layout-render exactly the way it was designed, but this pattern worked fine with 1.5.4 and it pretty usefull to us.

Thanks in advance for any feedback on this issue.

Show
Sébastien Lesaint added a comment - 05/Jan/11 7:20 AM Hi ! I think there is still an issue with layout when using c:import in the chain of inclusion. I check with rev 1387 of the trunk, hoping the fix for jsp:include would make a difference, but it didn't. I attached a sample webapp (thanks to David Dundua, I just modifed his sample webapp) illustrating the issue. Maybe we are not using layout-render exactly the way it was designed, but this pattern worked fine with 1.5.4 and it pretty usefull to us. Thanks in advance for any feedback on this issue.
Hide
Sébastien Lesaint added a comment - 05/Jan/11 7:21 AM

obviously, I meant "it worked fine with 1.5.3"

Show
Sébastien Lesaint added a comment - 05/Jan/11 7:21 AM obviously, I meant "it worked fine with 1.5.3"
Hide
Nick Stuart added a comment - 05/Jan/11 11:12 AM

Ben, yes we do use the layout tags as the outermost tags in our real world usuage. I was just adapting some test cases so I know that all the html out side of those tags are discarded (no worries there!)

I'll give it a test. My main issue was the stuff happening inside the tags, not the other html mess outside of them

Show
Nick Stuart added a comment - 05/Jan/11 11:12 AM Ben, yes we do use the layout tags as the outermost tags in our real world usuage. I was just adapting some test cases so I know that all the html out side of those tags are discarded (no worries there!) I'll give it a test. My main issue was the stuff happening inside the tags, not the other html mess outside of them
Hide
Ben Gunter added a comment - 05/Jan/11 11:17 AM

Nick, glad to hear that.

Sebastien, I'm investigating your issues. Please note, though, what I wrote in an earlier comment about the layout-render and layout-definition tags wanting to be the outermost output-producing tags in a page.

Show
Ben Gunter added a comment - 05/Jan/11 11:17 AM Nick, glad to hear that. Sebastien, I'm investigating your issues. Please note, though, what I wrote in an earlier comment about the layout-render and layout-definition tags wanting to be the outermost output-producing tags in a page.
Hide
Ben Gunter added a comment - 06/Jan/11 10:01 AM

Reopening for work on the issue reported by Sébastien.

Show
Ben Gunter added a comment - 06/Jan/11 10:01 AM Reopening for work on the issue reported by Sébastien.
Hide
Keith added a comment - 06/Jan/11 10:51 AM

I am still seeing this issue with 1.5.5. (Same example was working with 1.5.3). We are also using the Stripes Security Filter (not sure if that makes any difference).

For now we will continue to use 1.5.3... If I have time I will try to extract a sample web app with our layout so you can re-create the problem.

Show
Keith added a comment - 06/Jan/11 10:51 AM I am still seeing this issue with 1.5.5. (Same example was working with 1.5.3). We are also using the Stripes Security Filter (not sure if that makes any difference). For now we will continue to use 1.5.3... If I have time I will try to extract a sample web app with our layout so you can re-create the problem.
Hide
Ben Gunter added a comment - 06/Jan/11 10:54 AM

You're still seeing what issue, specifically? I'm about to commit some changes that fix a lot of little problems. Once the 1.5.6-SNAPSHOT is deployed, try that out and let me know how it goes.

Show
Ben Gunter added a comment - 06/Jan/11 10:54 AM You're still seeing what issue, specifically? I'm about to commit some changes that fix a lot of little problems. Once the 1.5.6-SNAPSHOT is deployed, try that out and let me know how it goes.
Hide
Ben Gunter added a comment - 06/Jan/11 12:33 PM

The changes have been committed and the snapshot deployed. I fixed the bug that was causing c:import and jsp:include to fail in this case. I also looked at the documentation for stripes:layout-render and found that it does not, in fact, specify that the render tag must be the outermost tag in the page. So I dug a little further and was able make some changes to allow stripes:layout-render anywhere in the page. That required LayoutRenderTag to implement BodyTag, which it did not before, so you need to force your JSPs to recompile for that update to take effect.

Please try it out. I look forward to your feedback.

Show
Ben Gunter added a comment - 06/Jan/11 12:33 PM The changes have been committed and the snapshot deployed. I fixed the bug that was causing c:import and jsp:include to fail in this case. I also looked at the documentation for stripes:layout-render and found that it does not, in fact, specify that the render tag must be the outermost tag in the page. So I dug a little further and was able make some changes to allow stripes:layout-render anywhere in the page. That required LayoutRenderTag to implement BodyTag, which it did not before, so you need to force your JSPs to recompile for that update to take effect. Please try it out. I look forward to your feedback.
Hide
Keith added a comment - 07/Jan/11 4:23 AM

Hi,

The problem I am seeing is the java.lang.NoSuchMethodError: net.sourceforge.stripes.tag.layout.LayoutComponentTag.doAfterBody()I

I am still seeing it with the 1.5.6-SNAPSHOT however some of the page does render now, so it is an improvement on the 1.5.5.

Below is the stacktrace when running 1.5.6-SNAPSHOT

2011-01-07 10:19:30,434 [ERROR] net.sourceforge.stripes.tag.layout.LayoutCompone
ntTag:[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuni
ng)':- Unhandled exception trying to render component "maincontent" to a string
in context /jsp/index.jsp -> /jsp/layout/Layout.jsp
javax.servlet.ServletException: java.lang.NoSuchMethodError: net.sourceforge.str
ipes.tag.layout.LayoutComponentTag.doAfterBody()I
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:341)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:183)
at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(Request
DispatcherImpl.java:526)
at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispat
cherImpl.java:447)
at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:163
)
at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:184
)
at net.sourceforge.stripes.tag.layout.LayoutContext.doInclude(LayoutCont
ext.java:184)
at net.sourceforge.stripes.tag.layout.LayoutComponentRenderer.write(Layo
utComponentRenderer.java:133)
at net.sourceforge.stripes.tag.layout.LayoutComponentTag.doStartTag(Layo
utComponentTag.java:202)
at jsp_servlet.jsp._layout.layout._jsptag8(_layout.java:526)
at jsp_servlet.jsp._layout.layout._jspService(_layout.java:271)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run
(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri
tyHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:300)
at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(Servlet
StubImpl.java:416)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:326)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:183)
at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(Request
DispatcherImpl.java:526)
at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispat
cherImpl.java:447)
at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:163
)
at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:184
)
at net.sourceforge.stripes.tag.layout.LayoutContext.doInclude(LayoutCont
ext.java:184)
at net.sourceforge.stripes.tag.layout.LayoutRenderTag.doEndTag(LayoutRen
derTag.java:162)
at jsp_servlet.jsp.index._jsptag1(_index.java:196)
at jsp_servlet.jsp.index._jspService(_index.java:109)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run
(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri
tyHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:300)
at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(Servlet
StubImpl.java:416)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:326)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:183)
at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(Request
DispatcherImpl.java:526)
at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispat
cherImpl.java:253)
at net.sourceforge.stripes.action.ForwardResolution.execute(ForwardResol
ution.java:110)
at net.sourceforge.stripes.controller.DispatcherHelper$7.intercept(Dispa
tcherHelper.java:508)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution
Context.java:158)
at org.stripesstuff.plugin.security.SecurityInterceptor.interceptResolut
ionExecution(SecurityInterceptor.java:225)
at org.stripesstuff.plugin.security.SecurityInterceptor.intercept(Securi
tyInterceptor.java:129)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution
Context.java:155)
at net.sourceforge.stripes.controller.HttpCacheInterceptor.intercept(Htt
pCacheInterceptor.java:99)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution
Context.java:155)
at net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.inter
cept(BeforeAfterMethodInterceptor.java:113)
at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution
Context.java:155)
at net.sourceforge.stripes.controller.ExecutionContext.wrap(ExecutionCon
text.java:74)
at net.sourceforge.stripes.controller.DispatcherHelper.executeResolution
(DispatcherHelper.java:502)
at net.sourceforge.stripes.controller.DispatcherServlet.executeResolutio
n(DispatcherServlet.java:286)
at net.sourceforge.stripes.controller.DispatcherServlet.service(Dispatch
erServlet.java:170)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run
(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri
tyHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:300)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
va:56)
at net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilt
er.java:247)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
va:56)
at ie.bge.middleware.util.audit.AuditFilter.doFilter(AuditFilter.java:54
)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
va:56)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio
n.doIt(WebAppServletContext.java:3684)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio
n.run(WebAppServletContext.java:3650)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(Authenticate
dSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:
121)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppS
ervletContext.java:2268)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletC
ontext.java:2174)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.j
ava:1446)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
Caused by: java.lang.NoSuchMethodError: net.sourceforge.stripes.tag.layout.Layou
tComponentTag.doAfterBody()I
at jsp_servlet.jsp.index._jsptag2(_index.java:235)
at jsp_servlet.jsp.index._jsptag1(_index.java:185)
at jsp_servlet.jsp.index._jspService(_index.java:109)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run
(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri
tyHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
a:300)
... 67 more

Show
Keith added a comment - 07/Jan/11 4:23 AM Hi, The problem I am seeing is the java.lang.NoSuchMethodError: net.sourceforge.stripes.tag.layout.LayoutComponentTag.doAfterBody()I I am still seeing it with the 1.5.6-SNAPSHOT however some of the page does render now, so it is an improvement on the 1.5.5. Below is the stacktrace when running 1.5.6-SNAPSHOT 2011-01-07 10:19:30,434 [ERROR] net.sourceforge.stripes.tag.layout.LayoutCompone ntTag:[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuni ng)':- Unhandled exception trying to render component "maincontent" to a string in context /jsp/index.jsp -> /jsp/layout/Layout.jsp javax.servlet.ServletException: java.lang.NoSuchMethodError: net.sourceforge.str ipes.tag.layout.LayoutComponentTag.doAfterBody()I at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:341) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:183) at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(Request DispatcherImpl.java:526) at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispat cherImpl.java:447) at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:163 ) at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:184 ) at net.sourceforge.stripes.tag.layout.LayoutContext.doInclude(LayoutCont ext.java:184) at net.sourceforge.stripes.tag.layout.LayoutComponentRenderer.write(Layo utComponentRenderer.java:133) at net.sourceforge.stripes.tag.layout.LayoutComponentTag.doStartTag(Layo utComponentTag.java:202) at jsp_servlet.jsp._layout.layout._jsptag8(_layout.java:526) at jsp_servlet.jsp._layout.layout._jspService(_layout.java:271) at weblogic.servlet.jsp.JspBase.service(JspBase.java:34) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run (StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri tyHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:300) at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(Servlet StubImpl.java:416) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:326) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:183) at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(Request DispatcherImpl.java:526) at weblogic.servlet.internal.RequestDispatcherImpl.include(RequestDispat cherImpl.java:447) at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:163 ) at weblogic.servlet.jsp.PageContextImpl.include(PageContextImpl.java:184 ) at net.sourceforge.stripes.tag.layout.LayoutContext.doInclude(LayoutCont ext.java:184) at net.sourceforge.stripes.tag.layout.LayoutRenderTag.doEndTag(LayoutRen derTag.java:162) at jsp_servlet.jsp.index._jsptag1(_index.java:196) at jsp_servlet.jsp.index._jspService(_index.java:109) at weblogic.servlet.jsp.JspBase.service(JspBase.java:34) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run (StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri tyHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:300) at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(Servlet StubImpl.java:416) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:326) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:183) at weblogic.servlet.internal.RequestDispatcherImpl.invokeServlet(Request DispatcherImpl.java:526) at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispat cherImpl.java:253) at net.sourceforge.stripes.action.ForwardResolution.execute(ForwardResol ution.java:110) at net.sourceforge.stripes.controller.DispatcherHelper$7.intercept(Dispa tcherHelper.java:508) at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution Context.java:158) at org.stripesstuff.plugin.security.SecurityInterceptor.interceptResolut ionExecution(SecurityInterceptor.java:225) at org.stripesstuff.plugin.security.SecurityInterceptor.intercept(Securi tyInterceptor.java:129) at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution Context.java:155) at net.sourceforge.stripes.controller.HttpCacheInterceptor.intercept(Htt pCacheInterceptor.java:99) at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution Context.java:155) at net.sourceforge.stripes.controller.BeforeAfterMethodInterceptor.inter cept(BeforeAfterMethodInterceptor.java:113) at net.sourceforge.stripes.controller.ExecutionContext.proceed(Execution Context.java:155) at net.sourceforge.stripes.controller.ExecutionContext.wrap(ExecutionCon text.java:74) at net.sourceforge.stripes.controller.DispatcherHelper.executeResolution (DispatcherHelper.java:502) at net.sourceforge.stripes.controller.DispatcherServlet.executeResolutio n(DispatcherServlet.java:286) at net.sourceforge.stripes.controller.DispatcherServlet.service(Dispatch erServlet.java:170) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run (StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri tyHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:300) at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja va:56) at net.sourceforge.stripes.controller.StripesFilter.doFilter(StripesFilt er.java:247) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja va:56) at ie.bge.middleware.util.audit.AuditFilter.doFilter(AuditFilter.java:54 ) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja va:56) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio n.doIt(WebAppServletContext.java:3684) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio n.run(WebAppServletContext.java:3650) at weblogic.security.acl.internal.AuthenticatedSubject.doAs(Authenticate dSubject.java:321) at weblogic.security.service.SecurityManager.runAs(SecurityManager.java: 121) at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppS ervletContext.java:2268) at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletC ontext.java:2174) at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.j ava:1446) at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201) at weblogic.work.ExecuteThread.run(ExecuteThread.java:173) Caused by: java.lang.NoSuchMethodError: net.sourceforge.stripes.tag.layout.Layou tComponentTag.doAfterBody()I at jsp_servlet.jsp.index._jsptag2(_index.java:235) at jsp_servlet.jsp.index._jsptag1(_index.java:185) at jsp_servlet.jsp.index._jspService(_index.java:109) at weblogic.servlet.jsp.JspBase.service(JspBase.java:34) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run (StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri tyHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav a:300) ... 67 more
Hide
Ben Gunter added a comment - 07/Jan/11 7:14 AM

Keith, you need to force your JSPs to recompile. They're trying to call methods from BodyTag when LayoutComponentTag no longer implements BodyTag.

Show
Ben Gunter added a comment - 07/Jan/11 7:14 AM Keith, you need to force your JSPs to recompile. They're trying to call methods from BodyTag when LayoutComponentTag no longer implements BodyTag.
Hide
Sébastien Lesaint added a comment - 07/Jan/11 7:33 AM

Hi Ben,
I checked the testcase and our application against rev 1390 of branch 1.5.x and they both seems to work fine.
Thanks a lot for the fix

Show
Sébastien Lesaint added a comment - 07/Jan/11 7:33 AM Hi Ben, I checked the testcase and our application against rev 1390 of branch 1.5.x and they both seems to work fine. Thanks a lot for the fix
Hide
Nick Stuart added a comment - 07/Jan/11 7:41 AM

Of course you went and fixed that after I changed all my jsps around! (layouts not being outermost tags)

But really, thanks for all the work Ben! My main issue of the jsp:include works fine now, and I can test out the inner layouts at some point as well.

Here's why I was using the 'inner' layouts to begin with, maybe we can come up with a better solution. Basically, I was using it for small, shared 'components' that can be used all around our app. The main reason I was using the layout tag, and a simple 'jsp:include' is because the layout tag lets you pass in any parameters you like and have them set in the page context of the layout which is really handy. jsp:include forces you to use <c:set/> before and set it to 'request' scope so the variable is visible on the page being included. It works, but just seems messier to me.

So I was really using it to get around complete lack of 'components' or templates in JSP itself. I know their are jsp fragements, but those act weird and not fully comfortable using them for our needs.

Any thoughts?

Show
Nick Stuart added a comment - 07/Jan/11 7:41 AM Of course you went and fixed that after I changed all my jsps around! (layouts not being outermost tags) But really, thanks for all the work Ben! My main issue of the jsp:include works fine now, and I can test out the inner layouts at some point as well. Here's why I was using the 'inner' layouts to begin with, maybe we can come up with a better solution. Basically, I was using it for small, shared 'components' that can be used all around our app. The main reason I was using the layout tag, and a simple 'jsp:include' is because the layout tag lets you pass in any parameters you like and have them set in the page context of the layout which is really handy. jsp:include forces you to use <c:set/> before and set it to 'request' scope so the variable is visible on the page being included. It works, but just seems messier to me. So I was really using it to get around complete lack of 'components' or templates in JSP itself. I know their are jsp fragements, but those act weird and not fully comfortable using them for our needs. Any thoughts?
Hide
Ben Gunter added a comment - 07/Jan/11 7:56 AM

Nick, that sounds like a clever way to keep your JSPs a little cleaner. I had never thought about using stripes:layout-render in any way except as the outermost tag so it never crossed my mind as I was rewriting the tags. I was convinced that changing them to support such usage was going to be problematic, but as it turned out it really wasn't difficult to do at all. Sorry I made you change your JSPs around, but I thank you for having such a cooperative attitude!

Show
Ben Gunter added a comment - 07/Jan/11 7:56 AM Nick, that sounds like a clever way to keep your JSPs a little cleaner. I had never thought about using stripes:layout-render in any way except as the outermost tag so it never crossed my mind as I was rewriting the tags. I was convinced that changing them to support such usage was going to be problematic, but as it turned out it really wasn't difficult to do at all. Sorry I made you change your JSPs around, but I thank you for having such a cooperative attitude!
Hide
Timothy Stone added a comment - 07/Jan/11 8:49 AM

Ditto, Ben: Never thought about using layout-render any other way than outermost. Though this "attitude" I picked up from Freddy's examples and some "mistakes" made in implementation that didn't work, so I fell back on the examples and thought, "that's just the way it works!" I'll have to think about the use cases for nested use. Sounds like a blog post Rick

Show
Timothy Stone added a comment - 07/Jan/11 8:49 AM Ditto, Ben: Never thought about using layout-render any other way than outermost. Though this "attitude" I picked up from Freddy's examples and some "mistakes" made in implementation that didn't work, so I fell back on the examples and thought, "that's just the way it works!" I'll have to think about the use cases for nested use. Sounds like a blog post Rick
Hide
Sébastien Lesaint added a comment - 07/Jan/11 9:14 AM

In the example I provided for the jsp:include issue, I essentially reproduced what we are doing extensively :

  • a JSP calling layout-render for a layout-definition which defines what we could call a global page template with a content component
  • the content component might contain a jsp:include to include a JSPF (let's call it the content JSPF) which can be defined in Database
  • use stripes:layout anywhere in either the page template JSP or the content JSPF (or any JSP/JSPF it might import) as a way of reusing piece of JSP code intead of duplicating it

What's great about layout-define as a pseudo-component is that we can easily pretend they take "variables" :

  • variables are passed on to the layout-define as attributes of the layout-render tag
  • we can define default values for them just by having a <c:set> before the layout-definition tag in the JSPF
  • there variables can either be data to generate content from or flags changing how the JSP renders for example

We get a pretty clean JSP code in the end.

Show
Sébastien Lesaint added a comment - 07/Jan/11 9:14 AM In the example I provided for the jsp:include issue, I essentially reproduced what we are doing extensively :
  • a JSP calling layout-render for a layout-definition which defines what we could call a global page template with a content component
  • the content component might contain a jsp:include to include a JSPF (let's call it the content JSPF) which can be defined in Database
  • use stripes:layout anywhere in either the page template JSP or the content JSPF (or any JSP/JSPF it might import) as a way of reusing piece of JSP code intead of duplicating it
What's great about layout-define as a pseudo-component is that we can easily pretend they take "variables" :
  • variables are passed on to the layout-define as attributes of the layout-render tag
  • we can define default values for them just by having a <c:set> before the layout-definition tag in the JSPF
  • there variables can either be data to generate content from or flags changing how the JSP renders for example
We get a pretty clean JSP code in the end.
Hide
Marcus Kraßmann added a comment - 08/Jan/11 10:51 AM

My customer is also using WebLogic and there occur the same error messages after trying out release 1.5.5 (currently using 1.5.3). On Monday, I will try out the newest snapshot from Hudson. Crossing fingers

Other question: The streaming behaviour will bring performance benefits when rendering for example big sites with many lines, won't it? So maybe parts of the site will be rendered in the client's browser although the whole rendering did not finish? That would really be cool!

And the last thing: We also use many "snippets" that contain small abstractions for the corporate design. For example, html forms, inputs and buttons are all encapsulated in own layout-definitions, configurable via some attributes that may be passed to them. Maybe this is something like a "best practice" for larger sites and worth being mentioned on the web site...

Show
Marcus Kraßmann added a comment - 08/Jan/11 10:51 AM My customer is also using WebLogic and there occur the same error messages after trying out release 1.5.5 (currently using 1.5.3). On Monday, I will try out the newest snapshot from Hudson. Crossing fingers Other question: The streaming behaviour will bring performance benefits when rendering for example big sites with many lines, won't it? So maybe parts of the site will be rendered in the client's browser although the whole rendering did not finish? That would really be cool! And the last thing: We also use many "snippets" that contain small abstractions for the corporate design. For example, html forms, inputs and buttons are all encapsulated in own layout-definitions, configurable via some attributes that may be passed to them. Maybe this is something like a "best practice" for larger sites and worth being mentioned on the web site...
Hide
Ben Gunter added a comment - 08/Jan/11 11:23 AM

Marcus, if you're referring to the NoSuchMethod error, upgrading to the latest snapshot won't solve that. You have to recompile the JSPs to fix that. However, the latest 1.5.6 snapshot does have other important layout fixes you can test.

Generally, streaming layouts will improve performance and allow the client to begin rendering the page sooner. The difference will be especially noticeable for large pages. The exception is if the layout tags are inside another tag that buffers its content, then whatever is produced by the layout tags is buffered by that outer tag. (In that case, the buffering has nothing to do with the layout tags at all.) That is not common, though.

Show
Ben Gunter added a comment - 08/Jan/11 11:23 AM Marcus, if you're referring to the NoSuchMethod error, upgrading to the latest snapshot won't solve that. You have to recompile the JSPs to fix that. However, the latest 1.5.6 snapshot does have other important layout fixes you can test. Generally, streaming layouts will improve performance and allow the client to begin rendering the page sooner. The difference will be especially noticeable for large pages. The exception is if the layout tags are inside another tag that buffers its content, then whatever is produced by the layout tags is buffered by that outer tag. (In that case, the buffering has nothing to do with the layout tags at all.) That is not common, though.
Hide
Keith added a comment - 10/Jan/11 4:49 AM

Hi Ben,

The 1.5.6-SNAPSHOT is working better.

One small issue is that in our code we are still using a few jsp:include directives in our layout jsp page. These used to work in 1.5.3, but no longer work in the latest versions. Is there a reason for this? It should be a straightforward update to change these to be layout:components however.

Thanks for the fix.

Show
Keith added a comment - 10/Jan/11 4:49 AM Hi Ben, The 1.5.6-SNAPSHOT is working better. One small issue is that in our code we are still using a few jsp:include directives in our layout jsp page. These used to work in 1.5.3, but no longer work in the latest versions. Is there a reason for this? It should be a straightforward update to change these to be layout:components however. Thanks for the fix.
Hide
David Dundua added a comment - 11/Jan/11 9:37 PM

Ben, I found another issue. This one is related to how parameters are passed to the layout-render tag. I have modified the first test case to demonstrate the issue alongside with expected behavior.

Show
David Dundua added a comment - 11/Jan/11 9:37 PM Ben, I found another issue. This one is related to how parameters are passed to the layout-render tag. I have modified the first test case to demonstrate the issue alongside with expected behavior.
Hide
David Dundua added a comment - 11/Jan/11 9:37 PM

Modified first test case to demonstrate issues with how parameters are passed to layout-render tag.

Show
David Dundua added a comment - 11/Jan/11 9:37 PM Modified first test case to demonstrate issues with how parameters are passed to layout-render tag.
Hide
Nick Stuart added a comment - 14/Jan/11 2:23 PM

Found a weird one (at least to me). I have the following:
<s:layout-render>
<s:layout-component>
<s:form>
<s:layout-render>
<s:layout:component>
form stuff here
</s:layout-component>
</s:layout-render>
</s:layout-component>
<s:layout-render>

In the nested component with 'form stuff here', the form tag is being duplicated from the above component. So I get two <form> tags, one nested in the other, which obviously makes the browser do weird things and stuff doesn't get submitted correctly.

I know this is using layout in an 'unintended' fashion, but the behavior of forcefully rendering the form tag where it is not declared (and rendering it twice) is a bit odd..

Show
Nick Stuart added a comment - 14/Jan/11 2:23 PM Found a weird one (at least to me). I have the following: <s:layout-render> <s:layout-component> <s:form> <s:layout-render> <s:layout:component> form stuff here </s:layout-component> </s:layout-render> </s:layout-component> <s:layout-render> In the nested component with 'form stuff here', the form tag is being duplicated from the above component. So I get two <form> tags, one nested in the other, which obviously makes the browser do weird things and stuff doesn't get submitted correctly. I know this is using layout in an 'unintended' fashion, but the behavior of forcefully rendering the form tag where it is not declared (and rendering it twice) is a bit odd..
Hide
Ben Gunter added a comment - 03/Feb/11 11:06 AM

David, I just committed a fix for the parameter passing issue you described. A new snapshot should be deployed soon. Please give it a test and let me know how it goes.

Show
Ben Gunter added a comment - 03/Feb/11 11:06 AM David, I just committed a fix for the parameter passing issue you described. A new snapshot should be deployed soon. Please give it a test and let me know how it goes.
Hide
David Dundua added a comment - 03/Feb/11 4:45 PM

Ben, I tried the latest snapshot and it works. Thanks again for fixing it.

Show
David Dundua added a comment - 03/Feb/11 4:45 PM Ben, I tried the latest snapshot and it works. Thanks again for fixing it.
Hide
Ben Gunter added a comment - 21/Apr/11 2:43 PM

Nick, I just committed a patch that fixes the stripes:form/stripes:layout-render issue you reported on 14 Jan. If you can, please test and let me know how it goes.

Show
Ben Gunter added a comment - 21/Apr/11 2:43 PM Nick, I just committed a patch that fixes the stripes:form/stripes:layout-render issue you reported on 14 Jan. If you can, please test and let me know how it goes.
Hide
Ben Gunter added a comment - 09/Feb/12 1:51 PM

Hi, folks. I wanted to let you know that Timothy Stone, Rick Grashel and I have done a lot of research and testing to get to the root of the problem with WebLogic. We have determined that it is a bug in WebLogic that is triggered when a call to PageContext.pushBody(Writer) is followed by a call to PageContext.include(String, boolean). This sequence of calls is central to the functionality of the streaming layout tags, and so this bug completely breaks them. I have devised a workaround for this problem that is used automatically if the application is running under WebLogic. Long story short, streaming layout tags will work under WebLogic in Stripes 1.5.7. Timothy will follow up with Oracle in an attempt to get them to recognize and fix this bug.

Show
Ben Gunter added a comment - 09/Feb/12 1:51 PM Hi, folks. I wanted to let you know that Timothy Stone, Rick Grashel and I have done a lot of research and testing to get to the root of the problem with WebLogic. We have determined that it is a bug in WebLogic that is triggered when a call to PageContext.pushBody(Writer) is followed by a call to PageContext.include(String, boolean). This sequence of calls is central to the functionality of the streaming layout tags, and so this bug completely breaks them. I have devised a workaround for this problem that is used automatically if the application is running under WebLogic. Long story short, streaming layout tags will work under WebLogic in Stripes 1.5.7. Timothy will follow up with Oracle in an attempt to get them to recognize and fix this bug.

People

Vote (2)
Watch (6)

Dates

  • Created:
    03/Dec/10 9:30 PM
    Updated:
    09/Feb/12 1:51 PM
    Resolved:
    07/Feb/12 9:50 AM