Physical Request-Scoped Attributes for JSF in Portlets

•July 3, 2008 • Leave a Comment

One of the more frustrating parts of portal development is the fact that the Portal Specification does not follow good “design by contract” principals. One aspect of this deficiency is how the behavior of request-scoped attributes is defined in the portlet specification.

In the servlet world, there is one Request object for each physical request from the the browser. This is called a single-phased request. Because of their complexity and the need to enable applications to perform better, the Portlet 1.0 specification introduced a multi-phased request in which certain types of requests are run in response to certain types of requests. This means that rendering logic can be light and fast in its implementation while data-fetching logic and processing could be done only when a portlet is the target of its own request.

Although this approach has merit, the Portal Specification does not clearly outline the lifespan of a request-scoped attribute. Many portal vendors (quite incorrectly in my opinion) say that items added to the request during the processAction will NOT be available during the render. While other vendors, including the R.I. do preserve these attributes between an action and its render request. This means that different containers behave differently depending on their implementation, which is something that directly violates “Design by Contract” principals.

JSR-301 Portlet Bridge’s Take

The JSR-301 Specification tries to address this inconsistency for JSF applications by stating that Request Attributes which are added during a JSF Action phase of the lifecycle, should be available during the following render and all subsequent renders. This allows a situation where a JSF portlet which needs to be rendered as a result of another portlet’s action, can simply continue by running the render portions of the lifecycle. This behavior happens regardless of behavior and although there may be some challanges in dealing with this nuance, it will remain consistent across portal boundries.

For those attributes that should NOT be around for subsequent renders, like per-request state information, JSR-301 added a special configuration as well as an “@ExcludeFromManagedRequestScope” attribute which allows an attribute to remove itself from this feature. For example, let’s say a renderkit stores an attribute on the request which holds a flag telling the renderkit to render in XML (for an Ajax request) rather then html. If this bean persisted to multiple requests, you might find that your renderkit would render ajax content directly into your portlet’s window on the portal page. This is NOT the desired result.

Where JSR-301 falls short, however, is that it does not enforce any sort of consistency when a bean is excluded from the managed request scope, instead it defers to the logic defined by the portal container. As such, attributes which are excluded from the managed request scope suffer from the same implementation-specific problems that the Portlet 1.0 containers suffer from.

The good stuff

There are several ways to handle this situation. The first is to make sure that beans are able to be re-created on an as-needed basis, even from a portlet render request. This is a challange in a portlet environment because parameters which are passed into the action are not available during the subsequent render request unless they are explicitly added. Furthermore, if the parameters are added, they will be added to every Render request until either a render request is called specifically or until antoher action is called on the portlet. In either case, this suffers the same pitfalls as the bridge’s managed request scope, so if your initialization state is dependent on incoming parameters for your initialization, it will be very difficult for you to manage this manually.

Another approach, and the one which I will concentrate on here, is to develop your own mechanism for preserving request attributes from action to render. Before I get started, I also want to make some comments about the code. This code it an example which I’m using to illustrate an idea. As such, I’m not worrying about thread safety and robustness so much as I’m trying to illustrate an idea. If you want a pre-canned solution, I will likely be adding one to the configurator mechanism that I currently have under development, so keep watching this blog for further details.

The code below outlines the usage of a custom FacesContext Decorator.

  public class FacesContextImpl implements FacesContext
  {
    private FacesContext _orig;
    public static final String STATE_NAME = "scottobryan.STATE";
    public FacesContextImpl(FacesContext context)
    {
      _orig = context;
      ExternalContext ec = getExternalContext();
      Map<String, Object> saved = null;
      if(ec.getRequest() instanceof RenderRequest)
      {
        /*
         *First we look to see if we have a stored state
         *For this example I'm using the session but you can
         *use other scopes
         */
        saved = (Map<String, Object>)ec.getSessionMap()
                                         .remove(STATE_NAME);
      }

      if(saved == null)
      {
        saved = new HashMap<String, Object>();
      }

      ec.getRequestMap().put(STATE_NAME, saved);

      //TODO your other logic here
    }

    //TODO all other methods should delegate except release
    @Override
    public void release()
    {
      ExternalContext ec = getExternalContext();
      if (ActionRequest) instanceof ec.getRequest())
      {
        Map<String, Object> state =
         (Map<String, Object>)ec.getRequestMap()
                                  .remove(STATE_NAME);
        ec.getSessionMap().put(STATE_NAME, state);
      }

      _orig.release();
    }
  }

Lines 17 and 18 are responsible for trying to get the state off the session if it exists. If it does not then a new state map is created regardless of environment.

Lines 33 to 46 will save the map to the session when the FacesContext is release by the bridge. It will only do this on an action request since that’s the only usecase we care about. For cleanliness I go ahead and remove it from the request, but an uglier (albeit faster) technique might be to try to leave it on the request so that during the next render you can figure out whether you are in a container which preserves request attributes and are therefore able to disable this caching altogether.

The code will make sure that there will be a map stored on the request attributes by the name of STATE_NAME and that any attributes which are appended to it will be available throughout the lifetime of the physical request. If you have a container that is not tolerant of non-serializable data on the session (by spec it should be, just not for failover), you can either make all your stuff serializable or you can play around with appending it to the Application scope.

