| Author |
Message |
|
|
Heh. Yeah, being on the bleeding edge is what interests me, but that's also what makes it difficult to make a proof of concept work.
I did just discover though, at least I'm extremely certain that if you have a renderer that tells the render manager to render when there are no views listening, in the liferay environment, you will get a "Session Expired" message box the exact second the page loads. This is provided you don't already have it loaded on a page that contains other portlets. I was able to get it off of my initial page of portlets to a blank page, which prevented that session expired message. When I added the portlet that my thread wanted to render to, I am able to use my other portlets normally. Is this a known issue? I can try to throw a sample together to illustrate this. I've actually ran into this issue several times and it's always when a renderer fires with information that would be displayed by a portlet that wasn't added (hence no listener for that render group has been registered yet).
Hopefully that makes sense.
|
 |
|
|
|
I'll find out and let you know, it's a specific product we tried. I'm guessing the way the requests end up rewritten is causing a problem.
|
 |
|
|
|
No problem, it just seems like the majority of my problems are coming due to not being about to understand exactly how the renderers operate in situations since it seems like no matter what I try, the majority of the time icefaces will fail. This is probably more likely my misunderstanding, but I just want to finally understand it all so that I can feel comfortable with using icefaces as a permanent solution in our project.
|
 |
|
|
Actually this time, I'm noticing now that it appears to coincide with one of my ondemandrenderer firing.... at that time though, there isn't a view listening because it's repsond to an event that happened in a thread, but the portlet that would be listening to it hasn't been created it.
If there isn't a renderer attached yet and the event attempts to fire will that cause this error?
|
 |
|
|
|
Whenever I make a chance that icefaces does not like, I will just start getting this messages popping up but there is no explanation why... how do you troubleshoot what icefaces isn't happy about?
|
 |
|
|
I thought that was the job of your render manager? Doesn't it handle giving the same reference to any new bean created? I'm just trying to go by your examples and they seem to indicate this is the preferred way to do it...
So basically I should get a reference in my Application bean and then have the application bean set as a property on my request bean, so it can add itself as a listener. It's strange because that's not in any way the impression I got about how this though it would explain why there are too many render calls happening, but it doesn't explain why bother even having a rendermanager that is set as a property on your bean. I thought that the rendermanager gave you back the same instance based on what string you give.
|
 |
|
|
When I deploy our portlets on a system with a Reverse Proxy, then we get Session Expired messages everytime someone logged in. I'm guessing because of the path change due to the reverse proxy... has anyone successfully implemented this before?
Thanks!
|
 |
|
|
Just to add another note, my app server has been up since I've posted the last message, I've been testing the layout of a new portlet.. while I have some portlets on my page.. there is only one portlet that has an intervalrenderer (basically the same thing as what I sent you) but now it's up to 10 intervalrenderers, for one single portlet. Now, as soon as I log out of the portal, which I just did, the renderers all get destroyed. Shouldn't they be getting destroyed as new ones are getting created? You said you found some code that indicates they might stick around longer than they should but this has to have been at least an hour.
05:41:59,968 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@1f0232d
05:41:59,968 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@631bf9
05:41:59,968 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@67fda8
05:41:59,968 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@219014
05:41:59,968 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@1480f14
05:41:59,968 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@123b1e5
05:41:59,984 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@1e3fcea
05:41:59,984 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@f26f83
05:41:59,984 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@158aa43
05:41:59,984 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.mytask.ba
gbean.ResponseBackingBean@1f31e7
05:41:59,984 DEBUG [ValueBindingImpl] getValue Result:true
05:41:59,984 DEBUG [ValueBindingImpl] getValue Result:true
05:41:59,984 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,000 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,000 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,000 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,000 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,000 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,015 DEBUG [ValueBindingImpl] getValue Result:true
05:42:00,015 DEBUG [ValueBindingImpl] getValue Result:true
|
 |
|
|
|
Ok, that makes sense, I guess I'm considering at least anything in the same WAR to be treated the same as if it were two servlets or something. So guess that means that portlets don't share a session then either...?
|
 |
