Is Visual Web Pack Based On Shale?
By craigmcc on Dec 07, 2006
Short context setting comment: Yes, it has been a long time. No, there's no good reason. Yes, we just had another release that frees my time in the short term. No, that's not an excuse. Deal with it :-).
If you follow Netbeans at all, you will undoubtedly have noticed that the Visual Web Pack extension to NetBeans 5.5 just went final today. This is the culmination of a substantial effort to bring the visual development paradigm of Sun Java Studio Creator to the NetBeans developer community.
Along the way, Creator and Visual Web Pack needed to provide support for simplifying the server side Java code related to a web application developed visually. A perceptive user noticed the fact that this support is very similar to the "View Controller" support provided by the Shale application framework, of which I am the original creator. The answer to this question is (I hope :-) an interesting story.
When I was co-specification lead for JavaServer Faces 1.0 (JSR-127), we recognized that we had a set of conflicting goals ... bring world peace in the web application framework space :-), and get a spec out the door as quickly as possible, because the Java platform was under competitive pressure, especially from Microsoft's ASP.NET and similar frameworks. In order to meet the timeliness goal, we focused primarily on the component level APIs and the low level event infrastructure needed to run a component architecture at all. Supporting the kinds of events that an application level developer would be interested in was (because of the timing) out of scope.
But, we (the expert group) also knew that, if we required all JSF apps to be built on top of the basic request processing lifecycle only, with no possible way to extend it, this would hamper JSF adoption because it would be impossible to meet the functionality expectations of developers used to frameworks like Struts.
Therefore, we chose to provide a set of rich extensibility points in the JSF request processing lifecycle, plus made it possible to plug in replacements for several of the standard functional pieces of JSF. While it is possible for an application developer to do this sort of thing, the extensibility is primarily oriented towards the needs of developers of two kinds of functionality -- JSF component libraries, and application frameworks built on top JSF. The hope was that, because JSF was on track to become a standard API (and part of the Java EE 5 platform), third parties would leverage these capabilities to provide substantially more functionality than the standard itself required. (Side note -- the market's response to this extensibility has been beyond \*my\* wildest dreams -- your eyes will boggle at, for example, the sophistication and capability of Ajax-enabled JSF component libraries that are available today.)
I joined the Java Studio Creator team, as architect, shortly after JSF 1.0 went final. The vision of this project was to build a tool that enabled visual drag-n-drop development of Java-based web applications, in a style that would be familiar to developers used to tools like Microsoft Visual Studio. Using JSF components helped us solve the "visual" part of the equation, because the component architecture was explicitly defined to make this kind of thing feasible. But, what do we do about simplifying the Java code you have to write at the back end? It became clear that we needed to provide some infrastructure for the backing bean that is associated with each visual JSF page.
In the early prototypes of Creator, we saw people take advantage of the fact that the backing beans (called page beans in Creator and VWP) are created on demand using the JSF managed beans facility. They are typically stored in request scope, so you (as an application developer) can count on an instance of the bean getting created for each request that references a particular page. So, the constructor of this bean sounded like a good place to do business logic needed for each request. That solved some problems, but not all of them.
So, in the initial 1.0 version of Creator, we leveraged one of the extension points called PhaseListener to provide application level callbacks that could be used to host application logic. The classic kind of thing app developers face, in an event driven development style, is questions like "where do I put the database query needed to provide the data to populate a JSF table component?". You don't want to do this before processing a postback to the same page. And you don't want to do the query at all if you are going to navigate somewhere else instead of redisplaying the current page. The answer was to hook into the JSF lifecycle, just before rendering happens, and call a
prerender() method that the app developer can use to "pull" data needed out of the model tier to render this view. The promise made to the app developer is that the
prerender() method for a particular page will \*only\* be called if this page is going to be rendered, and \*only\* immediately before the rendering takes place (so, for example, you can change query criteria when processing a form submit, and the query will reflect the latest changes only).
At around the same time, I was paying attention to how the various web application frameworks were reacting to the existence of JavaServer Faces now that it was a standard. In most cases, there were modest efforts to make it possible to use JSF components in the view tier of your application, but each framework opted to keep using its own controller architecture. Nobody at the time noticed that JSF has a simple, quite functional, but very extensible controller that runs the request processing lifecycle for the components -- and this controller can serve as the basis for application level processing too! "What would happen," I asked myself, "if we simply built an application framework as an extension of the JSF controller? The answer was that you get some interesting benefits, even if you do not use the components part of JSF at all:
- Your framework can be much smaller, because you don't need to provide the features that JSF already supports (navigation, validation, pushing updates to the model, and so on).
- Your framework can leverage some very interesting low level capabilities of the JSF architecture, including most importantly managed beans (for create-on-demand services with dependency injection), and value binding expressions (a scripting-like interface for data binding).
Hence, Shale was born. Because the application model supported by Creator and Visual Web Pack was proving very popular, I wanted to support similar functionality in Shale -- plus take advantage of the fact that you can evolve your code faster in an open source environment, so I could feed improvements back into the Creator and VWP codebases. However, using JSF as a basis lets Shale support a bunch of other interesting features as well. The support for these features is separated into fine grained, very small, modules that let you pick and choose just the pieces you need. Currently, those pieces include:
- Application Controller to give you a pluggable way to enforce logic that is applied on every request, similar to the way that action oriented frameworks like Struts support this.
- Clay is an alternative view handler that lets you compose views out of reusable XML or HTML representations of parts of your page, without having to write JSF "components" in Java.
- Dialog Manager that provides support for "conversations" with a user, where the management of the dialog is defined by a state diagram. The manager also supports convenient data storage for each dialog instance, which is thrown away when the dialog completes -- essentially acting like a new scope that lasts longer than a request but shorter than a session.
- Remoting is a library providing support for writing server side handlers for asynchronous Ajax requests.
- Spring Integration supports using Spring to create managed
beans for you, instead of configuring them in a
faces-config.xmlfile. Note that Spring 2.0's direct support for scopes makes this feature not as important any longer.
- Test Framework is a robust set of mock objects for building unit tests for Servlet/JSP/JSF based applications, including tests for your backing beans.
- Tiger Extensions is an add-on library useful if you are running on Java SE 5 or later. It lets you declare things like managed beans, or register JSF components, without having to configure them in an XML file. In addition, you can receive support for things like the View Controller support (see below) based on annotated methods, instead of having to implement a particular interface.
- Tiles Integration incorporates support for the Tiles framework, a popular component of Struts that supports reusable layouts.
- View Controller is the application event callbacks support that is most similar to the application model supported by Creator and VWP.
As you can see, that's quite a list. My dream is that it will soon be possible (since VWP is going to be open sourced) to substitute in Shale's view controller support for the functionally similar library in VWP, and then be able to leverage all of the other Shale features as well, in an application development environment that supports visual drag and drop editing like VWP does.
However, in the mean time, the code bases are not the same.