Sunday, February 1, 2009

Problems with the Mozilla Component.utils.Sandbox

Writing a Firefox extension can be time consuming for the first time, the documentation is more reference oriented, more oriented to C++ than the JavaScript version, but it is the worst when there are bugs and you waste hours of work. That is what happened to me with the Sandbox APIs of Firefox 3. After talking to members of the FireBug extension on its Google groups forum, I found out that I am not alone with Sandbox frustrations.

The Sandbox

The sandbox, introduced in full in FF3, is a container that allows extension developers to run code in lower security. This is helpful for interacting with browser web pages or for running code from a server. The Sandbox API Documentation is pretty light, and gives no useful examples for real-world applications. The primary use of the sandbox is probably to work with pages, but they show no example on how to do that.

My Problem

When I was working on an extension I write for work, I found that I had some extremely peculiar results. As an illustration, lets say there are two types of JavaScript objects in a page that you want to work with. The first, is a single instance object that looks up other JS objects, and the second, a 'normal' JS object that we want to create. So for my example, lets say we want to lookup an object, pass that object into a constructor and then run a method on that new object:

  var obj = TheRegistry.lookupObject('customId1');
  var ref = new ObjectReference(obj);
  ref.save();

Now, I want to run this code in my extension, so I setup the sandbox and execute the code like this:

  var evalInSandbox = function(win, script, vars)
  {
    win = getUnwrapped(win);
    var sandbox = new Components.utils.Sandbox(win);
    sandbox.window = win;
    sandbox.document = sandbox.window.document;
    sandbox.XPathResult = Components.interfaces.nsIDOMXPathResult;
    sandbox.__proto__ = win;
    if (vars)
    {
      for (var prop in vars)
      {
        sandbox[prop] = vars[prop];
      }
    }
    return Components.utils.evalInSandbox(
      "(function() { " + script + "\n })();", sandbox);
  };
  
  var getUnwrapped = function(obj)
  {
    while (obj.wrappedJSObject)
    {
      obj = obj.wrappedJSObject;
    }
    return obj;
  };
  
  var doSomething = function(window)
  {
    evalInSandbox(window,
      "var obj = TheRegistry.lookupObject('customId1');"+
      "var ref = new ObjectReference(obj);"+
      "ref.save();");
  }

What I was surprised to find out is that ref had no 'save' method, but I knew that was not the case. Looking further into it, ref == obj. What the heck?! I tried wrapping the code with with (window) { ... }, using new window.ObjectReference(obj), but nothing would work. Finally I gave up on the code and used a FireBug technique to inject a script tag into the page's DOM.

Wrap Up

I wrote this article, not to teach, but hopefully to save other people some time so if the google 'mozilla sandbox bugs' or something similar, they may find this. Hopefully Mozilla will fix the sandbox and improve its documentation, but until then, watch out for bugs, and stay away from creating page objects using the 'new' keyword inside of the sandbox, it just doesn't work.

BTW, the google group discussion I mentioned can be found here.

Tuesday, January 27, 2009

JSF Component Binding Stinks

Whoever came up with JSF component binding should be taken out back. While a nice thought, it really is just a purely awful piece of design and was not thought through at all.

Too harsh? Well, it sounds harsh, but when you consider all the flaws and bugs it causes, it isn't.

1. The problem

I have been telling people on the MyFaces mailing list to always ensure that they use binding with request scope beans, but I have realized that this advice was now bad. My advice should have been to never use binding at all, or to at least only use a setter, but no getter.

The reason behind this, is that there is a fundemental flaw in how binding was designed. Binding is too completely separate pieces of functionality, jammed together in one implementation:

  1. Component factory
  2. Component access from code

The latter is what people normally use binding for. This is how the framework uses binding in a JSP component tag:

  1. Does the tag have the binding attribute set?
    1. If so, call the getter method
      1. If returns not null, use that value
      2. Else, create a new component
        1. Call the setter with the new component

