Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
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
Attachments
-
- example.tar.gz
- 29/Dec/10 6:08 PM
- 0.9 kB
- Nick Stuart
-
$i18n.getText("admin.common.words.hide")
- stripes-bug.zip
- 03/Dec/10 9:30 PM
- 10 kB
- David Dundua
-
- stripes-bug/pom.xml 2 kB
- __MACOSX/stripes-bug/._pom.xml 0.2 kB
- stripes-bug/src/.../DefaultContext.java 0.3 kB
- stripes-bug/src/.../ExceptionHandler.java 0.8 kB
- stripes-bug/src/.../stripes/HomeAction.java 0.7 kB
- stripes-bug/src/main/resources/log4j.xml 0.7 kB
- stripes-bug/src/main/webapp/error.jsp 0.6 kB
- stripes-bug/src/main/webapp/index.jsp 0.6 kB
- stripes-bug/src/.../test1/layout-sub.jsp 0.6 kB
- stripes-bug/src/main/.../test1/layout.jsp 1.0 kB
- stripes-bug/src/main/.../test1/test1.jsp 0.3 kB
- stripes-bug/src/main/.../test2/layout.jsp 0.6 kB
- stripes-bug/src/.../some-other-layout.jsp 0.4 kB
- stripes-bug/src/main/.../test2/test2.jsp 0.6 kB
- stripes-bug/src/main/.../WEB-INF/web.xml 2 kB
-
$i18n.getText("admin.common.words.hide")
- stripes-bug-2.zip
- 02/Jan/11 1:10 AM
- 12 kB
- David Dundua
-
- stripes-bug/pom.xml 3 kB
- __MACOSX/stripes-bug/._pom.xml 0.2 kB
- stripes-bug/src/.DS_Store 6 kB
- __MACOSX/stripes-bug/src/._.DS_Store 0.1 kB
- stripes-bug/src/.../DefaultContext.java 0.3 kB
- stripes-bug/src/.../ExceptionHandler.java 0.8 kB
- stripes-bug/src/.../stripes/HomeAction.java 0.8 kB
- stripes-bug/src/main/resources/log4j.xml 0.7 kB
- stripes-bug/src/main/webapp/error.jsp 0.6 kB
- stripes-bug/src/main/webapp/index.jsp 0.7 kB
- stripes-bug/src/.../test1/layout-sub.jsp 0.6 kB
- stripes-bug/src/main/.../test1/layout.jsp 1.0 kB
- stripes-bug/src/main/.../test1/test1.jsp 0.3 kB
- stripes-bug/src/main/.../test2/layout.jsp 0.6 kB
- stripes-bug/src/.../some-other-layout.jsp 0.4 kB
- stripes-bug/src/main/.../test2/test2.jsp 0.6 kB
- stripes-bug/src/main/.../test3/component.jsp 0.2 kB
- stripes-bug/src/main/.../test3/layout.jsp 0.7 kB
- stripes-bug/src/main/.../test3/test3.jsp 0.3 kB
- stripes-bug/src/main/.../WEB-INF/web.xml 2 kB
-
$i18n.getText("admin.common.words.hide")
- stripes-bug-3.zip
- 05/Jan/11 7:20 AM
- 10 kB
- Sébastien Lesaint
-
- stripes-bug/stripes-bug/pom.xml 2 kB
- stripes-bug/stripes-bug/.../webapp/index.jsp 0.5 kB
- stripes-bug/stripes-bug/.../index.jsp~ 0.5 kB
- stripes-bug/stripes-bug/.../webapp/test.jsp 0.1 kB
- stripes-bug/stripes-bug/.../sub_layout.jspf 0.1 kB
- stripes-bug/stripes-bug/.../main_layout.jspf 0.2 kB
- stripes-bug/stripes-bug/.../content.jsp 0.3 kB
- stripes-bug/stripes-bug/.../webapp/error.jsp 0.6 kB
- stripes-bug/stripes-bug/.../log4j.xml 0.7 kB
- stripes-bug/stripes-bug/.../WEB-INF/web.xml 2 kB
- stripes-bug/stripes-bug/.../HomeAction.java 0.6 kB
- stripes-bug/stripes-bug/.../HomeAction.java~ 0.7 kB
- stripes-bug/.../ExceptionHandler.java 0.8 kB
- stripes-bug/.../DefaultContext.java 0.3 kB
$i18n.getText("admin.common.words.show")- stripes-bug-3.zip
- 05/Jan/11 7:20 AM
- 10 kB
- Sébastien Lesaint
-
$i18n.getText("admin.common.words.hide")
- stripes-bug-4-param-problems.zip
- 11/Jan/11 9:37 PM
- 12 kB
- David Dundua
-
- stripes-bug/.DS_Store 6 kB
- __MACOSX/stripes-bug/._.DS_Store 0.1 kB
- stripes-bug/pom.xml 3 kB
- __MACOSX/stripes-bug/._pom.xml 0.2 kB
- stripes-bug/src/.../DefaultContext.java 0.3 kB
- stripes-bug/src/.../ExceptionHandler.java 0.8 kB
- stripes-bug/src/.../stripes/HomeAction.java 0.8 kB
- stripes-bug/src/main/resources/log4j.xml 0.7 kB
- stripes-bug/src/main/webapp/error.jsp 0.6 kB
- stripes-bug/src/main/webapp/index.jsp 0.7 kB
- stripes-bug/src/.../test1/layout-sub.jsp 0.8 kB
- stripes-bug/src/main/.../test1/layout.jsp 1.0 kB
- stripes-bug/src/main/.../test1/test1.jsp 0.4 kB
- stripes-bug/src/main/.../test2/layout.jsp 0.6 kB
- stripes-bug/src/.../some-other-layout.jsp 0.4 kB
- stripes-bug/src/main/.../test2/test2.jsp 0.6 kB
- stripes-bug/src/main/.../test3/component.jsp 0.2 kB
- stripes-bug/src/main/.../test3/layout.jsp 0.7 kB
- stripes-bug/src/main/.../test3/test3.jsp 0.3 kB
- stripes-bug/src/main/.../WEB-INF/web.xml 2 kB
$i18n.getText("admin.common.words.show")- stripes-bug-4-param-problems.zip
- 11/Jan/11 9:37 PM
- 12 kB
- David Dundua
Activity
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.
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....
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.
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!
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.
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.
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.
Example of <jsp:include> not rendering correctly.
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
David, a fix for your third test case was committed in r1380.
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.
Ben, Thank you very much. I built the latest from trunk and test case 3 is working now.
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.
obviously, I meant "it worked fine with 1.5.3"
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 ![]()
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.
Reopening for work on the issue reported by Sébastien.
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.
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.
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.
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
Keith, you need to force your JSPs to recompile. They're trying to call methods from BodyTag when LayoutComponentTag no longer implements BodyTag.
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
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?
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!
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 ![]()
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.
- 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
- 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
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...
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.
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.
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.
Modified first test case to demonstrate issues with how parameters are passed to layout-render tag.
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..
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.
Ben, I tried the latest snapshot and it works. Thanks again for fixing it.
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.
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.
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.