|
|
Actually the app isn't any different (at least the bean that is using the interval renderer). My request scoped bean has a table, just like the one that I submitted in the support case. When I create an interval renderer, I end up with more and more beans. I was just noticing that as I was doing testing right now, I have 4 request scoped beans rendering for two different portlets (one in IE and one in Firefox), hence why I asked my question, I don't end up with multiple beans if I disable the IntervalRenderer. The only thing I'm doing different this time is that my request scopped beans are referencing more application scoped beans:
04:46:37,031 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.myapp.backingbean.ResponseBackingBean@cacc70
04:46:37,046 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.myapp.backin
gbean.ResponseBackingBean@f3c260
04:46:37,046 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.myapp.backin
gbean.ResponseBackingBean@157e5ef
04:46:37,046 DEBUG [VariableResolverImpl] resolveVariable: Resolved variable:com.myapp.backin
gbean.ResponseBackingBean@1a14f45
I also was testing in IE (6.0) which will not fire an action event for my table, but it does in the latest firefox. I'm wondering if it's confused or something by the multiple beans or if it's just another reminder of how pathetic that browser really is. Either way, are their known issue with IE? I try not to deviate from anything that I see in your example styles to try to prevent breaking either browser with incompatible stuff. It seems like IE always finds something to complain about though. Wonder if it will work if I turn off the interval renderer.....
|
 |
|
|
|
That and if you have multiple beans under the same interval registered name, doesn't creating a bean make every single one of the other beans render as well if you use renderRequest in the setRenderManager?
|
 |
|
|
|
In other words, in the sample code, it shows creating an IntervalListener in the setRenderManager(RenderManager renderManager) method of your bean. Then it has you do a renderRequest. The question is that doesn't that attempt to kick off a rendering when there is already a rendering in progress? I get a lot more traffic when I had that method being called when I switch a page, such as a tab and I get a lot of errors about the DOM being corrupt. If I don't use it, then the server side rendering never occurs... is the example really correct that that is how it's to be done? it seems as though any time the page is fully refreshed you kick off two render passes and corrupt your tree...
|
 |
|
|
|
What's funny about that is it's totally counterintuitive to what should happen. The reason being is that why would you want a request scoped bean that doesn't actually take part in a request? Either way, I had began with Session since that's more what I would assume would be the best way, but the Session beans exhibit the exact same behavior, you still don't get the reference to the existing one. The Application one is the only one that behaves that way, which is fine but it means that I have to be a little more careful about how I do it. Either way, it's now implemented that way and works way better.. I wish I would have realized this sooner... it didn't always directly seem linked to that as the problem.
|
 |
|
|
I actually opened up a support case friday with a WAR file that appears to exhibit the behavior.. I THINK the reason that multiple beans gets created is if you have a reference from one bean to the other, because I think if you have two request beans, and there are to reference each other for communication, JSF (or icefaces, I'm not sure whose responsibility it is) actually will create new instances of the beans and set them as properties of the other request beans... I THINK it's related to that, because I notice that you you have 2 request beans, and one of them with a property of the same class type as the other, you will not get a reference of that object, you get a new one.
Either way, I spent a long grueling sleepless weekend, I completely rewrote the performance related areas of our app that I found with JProbe so that any issue like this wouldn't combine to kill our app. I ended up writing a User state cache that each user gets which controls access to the data and manages when database accesses happen. This way portlets can share data and still be fast... and man that made all the difference..... wow. Can't wait until the few bugs are worked out.....
|
 |
|
|
So I've been trying to work around the performance problems I've been running into recently. Just when I thought I was able to work around them by disabling functionality and changing how my beans work, I am now seeing a new performance related problem.
Since I've changed all my beans to request scope, and moving on to test ones that I hadn't tested yet, I'm noticing that my requests are becoming slow again (I stopped using the IntervalRenderer for updating content since it ends up rendering my app useless after a short period of time). I was noticing that my constructors on my beans are being called twice. So basically I have 3 portlets, each portlet uses one and only one request scoped bean. Each time I change a page, such as a tab, or login or refresh the page, my requests will take about 2 minutes to complete. Now I know it was going to go a little slower because I'm using request beans and can no longer take advantage of preinitializing data for a user session, but it's way slower than I expected. I fired up the debugger on the constructor of one of my beans and noticed that these two classes were mentioned in the call stack:
HtmlOutputText.isRendered
DataTableTag.doEndTag
Coincidentally, my portlet has an output text component and a datatable component (it also has a TabPane in it also, but apparently that has no effect). So it looks like that for every rendered component in a portlet, a new request scoped bean is used? There is no other reason that my beans would be created more than once since it's only a single request.
I tried the debugger on a different one of my request scoped beans and I noticed it hit the constructor twice on that one. That portlet only have a DataTable on it, but it has two rows, in the stack track each time it stopped, I noticed it contained this method call:
TableRenderer.processCurrentRowData
So is this saying that for each row in a data table in a portlet, a new bean is created?
It appears to be doing this as well for my third portlet since setting a breakpoint in that constructor also happens at the time that it calls:
TableRenderer.processCurrentRowData
That portlet has two tables though, one table has a row in it and the other one is empty.
I guess at this rate, I gotta go and switch everything back to session scope and see if there is any way I can get this app into a usable state that way.
|
 |
|
|
|
|