What you now see is that the getter method acts as both a normal JavaBean property getter as well as a factory. The problem is that 90% of the time, the lifetime of this member variable is too long. Almost always, the component in the bean should only be ever stored as long as the view is being processed. Take this example:

Developer has a managed bean with a request scope with a bound component. The page navigates from view1 to view2.

Jspx Code:

  <?xml version='1.0' encoding='utf-8'?>
  <jsp:root
    version="2.1"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:jsp="http://java.sun.com/JSP/Page">
    <jsp:directive.page contentType="text/html;charset=utf-8"/>
    <f:view>
      <html>
        <body>
          <h:form>
            <h:outputText binding="#{myBean.textComponent}" />
          </h:form>
        </body>
      </html>
    </f:view>
  </jsp:root>

Now the views would probably be different, but it is not unusual for someone to reuse #{myBean.textComponent} in the page. Now what happens is that view1 causes the #{myBean.textComponent} to be set since it would return null on the restore view. View 2 is navigated to, but the #{myBean.textComponent} returns the component from view 1, so it is not re-created. Now we have an illegal state, a component is shared between two views.

There could have been two ways of fixing this:

  1. There could have been a create or factory attribute on the JSP tag and only that attribute could ever create the component and the set method on the binding would be used, but never the getter method.
  2. The JSP tag component creation should be smart enough to always check that a component is never shared across views. Therefore, if a binding expression returns a component that already has a parent and by looking up the tree, the view root is not the current view root, a new component should have been created.

So what is the best work around for this problem?

Well the best solution is to never use binding under any circumstances, ever, no exceptions. This is the only safe way to write JSF pages. If your bean needs to access a component, use findComponent or invokeOnComponent to get the component.

The other alternative is to check the view root yourself in you bean when the getter is called. If the view has changed, return null. Example:

  package blog;
  
  import java.util.Map;
  
  import javax.faces.component.UIComponent;
  import javax.faces.component.UIViewRoot;
  import javax.faces.context.FacesContext;
  
  public class MyBean
  {
    public void setMyComponent(UIComponent myComponent)
    {
      this.myComponent = myComponent;
    }
  
    public UIComponent getMyComponent()
    {
      checkViewRoot();
      return this.myComponent;
    }
  
    private void checkViewRoot()
    {
      UIViewRoot current = FacesContext.getCurrentInstance().getViewRoot();
      if (this.viewRoot == null || (current != null && current != this.viewRoot))
      {
        this.viewRoot = current;
        // view is new or has changed, make sure the component is not re-used
        this.myComponent = null;
      }
    }
  
    private UIComponent myComponent;
    private UIViewRoot viewRoot;
  }

Ugly? Bad performance? Yes! Unfortunately this may be the best solution if you have to use component binding. From what I have seen from JSF 2.0 I think there may be factory support, so that component binding to be able to gain access to a component in a bean is separated from component creation. I hope so. Until then, I strongly recommend that you forget that the binding attribute exists at all.

Monday, January 19, 2009

JSF compared with CGI-like development for small web sites

I have been developing small side web sites in PHP, Python and Java. With my primary job working with Java / JSF, I found that it was not my favorite development environment. I thought I would share some of my experiences.

JSF

JSF is a great framework, with a lot of promising ideas, but the more I have tried to work with it, the more I find that it may not be the best solution for writing web pages nor small web applications.

Pros:

  • Many open source libraries to leverage
  • Large company backing
  • Complex components with 3rd party libraries
  • Code and view are separated
  • Java has good refactoring tools
  • Fail-over, clustering and other robust business features
  • Part of J2EE
  • Built-in validation and conversion
  • 3rd party libraries can make AJAX fairly easy

Cons:

  • Must be compiled and deployed
  • Too much XML configuration
  • Components are good for 90% of use cases, but severely handicap the other 10%
  • AJAX geared for PPR only, hard to use AJAX for web-service like functionality
  • State saving methodology is abysmal and kills performance and scalability
  • Multi-phased processing on server is confusing to many users
  • Poor CSS support as components and HTML are loosely tied
  • Poor JavaScript library integration
  • Very few web hosting choices

