Steve Sims

Greenhorn
+ Follow
since Feb 24, 2009
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
2
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Steve Sims

Although I've marked this topic as resolved, on the basis that I was happy with Tim's advice to stick with the original solution on the basis of risk, I was still intrigued to discover whether I could make Andrea's solution work. Referring to my reply to Andrea, I commented that I needed some way to skip back through the JSF lifecycle in order that the view would be rebuilt with index.xhtml's <ui:include> tag pointing to the newly selected content page.

Whilst searching for a number of solutions, I came across this post: http://www.theserverside.com/discussions/thread.tss?thread_id=48227#246767 which describes how to replace the current view with a new one. I've implemented this in the test app detailed previously within this topic and it appears to work fine. The changes that I made are as follows:

PageBean.java


The obvious issue with it is that it's pretty drastic thing to do and I might expect problems with the content around the "included" pages because it completely removes the current view (and therefore any state associated with the components that were in it) and creates a new version of the same one so use it at your own risk.

I don't know enough about JSF to be able to see all of the implications of it but it does answer my previous question which is why I posted it. If anybody has any comments on it, I'd be interested to hear them however as it may be something that I look at again in a future project.

UPDATE:
Instead of creating a new view, I tried calling ViewHandler.restoreView(FacesContext) which appears to work too - I've currently got no idea what ramifications this might have, but the phase listener that I have monitoring the lifecycle isn't really altered. It does however cause the view to be rebuilt - I'm hoping that any component state is therefore preserved as if this had been a normal page navigation?

The updated reloadView() method is below:

PageBean.java

Again, any answers as to whether this is a reasonable thing to do or not are greatly appreciated.
13 years ago
JSF
Hi Tim,

Thanks again for your feedback. It's good to know that you consider the original approach to be the one to continue with in a real system at this stage. I fully agree with your analysis of premature optimisation i.e. it's like shooting in the dark (especially when you know as little about what's going on inside JSF as I do!) - it's just hard to let it lie! In reality, I think that as long as I'm careful about encapsulating the functionality of a "page" inside its own managed bean as much as possible, any refactoring that I decide to do if there is a performance issue later on, should be much easier.

I'm going to mark this topic as resolved on this basis.

Thanks to both you and Andrea for your time and effort on my behalf.

Steve
13 years ago
JSF
Hi Tim,

Thanks for your reply. I agree with your advice about keeping it simple, however I felt that my original idea had that "bad design" smell about it, in particular the way in which it was creating components and having to parse a large facelets page, most of which would never be used in any given request. Andrea's method of leveraging the facelets templating functionality feels much better to me, except that I can't fit it into the Faces lifecycle satisfactorily.

I guess my fear is that until a large application using my original technique is finished, I wouldn't see any scalability issues until right at the end when the app was tested under load, at which point they might be a real pain to fix and require a lot of refactoring.

As you say, JSF does an awful lot behind the scenes and wrenching it around just to make work what feels like a good solution is probably asking for a world of pain either now or in the future; however, if there is a method of doing it "nicely" then I'd certainly be interested in hearing it!

Steve
13 years ago
JSF
Hi Andrea,

Thank you very much for posting that reply, I'm really close to cracking this now. I've done the following:

index.xhtml:


PageBean.java


page1.xhtml


page2.xhtml


Unfortunately, I've hit a problem with it; the value expression #{pageBean.includeFile} inside index.xhtml's <ui:include /> tag is evaluated before either an ActionSource event or an AjaxBehaviorEvent from the <h:commandButton> or <f:ajax> (page1.xhtml & page2.xhtml) is processed. This means that although I can update PageBean.includeFile to be "page2.xhtml" from the listener, that file won't be included until the next request. I've added a phase listener and can see that includeFile is evaluated before the Apply Request Values phase so even if I set <f:ajax immediate="true"/>, it's still processed after includeFile has been read. Practically speaking, this means that I have to click my button twice in order to navigate to the next page.

Do you by any chance have any ideas how I could work around this at all?

Many thanks for your help - your solution was just what I was looking hoping for!

Steve
13 years ago
JSF
I've created a small application that consists of a single Facelets page, with the pages that I want to display all contained within it. Each "page" is really an <h:panelGroup> with its "rendered" attribute set if it is the one to be displayed. The following code example shows the sort of thing that I've done:

That solution works fine, however it looks like a bad design to me; the problem being (as I understand the lifecycle) is that if "rendered" is false, it only prevents the HTML markup from being rendered in the response and in fact, even if #{myViewScopedBean.currentPage} evaluates to "Page2", "page1" and all of its child components are still being created. This seems really wasteful and within an application that has many "pages" and therefore components, it must simply be the wrong way of doing it.

Is there any way that I can programmatically "switch out" the creation of parts of the component tree (for example "page1" and children) when I only want to display "page2"? I've looked within the Facelets templating tags and I couldn't see anything there that might let me do it. Or am I on the wrong track entirely and people use an entirely different method to create large all-AJAX based web apps?

Many thanks in advance for your help.

Steve
13 years ago
JSF
I'm now happily running integration tests with repeatable results from a standalone JUnit application, calling through a JAX-RS view layer using HTTP into an EJB3 business logic layer which in turn is using the EclipseLink JPA data layer.

My original problem was that I want to use functionality in the test code that I don't want to expose in the production code (such as wiping all data from the database etc.). Using JDBC from JUnit (which can't directly use my JTA configured Persistence Units), I was able to do all of the nasty things required for my tests to behave consistently. Unfortunately, EclipseLink's cache was becoming stale due to my outside tinkering through JDBC.

My test harness now performs the following actions before each test:
  • Clear out each table in the database using JDBC
  • Call an application one-time-only "setup" resource that in turn calls through to an EJB business method that invalidates all EclipseLink cache for the server
  • Perform any per-test JDBC database bootstrapping


  • The call used to solve my particular problem of stale cached objects was made accessible by using EclipseLink's JpaHelper utility class to eventually get hold of an interface to the identity map, upon which I call invalidateAll() to invalidate all cached objects. The following code was added to the "setup" resource that ultimately initialises a newly deployed instance of the application by bootstrapping the database amongst other things:

    Perhaps this'll be of some use for other people wondering how to invalidate the entire EclipseLink cache for a particular server.

    Thanks,

    Steve
    Hello,

    I'm trying to test a Glassfish hosted web application which calls various EJBs that in turn use the Eclipselink JPA implementation as the persistence layer. In my pre-test setup method, I'm using JDBC native queries to clear out the tables in my database so that each test will run with a clean database.

    I then have a JUnit test case that is designed to run standalone and access the app using an HTTP client and everything's working great...the first time around. The issue is the second run as on the server, I can see records being retrieved (presumably from Eclipselink's cache) that aren't in the database (which I can see has been cleared out by the "setUp" JDBC calls mentioned earlier).

    I've tried turning the cache off in the persistence.xml descriptor by setting eclipselink.cache.type.default to NONE, which caused stack overflow errors and I've also tried reducing the size of the cache to 0 in an attempt to force the cache to refresh all objects from the data store but it doesn't help unfortunately.

    I was wondering how people tested remotely in this manner?

    Many thanks for reading this post,

    Steve