Also, it might be good to be able to encode some sort of id that can be used to tell whether the state belongs to a certain render request or not in case something happens and the render does not follow the action for which is was intended. This could happen as a result of a network hickup on a remote (WSRP) portal, but I’m hoping that in such circumstances portals are able to recover better.

Enjoy!

Commercial Viability of OpenSource

•June 23, 2008 • Leave a Comment

Let me start of by saying that I’m no zealot. I don’t really care bits for beans about the difference between OpenSource and Free (the impact is the same to me as a user of the software), and I have no compunctions about going out an buying a piece of software if it is worth what I spend on it. I also believe that OpenSource products are only strengthened when companies are allowed to leverage them to make money.

I was talking to a friend the other day and their company was trying to decide whether to go with an open source project for development of their applications or whether to develop something completely in-house. The question they were asking themselves was, “Is it more important for you to have a stable API, or is it more important to claim that your software is based off of open standards.” We can all guess what the answer was.

This, however, is not a fair question. They confused having less control over a project with not being able to have stable APIs. OpenSource software can, and often does, have API’s that are just as stable as the ones developed in-house. In many cases they are more stable, especially if the OS Community you choose has a large and diverse support base. Sure, there are some OpenSource products that change from release to release, but if a company does its due diligence and finds a community where backward compatibility is important, using these products should not be much of a concern.

While the above may not have been a fair question though, I think the real question to ask is if OpenSource Software can deliver the balance between flexibility and stability that a company is looking for. Many companies have changed API’s and implementations from time to time simply because the current architecture didn’t lend itself to solving an important problem. This is especially true in XP shops which don’t pay as much attention to the longevity of a design as other development paradigms. Tying yourself to an OpenSource community makes this “balance” a little more difficult because the balance the product does not have a singular definition of what this proper balance is. I would assert, as a matter of fact, that for larger and more organized OpenSource communities, you tend to find that a project mimic’s its most conservative contributors.

So how can some of the issues of OpenSource be mitigated?

  1. Research the community: As important as the functionality of an OpenSource project is the community that supports it. This is one of the most often overlooked aspects of deciding whether to use or support an OpenSource initiative. Is backward compatibility important to the community? Is the community responsive to bugs and enhancements? Is the community responsible with managing it’s releases. Is the community generally in line with your companies ideals between the balance of stability and flexibility. Especially if you are willing to become active in the community, driving functionality is easy provided the community holds the same values as your organization.
  2. Become active in the community: Many OpenSource communities, like Apache, give a bigger say in product direction to those people who contribute the most to the project. It’s only fair. This of course needs to be tempered with the fact that the community must be protected from bullies (ie. companies who dedicate a bunch of resource to ‘hijack’ a community). Most programmers and managers of large community-driven projects tend to be responsible and simply want to do the right thing. The best way to protect your companies interests in an OpenSource project is to become active. OpenSource projects should not be seen by organizations as “free” software. Rather the cliche’ of “you get what you pay for” holds true. The more you put into a project, the more say you have in the project’s direction and those efforts in turn benefit the community. As such, while OpenSource may not be free, it will generally be a bargain.
  3. Become Organized: The best way to limit exposures to an OpenSource community is to be organized. Have a clear understand of your architecture and identify which parts are harder for your to be flexible in then others. Let your developers who contribute to the OpenSource community have a clear understanding of your product and its direction so that they can, in turn, fight harmful initiatives in the OpenSource community. Also understand at what level you integrate with an OpenSource product and identify which areas are most important to you and your company to concentrate your development efforts.

I hope this helps somewhat and I’ll probably have more rants about the OpenSource in the future. There are many companies who have leveraged the power of OpenSource to drive their commercial goals whether those goals be industry acceptance, shared development, or cheaper infrastructure.

Good Luck!

Speaking at JSFOne

•June 18, 2008 • Leave a Comment

Kito Mann is starting a new conference called JSFOne and I’ve been invited to be a speaker. I’m going to be covering some of the work that we’ve done on the JSR-301 Portlet Bridge as well as some advanced topics with JSF and Portlets.

Although for many, Portlet compatibility is a secondary concern, I’ve seen a few innovative applicaiton suites that have been able to utilize portlet technology to increase productivity and ease of use. JSF integration with these environments was originally thought to be fairly straight forward but when people began using JSF within a Portlet environment, they soon realized how wrong this assumption was.

As such, the Portlet world and JSF’s role as a view technology within that world is currently in a state of transition. Many JSF developers find programming portlets cumbersome and hard to understand. I’m hoping in these sessions to belay those fears and to help people to understand that Portlet Development in JSF need not be difficult, but it is different. Much of the complexity of using JSF Development in a portlet environment will hopefully be solved with the 301 bridge and allow us to move forward with enabling companies to leverage these technologies.

First Post

•June 18, 2008 • Leave a Comment

Well after much prodding, and a certain amount of hair pulling, I’ve decided to open up a blog. I’m hoping that this blog will help out people with their projects and I’m sure I can find some unique topics of interest in it.

Enjoy!