Comparison with CGI

CGI and similar programming usually involves Perl, PHP, Ruby or Python. I have not written Perl in a while as I prefer python and hove not written and Ruby, but I have written full sites in PHP. CGI, or Apache module based languages do not have the framework idea that Java has. Java seeks to give you factories, factories for your factories, paradigms, many standard and rigid APIs, where these other libraries do not. This is a pro. and a con. in my opinion. I love jQuery as it makes client side development terrific, I could do a whole set of blogs on it (maybe I will), but it is more easily used from these other languages compared to Java.

What I find is that even though I love the cool frameworks of Java, the many nice APIs, it is very hard to make a web site with JSF that looks even remotely appealing. From my experience, I can create about a third of a website with jQuery, PHP or Python and PosgreSQL before I have written one page in JSF. This is mostly because of the problem that JSF is too high-level. It does not let me do what I want. In PHP I can loop over a data set and create a table and then easily use jQuery and AJAX to add & remove rows from that table. JSF this is extremely hard, you get validation errors from current rows, the 3rd party render kits never have add & remove rows, their AJAX is almost always built in and you can't customize it.

What it comes down to is that I do not need help with the GUI and HTML, I just want some help with tedious tasks. JavaScript libraries like jQuery make rapid web development easy as there are a ton of plug-ins written for it, many of which are more customizable than the ones offered for JSF. Since I can design my own site and get low level, I do not have to fight a render kit from JSF, or the phases of JSF, I just write it the way I want. Now for users that may not be the best with HTML and JavaScript, maybe a framework is great.

Even though this is important, the other thing I love about developing on Apache and not in a JSF server, is that to make a change, I save a file. In Java, I run mvn (Maven 2) to build, then restart Jetty to test. Working with Tomcat, JBoss or another application server is even worse. It just takes too long to work on. I can make a couple of changes and test with PHP when I am still waiting for my Java application server to start up. Not too mention that Java servers tend to be a major RAM hog.

JSF and Component Trees

Another thing that keeps bothering me in JSF is the notion of a web application and the component tree. In JSF, the pages are designed to be shown once, but this is not how web applications work. Web applications, should be mostly one web page that changes as I interact with it (like gmail for example). I should not have to wait for full page refreshes all the time. JSF's components can do this, but not the view layer. JSP is horrendous with dynamic includes and Facelets has issues too (mostly tag / tag handler to component ID matching issues). Without dynamic includes, it is very hard to author wizards, or pages that change (not reload).

I wonder if Google was smart to avoid Java's JSRs and avoid JSF and develop GWT, a web application development framework made for robust clients.

Final thoughts

This is truly a blog post, in that I am just sharing some thoughts as they stream from my head to my keyboard. I could say more on the subject, but don't have the time at the moment. Perhaps JSF2 will improve JSF development, but from what I have seen it only goes so far and will have many of the same flaws, although it does have a lot of cool new functionality.

It will be interesting to see where the space goes in 5 years, but I will be surprised if JSF lasts that long with its current design. I think that high-level frameworks are just too hard to work with. I really see why most web sites are still written using interpreted languages like Perl, PHP and Python. I still love Java and JSF, but for small web sites on the side, I really don't think JSF can compete at all with its light-weight competitors.

Tuesday, January 13, 2009

tr:switcher has some lifecycle caveats

The Apache MyFaces Trinidad has some optimizations in the component that can easily cause application exceptions.

The switcher only decodes, validates, updates and renders the facet that is currently show. For example:

<tr:switcher defaultFacet="#{bean.facet}">
 <f:facet name="one" />
 <f:facet name="two" />
</tr:switcher>

If bean.facet evaluates to "one", then only the facet with that name will be decoded, validated, updated and rendered. This means, that if the bean value is changed, another component will be acted upon. Take this example:

<tr:selectOneChoce id="soc1" value="#{bean.facet}" autoSubmit="true">
 <f:selectItem itemLabel="One" itemValue="one" />
 <f:selectItem itemLabel="Two" itemValue="two" />
</tr:selectOneChoce>
<tr:switcher id="sw1" defaultFacet="#{bean.facet}">
 <f:facet name="one">
   <tr:inputText id="it1" value="#{bean.one}" />
 </f:facet> 
 <f:facet name="two">
   <tr:inputText id="it2" value="#{bean.two}" />
 </f:facet> 
</tr:switcher>

What will happen is this:

  1. APPLY_REQUEST_VALUES
    1. soc1 is decoded (submitted value is set)
    2. sw1 is decoded
    3. it1 is decoded (submitted value is set)
  2. PROCESS_VALIDATIONS
    1. soc1 is validated (value is converted and set as a local value)
    2. sw1 is validated
    3. it1 is validated (value is converted and set as a local value)
  3. UPDATE_MODEL_VALUES
    1. soc1 is updated (backing bean #{bean.facet} is set to new value)
    2. sw1 is updated
    3. it2 is update (no submitted or local value)

As you can see it1 is decoded and validated, but not updated. it2 is updated but not decoded or validated.

Now, lets consider the Trinidad tree (UIXTree component). Inside the decode of the tree, the code ensures that the component has been initialized using its __init() method. This method ensures that the tree's disclosed and selected row key sets are not null. Since the JSF phases dictate that the decode method will be called before the updateModel method, the init method is not run for the other phases. Now, if the switcher is used as it is above and there is a tree in one of the facets, this means that the tree may not have ever initialized its disclosed row keys.

The 'fix'

To ensure that a component's lifecycle is fully run, that means that the switcher's facet cannot be changed between the decode and the end of the update model phase. This basically means that the value should only be changed during the INVOKE_APPLICATION phase. So here is an example of that:

<tr:selectOneChoce id="soc1" valueChangeListener="#{bean.switch}" autoSubmit="true">
 <f:selectItem itemLabel="One" itemValue="one" />
 <f:selectItem itemLabel="Two" itemValue="two" />
</tr:selectOneChoce>
<tr:switcher id="sw1" defaultFacet="#{bean.facet}" binding="#{bean.switcher}">
 <f:facet name="one">
   <tr:inputText id="it1" value="#{bean.one}" />
 </f:facet> 
 <f:facet name="two">
   <tr:inputText id="it2" value="#{bean.two}" />
 </f:facet> 
</tr:switcher>
public class Bean
{
 private String facet;
 private UIXSwitcher switcher;

 public Bean()
 {
   this.facet = this.selectFacet = 'one';
 }

 public UIXSwitcher getSwitcher() { return this.switcher; }
 public void setSwitcher(UIXSwitcher switcher) { this.switcher = switcher; }

 public String getFacet() { return this.facet; }

 public void switch(ValueChangeEvent event)
 {
   if (event.getPhaseId() != PhaseId.INVOKE_APPLICATION)
   {
     event.setPhaseId(PhaseId.INVOKE_APPLICATION);
     event.queue();
     return;
   }
   this.switcher.setFacetName((String)event.getNewValue());
 }
}

Now this is a bit of a hack, but this ensures that the callback to set the switcher only occurs during the correct phase.

Change UIXSwitcher?

A very good argument could be made that UIXSwitcher should not prevent the decoding, validating and updating of all of its children. This would be more acceptible from a JSF perspective. The problem with this is that it would drastically impact performance of users that are expecting this behavior.

Wrap Up

The take away, is that any component that affects the lifecycle methods of other components must be used with care. A component should always decode, validate and update in that order, and should never have its lifecycle changed. Hopefully this post will help avoid problems that are not that easy to debug.

New location

I am moving my previous blog of http://andrewfacelets.blogspot.com to here. This is to broaden the scope of my blogs to all software development instead of constraining myself to JSF and facelets. Some blogs to be posted here shortly. Thanks for reading.