Sunday, September 30, 2007

David Heinemeier Hansson’s “weblog” Rails tutorial, step by step

David Heinemeier Hansson’s “weblog” Rails tutorial, step by step
July 13th, 2007

I went to look at this famous rails tutorial by DHH, as the creator of Rails is often referred to, in which he debuts Rails by showing how to make a blog app in under 15 minutes. Watching the video (which was actually very awkward because the quicktime controls were outside of my screen area, so i couldn’t pause it), i was struck by how much i prefer tutorials when they’re written down (though having a movie as well is useful). So, i decided to do a written version of his tutorial, with extra explanation, mainly for my own benefit, even though it’s written as if i’m instructing someone. Here goes. By the way, i’m using windows, while DHH uses a mac in the demo. Rails is pretty much platform-independent but i did find a few minor differences so if you’re on windows then this tutorial may be well suited to you.

MASSIVE DISCLAIMER - I’m a noob myself so some of this so-called teaching may be wrong, or at least not properly explained. If you see any errors please let me know!

Before we start, i’m assuming that you have at least a little (like me!) programming experience in some language, and that you have a basic (like me!) knowledge of ruby. If you don’t know (for example) how a ruby hash or a ruby for loop works then go and read the ruby page on wikipedia, it’s a nice quick introduction. That reminds me - Ruby and Rails are both meant to be capitalised but i’m lazy so will tend not to bother. Just in case anyone gets bothered by this sort of thing, i apologise but i’m not actually sorry.

First, install ruby and rails, and mysql, and a web server. The guys from Onlamp explain how to do this pretty well here. I used their recommendation of InstantRails which does pretty much everything you’ll need except perhaps a mysql front end.

So, assuming you’re all set up with the above (you might need to add the ruby/bin folder to your PATH environment variable if you’re using windows), open a command window in your rails working folder (eg InstantRails/rails_apps in my case) and type

rails blog

This creates a framework structure for a rails app called blog. You should see a load of stuff get made. Next, go to the new blog folder (in a new command window) and start your web server. I do this with

mongrel_rails start

Now, your web server should be up and running. Even though we’ve not created a database yet we can still go and see our rails app running, at http://localhost:3000/ in my case (your web server should tell you at what local address it’s running). We see a screen saying “Welcome to rails!” and some other standard stuff that shows us it’s working.

Next, we generate a controller class, called Blog. Do this by typing (at the command line)

ruby script/generate controller Blog

This will make a bunch of new files - it should list them, along with some others that weren’t created because they already existed. Go and open one of them, blog\app\controllers\blog_controller.rb. It contains a single empty class, BlogController, which extends ApplicationController.

Let’s add a new method, “index”. Index is the first page called by any website, and an index method acts as a replacement for the page, which doesn’t exist yet - it will be called when we browse the site.

The method is simply “hello world” - add the following inside the class:

def index
render :text => “Hello world!”
end

Some explanation: “render” is a rails method for rendering web pages. :text is a symbol, which is like a fixed variable name, actually stored as a number (under the hood, though we can view the number as well) for efficiency. Symbols are used in a similar way to variable names, and are denoted by the colon prefix. They have properties of a string as well as the hidden number - printing them simply prints the name minus the colon for example. They’re commonly used as hash keys, and we don’t put them in quotes when we use them. There are various ‘flavours’ of render - for example, we can render a saved html file with render :file => “file path /name”. Some more on render here.

The use of => in this case refers to the creation of a hash pair, which we pass to the method: the hash key is :text and the value is “Hello World!”. In this case, we’re calling the render method, which can take a hash. It then checks the hash for the existence of a specific key or keys, like :text for example, and if they exist then it gets the value associated with the key and does something with it - in this case print to the browser. The above code would be a little more obvious if the {} around the hash and the () around the method arguments weren’t omitted (like a lot of things in ruby, the syntax is optional). In other words, the line could have been written as

render( {:text => “Hello world!”} ) #passing a hash with one k-v pair as an argument

This strategy, of having a single method that takes a hash and analyses its contents to decide what to do, seems to be the ruby alternative to having lots of overloaded methods that take different arguments, as in Java or C. I guess that because of ruby’s dynamic typing, it’s hard to differentiate methods based on arguments. BTW, the hash must be the last parameter in the list, to allow an arbitrary (including zero) number of key-value pairs to be passed to the method and treated as belonging to the same hash.

Anyway, let’s get on with it. Save blog_controller.rb, go back to the browser and go to http://localhost:3000/blog or your equivalent. The text “Hello world!” should now be there.

As DHH explains, having the controller print to screen isn’t really the right way to do things - rails uses the model-view-controller pattern, and anything to do with displaying should be done in the “view” section of the app. You probably noticed how rails created controllers, models, and views folders in the app folder (the app folder is where we do our work). Remove the hello world line from blog_controller.rb (leave the empty index action for now) Go to the views folder. Rails uses a special kind of file to generate html for the browser to read, called rhtml files. These are basically html in which we can embed chunks of ruby code inside <%= %> brackets: when rails runs the rhtml files are used to make html, with the ruby blocks filled in with the results of the ruby code.

Make a file called index.rhtml in the app/views/blog folder - this is a template. Write “Hello from the template!”, save it, then go back to the browser and refresh. Instead of the ‘index’ action, the browser is now loading the index page (we didn’t have one before), and we see our message. We can go back and delete our index action completely now - the page doesn’t need the action to work.

Now let’s get serious - let’s get some database action in here. If you look in blog\config\database.yml you can see that rails has already set up the config for connecting to a DB called blog_development (we’re just worrying about the dev version of our software for now), on a DB server. I’m using mysql like in the onlamp setup instructions, you should be able to change the details for your own DB if it’s different (enter your username and password for example, if you changed your user name or don’t just have a blank password). But, we don’t have a DB called blog_development yet, so let’s make one.

DHH does this by hand, using a DB front end, in onlamp they use sql script to create the DB and also to add the tables, columns etc. Doing it by hand might be better to understand what’s being done, if you’re not confident in SQL then you’ll need a DB front end for this. If you’re using mysql then HeidiSQL is a decent free front end. Anyway, make a new database called blog_development.

So - the purpose of the DB is to model and store our domain entities, which we’ll mirror with our software classes. The first entity we’re going to model is a post, which consists of a title, some text, and a date. Ultimately we’re going to have a class in our models folder called Post, and one of the many cool things about rails is that if we name things right, then our ruby classes automatically map onto the database structure. The way we name things right is to have the name of a database table being the plural of the class it represents. So, in this case we should call our table “posts”. (Rails is pretty clever with the pluralisation - for example it knows that ‘people’ is the plural of ‘person’. We can override this automatic mapping if we want to , by explicitly saying “this class maps to this table”. Though i’m not sure how to do this.)

(POSTSCRIPT - i’ve since learned about overriding the rails defaults for table and field names, etc. For example if we wanted our Post class to map to a table called blogposts, which had a primary key called bp_id we could have, at the top of the class definition

class Post <>My wonderful weblog

Scaffolding was also placed in the view files, making some default display code for us. Now we’re going to chop some of the scaffold-created stuff out and replace it with our own html and ruby code. First, chop out the first table row section, which is the column titles. Have a look. Next, we make each post title a header (h2), that links to the post. After
<% for post in @posts %>
add

<%= link_to post.title, :action => ’show’, :id => post %>




Let’s try and break this ruby code (in red) down a bit:

for post in @posts #for every object (called ‘post) in the instance variable @posts (which points to an array of post objects, pointing into the DB), do the following:

link_to post.title, :action => ’show’, :id => post #equivalent to
link_to(post.title, {:action => ’show’, :id => post} ) #create a link that is represented by the post title, calls the action called ’show’ when clicked, and passes the ID of the post to the DB to retrieve the body.

Note that in the first ruby block, there’s no =. This is because we only need <%= on lines that return something. Purely structural code like a for expression only needs <%. Have another look in the browser. Next, show the post body beneath each title: add this line before the closing div tag:

<%= post.body %>



It’s easy enough to see that this is literally just displaying the body of the current post (as we cycle through the full list of posts). We can also see that the show/edit/destroy links are now cut off from the posts they correspond to, so let’s get them back in the same div element as the new title and body. (Actually we only need edit and destroy, as we show a post by clicking on the title now, which is more intuitive anyway). We put edit and destroy in their own paragraph, in small text, with the time of creation as well. In addition, since we’ve now got a big continuous list of posts, there’s no need to split them onto pages, so we can delete the previous page/next page lines.

After doing all that stuff, list.rhtml should look like this:

My wonderful weblog



<% for post in @posts %>

<%= link_to post.title, :action => ’show’, :id => post %>


<%= post.body %>



<%= post.created_at.to_s %>
<%= link_to ‘Edit’, :action => ‘edit’, :id => post %>
<%= link_to ‘Destroy’, { :action => ‘destroy’, :id => post }, :confirm => ‘Are you sure?’, :method => :post %>




<% end %>

<%= link_to ‘New post’, :action => ‘new’ %>

Note - i had one problem with DHH’s code: the line where we convert the timedate object into a string, (<%= post.created_at.to_s %>) he was passing it the symbol (:long). This broke it for me, i had to take out long and just call the to_s method with no parameters. Then it was fine. I don’t know what passing :long to the to_s method is supposed to do. My code shown above has the (:long) taken out. If anyone can explain this please add a comment.

Next, DHH shows how to list the posts in reverse order, ie most recent first: simply go to the for block in list.rhtml and change posts to posts.reverse. This demonstrates (i guess) that when we get the rows out of the DB they come into ruby as array elements, where each element is another array (or maybe a hash?).

More polishing: at the moment our body is just plain text: no italics or bold. We add this functionality in via the method textilize, which uses the same rules as the common markup language textile, in which we show bold with *bold text* and italics with _italicised text_. textilize just takes any block of text, which is what we have. Note that this is happening in the view. The database doesn’t know anything about bold or italic text - the view (in list.rhtml in this case) is translating the *s into bold markups. So, where we have post.body at the moment, we pass this as an argument to textilize:

<%= textilize(post.body) %>



Having said this, rails can’t find the textilize method when i try it: after a quick look on the net, i found that it needs to be added via a ruby gem before use (it’s part of the redcloth gem, which is kind of what packages are called in Ruby). So, if this doesn’t work for you either, just change it back to how it was before. That’s what i did (gems ain’t the focus of this tutorial).

(POSTSCRIPT - It’s actually very easy to add this gem: Just type “gem install redcloth” at the command line and then restart the web server. I have had some problems with other gems, such as rmagick, though, whose windows versions are a bit complex/broken)

Next, we’re going to look at partials, which are blocks of code that can be reused by different files. Open blog_controller.rb. We’re going to change the list action to just find all posts, instead of trying to seperate them into ten per page or whatever:

def list
@posts = Post.find(:all)
end

Then, go back to list.rhtml. Cut out all the contents of the for block, and put them into a new file, called _post.rhtml. This partial is going to be our ‘post displaying’ code. Make sure the name has the underscore, as this is used to denote partials. Now, _post.rhtml is a partial that represents the display for a single post. We can now use this in various places to make sure that a) we have a consistent style and b) we don’t repeat ourselves. “Don’t Repeat Yourself”, or “DRY”, is a good design pattern for any language and is a ruby and rails mantra.

The first place we need to use it is the place we just chopped it out of! Go back to list.rhtml and remove what’s left of the for loop completely. Instead, we have a single call to the render method. As with our “hello world” code earlier we pass render a hash, but in this case the hash has two elements: one has the key :partial, and points to the partial in question, simply called ‘post’ (it knows to add the underscore when looking for a partial), and the other has the key :collection, which points to @posts.reverse. So we’re saying “do the partial for every item in that collection”.

So, list.rhtml now looks like this:

My wonderful weblog



<%= render :partial => “post”, :collection => @posts.reverse %>

<%= link_to ‘New post’, :action => ‘new’ %>

Now refresh the list page - it should look exactly the same. Of course, partials are only worth doing if we use them in more than one place, so lets do that now. In the browser, click on a item title to go to the ’show’ page. It still has the old default looking style: we’re going to fix it to use the partial as well. Go to show.rhtml, delete the for block from there and replace it with a line that’s almost the same as the one we used to replace the for block in list.rhtml. The only difference is that instead of displaying a whole collection of posts, we just want to show one, the current one, ie @post. (we don’t reverse it because it’s a single post - reversing it makes no sense). So we change :collection to :object, and @posts to @post -

<%= render :partial => “post”, :object => @post %>

Now refresh the show page in the browser - it should have the new template.

Next - adding comments. Comments are a whole new type of object, so we’re going to have to change the model and the DB. Let’s do the model first. At the command line, in the main blog folder, type

ruby script/generate model Comment

Among other things, that will have created a new model file, comment.rb. (this will map automatically onto a table called “comments” in the DB but we’ll get to that in a bit). Open comment.rb.

Next we model the relationship between our classes: a comment belongs to a particular post instance, and we inform rails of this by writing

belongs_to :post

inside the Comment class definition. This relationship is two way - a post can have many comments. So, we need to modify the Post class definition as well, with

has_many :comments

Some nice self documenting code there. Ok, now we need something to work with - let’s go to the DB and make a new table called comments. Like with posts, make the primary key field called ‘id’, set up the same way as before. Next, add a field called body, of type text. The other component is something to link a comment to a post - a foreign key in other words, a reference to an id from the posts table. As you might expect, rails has a convention for foreign key names - it’s foreigntable_id, or “post_id” in this case. If we follow this convention we don’t even need to link the tables together - rails knows what we mean.

At the moment, we don’t have an interface to add comments, so we’re going to create one in the database to use as an example/test. So, go to the data page of the database (if you’re using heidisql you might need to refresh the table view first) and write some entries into the fields: use an id of 1 and make sure you use a post_id that exists in the posts table. Swap between table and data view to make sure your data got saved ok.

Ok, now we’re going to work out how to display the comments. The main (perhaps only) place for comments to appear is on the ’show’ page, so let’s look at show.rhtml. After the post, and the edit/back links, we’re going to list all the comments. This is another for loop, along the lines of “for every comment, show the comment”. Because of the conventions we followed, rails lets us get at all the comments belonging to a post simply by writing @post.comments. We then make a for loop out of this as follows, showing the comment body for each post, inside the loop.

<% for comment in @post.comments %>
<%= comment.body %>
<% end %>

That’s worked, but the comment is simply listed on the same row as edit/back, which looks bad. So let’s add just a little html formatting: a “comments” heading before we list the comments, and a line break (
) after every comment. So, show.rhtml now looks like this:

<%= render :partial => “post”, :object => @post %>

<%= link_to ‘Edit’, :action => ‘edit’, :id => @post %> |
<%= link_to ‘Back’, :action => ‘list’ %>

Comments



<% for comment in @post.comments %>
<%= comment.body %>


<% end %>

Next, lets let the user add comments. We’re going to do this with some form components that we write straight into show.rhtml. The code we’re going to write is pretty much the same as already exists in _form.rhtml and edit.rhtml, in the views/blog folder. We call form_tag with a hash consisting of the key “:action” and the value “comment”, and the key “:id” and the value @post. In other words, when we submit, we’re making a new comment, and also passing through the id of the post we’re looking at when we write the comment, so the DB knows which post we’re commenting on.

Then we’ve just got a text area which goes into body and a submit button. Finally we close the form with an html end tag. So, the following goes at the bottom of show.rhtml:

<%= form_tag :action => “comment”, :id => @post %>
<%= text_area “comment”, “body” %>

<%= submit_tag “Comment!” %>


OK, refresh the show page in the browser, and you should see a new text box and a submit button, labelled “Comment!”. Enter a comment and hit the “Comment!” button. Whoops! (sorry, couldn’t resist it). Rails doesn’t yet know what to do with this thing we just created, and we get an error message.

To fix this, we need to make an action called “comment”. This makes sense considering above that we told the form tag that we were calling an :action called “comment”. So, we do this in the controller. Remember the rules of MVC - the model is our ‘business logic”, ie what holds what, what connects to what, etc. The view handles everything to do with displaying the data to the user. The controller handles user actions, and making a new comment is a user action (the interaction happens, ie the form is displayed, in the view, but as soon as the user submits, it’s the controller’s job to handle the action).

(Postscript - i’ve since discovered the ’skinny controller/fat model’ principle, which says that as much functionality as possible that relates to an object should be moved out of the controller into the model class for that object. The controller, then, should really just act like a manager - telling things what to do but letting them actually do the work. Under this principle, the below code is actually fine, since we’re doing about as little as we could possibly do anyway. But if the process of creating a new comment was any more complicated, then we should really call a method in the Comment class, from the controller, to do it, then, again back in the controller, decide what to do next, eg redirect to the show page for the commented-upon article. So remember - the controller’s just a manager, and it should be a lazy one at that.)

So, open blog_controller.rb. This is perhaps the most complicated bit of ruby coding we’ve done yet, so i’ll go through step by step. If you see any errors in my explanation please let me know.

Before we start, a brief diversion to talk about parameter passing in rails, and ‘params’. ‘params’ is the default way of passing through parameters to a method, and it’s a hash. That means it contains hash keys, which as we’ve seen consist of a key and a value. Usually, the key is a symbol, ie starts with a colon. We can pass any (and as many) keys we want through, but the method is normally going to be look for some specific key or keys, denoted by name, which is a symbol like i said. When we pass the key through we don’t have to explicitly put it in params, but we need to look in params for it at the other end, ie inside the method, which we do in the standard square-bracketed hash-accessing way.

So, for example, if we wanted to write a method called ‘hello’ which takes a name and returns “hello name!”, then the typical rails way would be

def hello
#in ruby the last evaluated statement is returned by default
#so we can omit ‘return’ and just have the statement
“hello #{params[:name]}!”
end

Now, the person using this method needs to know to use the symbol “:name”. If they try to call it with hello(”max”) then it won’t work. So, the name of the symbol presents a bit of inflexibility and requires a bit of knowledge of the method. Generally, though, naming conventions make it easy to remember the names of the symbols and in lots of other ways it’s great: for example, the order in which you pass the parameters in a given hash is not important - a big plus. Anyway, to call the hello method we would say

hello :name => “max”

BTW, in case you were wondering, #{} is a ruby mechanism: the contents of the brackets is evaluated and then converted to a string. They’re commonly used inside a string as an alternative to the

puts “blah ” + var1.to_s + ” blah blah ” + var2.to_s

javaesque way of doing things - we’d instead write the above as

puts “blah #{var1} blah blah #{var2}”

Anyway, that’s enough diversions into ruby. Let’s get on with our rails app!

In BlogController.rb, make a new action called comment. The first line inside the action is this:

Post.find(params[:id]).comments.create(params[:comment])

Breakdown:

Post.find(params[:id])
This is going to use the class (ie static) method find, using the :id passed through from the form (remember the second key in the hash?).

.comments
Then (all on the same line), we take that post and access the comments array associated with it.

.create(params[:comment])
In that array, we create a new comment, passing through :comment (which is the comment we just created). This is a lot of work for one line - in this respect Ruby can be a bit scary at first, like your first driving lesson.

The next line stores (not sends!) a message to the user that their comment worked.

flash[:notice] = “Added your comment.”

‘flash’ is a temporary store in rails. We can put stuff in there, and if it’s not used before anything else happens, it’s deleted. The next time the view displays anything it will check if there’s anything in the notice field and if there is, display it. This is an example of controller-view separation: the controller doesn’t directly display anything: instead it’s stuck a postit on the view’s desk.

Next line:

redirect_to :action => “show”, :id => params[:id] #equivalent to
redirect_to ( { :action => “show”, :id => params[:id] } )

By now we should be getting used to this hash-passing syntax. Without being familiar with the code of the redirect_to method, we can imagine a general logic of:
redirect to what? An action.
Which one? “show”
Do you want to pass anything along to that? yes please, the :id, so we know which post to show.
And a value for that please? the :id of the post we’re currently looking at, that was passed through to us in params from the thing that called this method.

In other words, “call show for the current post”.

(POSTSCRIPT - just an aside, but the url in a rails app is kind of a translation of the redirect_to action: after the main domain name (or localhost:3000 or whatever), we have the name of the controller we want, then the name of the action, then the id to pass to the action. so

localhost:3000/blog/show/4

is equivalent to

redirect_to :controller => “blog”, :action => “show”, :id => 4

(if we don’t specify a controller, btw, it defaults to the current controller)

That means that your choice of controller for any action will affect the url that the user sees - so if you want to have a nice bunch of intuitive urls, you might need to think about reorganising your actions between your controllers, or making a new controller for some actions, or maybe just renaming your controllers or your actions. At the very least, think about your controller and action names before you name them - they’ll show up in your url, so don’t call them foo and bar! Having said all that, there might be a way to change the url that is displayed to be something other than the controller/action names. Please comment if you know any more about this!)

Here’s the complete comment action for blog_controller.rb

def comment
Post.find(params[:id]).comments.create(params[:comment])
flash[:notice] = ‘Added your comment.”
redirect_to :action => “show”, :id => params[:id]
end

Once you’ve added those (and saved), refresh the browser and add some comments. If you get an error message about it missing an ID, go back to the list screen, select the post again, then add the comments. It should work now.

That’s our blog app! Nice work.

In the video, DHH goes on to talk about unit testing and the rails ‘console’, but if you want more practise building stuff in rails, try finishing the onlamp tutorial i referred to earlier: Rolling with Ruby on Rails Revisited. Bill Walton and Curt Hibbs’ app is a little more complicated, but the ruby code should make more sense after working through the one we just did. If you want an introduction to unit testing in Rails (and you should, since there’s no compiler safety net in Ruby, and unit testing is definitely becoming the ‘way to code’) then watch the rest of the movie, which briefly introduces rails testing (as you might be expecting by now, rails sets up a load of tests for you automatically). If you want to really learn about tests though, look at some of the links at the bottom of this post.

OK, that’s it for this tutorial, i hope it’s been as educational reading this as it was for me to write it. Please mail me with any errors or suggestions. Thanks for reading!


FROM ::
http://nubyonrails.wordpress.com/2007/07/13/david-heinemeier-hanssons-weblog-rails-tutorial-step-by-step/

Ruby On rails Vs Java

Ruby On rails



FROM
http://www.rubyonrailsexamples.com/

Einstein-The-Bird

Friday, September 28, 2007

RE: What Web Application framework should you use?

Tim O'Brien has an interesting post titled What Web Application framework should you use?. The first thing I noticed about this post is the permalink. It looks like he started with "Isn't Rails supposed to change...", which makes me wonder what the rest of the title was. In this post, he rags on Java Web Frameworks and the lack of a clear path for choosing one. He ends up predicting that many will stick with Struts 1.x (poor bastards) and those that aren't tied to Java should move to Rails. I don't have a problem with folks moving to Rails, but I would like to comment on the Java Web Framework space and Tim's comments.

He says:

Prediction: The confusion over what is happening over at Struts is going to discourage people from continuing to use it. The Struts team did the right thing in recognizing that Struts 1.x was a dead-end, but that project needs a single public message. Is it Struts Action or is it Struts Faces? Or is it two frameworks capitalizing on the Struts brand name?

I think what is going on in the Struts project is definitely two frameworks capitalizing on a brand name. That was a concious choice on the project's part when they chose to start creating sub-projects. The interesting thing about Struts Shale is it's largely a prototype for JSF 2.0. Furthermore, it was rejected by many Struts developers as becoming Struts 2.0. Why? Because JSF sucks. Especially when used with JSP - which is what most folks are doing.

JSF continues to be the most over-hyped under-used framework in Javaland. If you read the blogs of first-time users, you'll find many complaints and issues on how things work. Granted, most of these problems are with JSP and the implementation, but still. If I were in charge of JSF, I'd dump JSP altogether, bundle Facelets with it and allow more flexible page navigation (including controller-to-page). Don't get me wrong, I like the ideas behind JSF, I just don't like the implementation (or the fact I have to wait years for things to be fixed in the spec).

That being said, I've yet to meet an unhappy WebWork fan. If you find someone that still likes Struts, ask them if they've used WebWork. Chances are they'll say no. As far as Tapestry is concerned, the learning curve is too high. It's been rejected time and time again by my clients because of the learning curve. Are they going to fix this? Yep, they're going to re-write the whole damn thing - again! Every major point release of Tapestry throws backwards-compatibility out the window. Furthermore, I've heard once you get over the learning curve, it's a joy to work with. I've also met people at conferences that've used it over a year and say they're still struggling with its concepts.

Spring MVC - I wish I had bad things to say about it, but I don't. It (obviously) has the best Spring integration, but I've found WebWork much more pleasurable to work with. Sure, Spring has a ThrowawayController, but with a name like that, you can tell it's a second-class citizen.

Inspired by Tim's post, here's my prediction:

Struts Action 2 will be the best choice for developing Java-based web frameworks. Not only does it support JSF, but it's easy to learn, test and use. Furthermore, it seems to be the most often used framework in major software products and web sites.

How's that for a clear message? Struts Action 2 is the shiznit, now let's get back to developing applications.

Disclaimer: This is my opinion with a lot of stuff thrown in to get folks riled up. I've never put a JSF, Tapestry or Spring MVC application into production (except for AppFuse of course), so most of my opinions are likely without foundation. In wonder how many applications Mr. O'Brien has put into production with these frameworks? Posted in Java at Jun 20 2006, 08:32:41 AM MDT 48 Comments

Comments:

Bingo, the successor to Struts 1.x (which, honestly, I see many sticking with these days) is Struts Action 2. But, I really convinced that a lot of the confusion in this space comes from mixed messages from the Struts group. C'mon is it Struts Shale or Struts Action, IMO, it can't be both...

JSF has some great ideas. Hightower's piece really frames the concepts well, but as soon as you start trying to put JSF into practice you either end up in the tar pit that is Sun's Java Studio Creator or in MyFaces, which is usable but still has a steep learning curve.

Shale to me seemed like a premature distraction from Struts 1.x - I really did seem like Craig started work on Shale almost in a vacuum.

But, it's funny, mention Rails anywhere and you get some really riled up Java developers. :-)

Posted by Tim O'Brien on June 20, 2006 at 08:59 AM MDT #

Matt, thank you for finally taking a definitive stance on this issue and giving us your opinion without holding anything back. Your contributions with appfuse/equinox in my opinion make your opinion on web frameworks one of the most valuable in the Java community. That being said, I do find it a bit amusing that you support all those other web frameworks in appfuse when you obviously dislike them.

One small question though. Webwork2 is basically dead as the team has moved onto the Struts Action project. Does it not worry you that WW2 won't evolve anymore and migration path to Struts Action is probably non-existent?

Posted by Wayland Chan on June 20, 2006 at 09:13 AM MDT #

Great post Matt. My only complaint is that I *wish* that Tapestry and JSF were not referred to as the only Java component web frameworks. Like you said, Tapestry is being constantly rewritten, and I have yet to fully get into the Tapestry "groove". JSF is pure crap unless you have some fancy IDE to autogenerate thousands of lines of XML.

But Wicket has surpassed every Java component framework I've tried. So much cleaner than Tapestry with a definate OO feel to it. It's very similar to Swing programming, which in my mind is a good thing.

It's a shame you don't drop Tapestry and incorporate Wicket into AppFuse. Tapestry may be the "leading" component framework right now, but I have yet to see a newcommer just "pick up" Tapestry without a whole lot of training. This kindof defeats the whole appfuse purpose of getting up and going as quickly as possible. Wicket seriously took me ten minutes before I was completely productive, and I haven't turned back since.

http://jroller.com/page/wireframe?entry=web_development_done_right

Posted by Ryan Sonnek on June 20, 2006 at 09:23 AM MDT #

> Webwork2 is basically dead as the team has moved onto the Struts Action project. Does it not worry you that WW2 won't evolve anymore and migration path to Struts Action is probably non-existent?

No, this doesn't worry me at all. WW2 is Struts Action 2, so it will continue to evolve. With developers like Don, Ted, Patrick and Crazy Bob - I'm not at all worried about this project's ability to improve.

As far as a migration path, it should be as simple as changing a few filenames and package names. I plan to start replacing AppFuse's WebWork version with SA2 in the next few weeks. Then I'll start showing others how to do it.

Posted by Matt Raible on June 20, 2006 at 09:29 AM MDT #

Great post Matt. Its about time someone starts to take a stand on these kind of issues.

My problem with the whole Java framework discussion is that JSF is now the official specification for J2EE Web frameworks. This seems wrong, since we are seeing that there a number of good approaches to writing a component based framework. It also creates a FUD scenario where teams select JSF, because it is the "standard" and will have better "vendor support".

The other problem, IMO, is that an action based framework is the more appropriate choice for many applications. I would also go as far to argue that an action based framework should be used if the team contains multiple beginner level developers, while component based frameworks are better left to very experienced development teams. A good direction for this discussion to go would be to talk about the distinction between action and component based frameworks and the advantages to using one over the other.

I think it will be interesting to see if Ruby has these kind of issues in a year or so and how the Ruby development community deals with them.

Posted by Rob Breidecker on June 20, 2006 at 10:49 AM MDT #

> It also creates a FUD scenario where teams select JSF, because it is the "standard" and will have better "vendor support".

I absolutely agree with this. The funny thing about JSF vs. Tapestry vs. WebWork (or XXX web framework) is you're likely to hire the same hot shots to help you implement an application with it. Who are these "hot shots"? Independent consultants who have experience putting a real application into production using the technology.

You're not going to hire Oracle, IBM or Sun (or JBoss for that matter) to help you learn and use JSF - you're going to hire somebody that's done it. So from a hiring perspective, there's lot of JSF positions, but I doubt there's a lot of truly experienced developers out there. Except for Hightower of course, but I think he likes banging his head against the wall. ;-)

Posted by Matt Raible on June 20, 2006 at 11:01 AM MDT #

Damn, I don't get a mention in the developer's list? ;-) Thanks for the vote of confidence in SAF though...

Posted by Jason Carreira on June 20, 2006 at 11:05 AM MDT #

MATT!!!!! ;) Seam is where it's at!!! Awesome, Awesome, Awesome, Awesome. Hey, did I mention it was awesome? Trully reuseable components, finally, that I can use on the web end and as an SOA without duplicated effort! If I was a songwriter, I'd write a song about Seam right now. W00t! ;)

Posted by Dan Hinojosa on June 20, 2006 at 11:59 AM MDT #

If you want to use a simple, event-driven framework, try Click http://click.sourceforge.net. It is simple and very easy to learn. Takes concepts from Tapestry and just makes it easy.

Posted by John Christopher on June 20, 2006 at 12:21 PM MDT #

> If I were in charge of JSF, I'd dump JSP altogether ...

If I were in charge of JSF, I would have built it as JSP 2.0 from the beginning. Seems that JSP & JSF will finally unite in JSP 2.1 spec, though the spec still tries to kick JSP out of the nest by limiting EL features for pure JSP pages.

If you are/were Windows developer, the example is right here: real-mode Win16 -> protected-mode Win16 -> Win16 + Win32s -> Win32 + DOS7 extensions -> pure Win32 -> Win32 + .Net -> ...

A developer of a Windows app can still build a Win16 app, deploy it on WinXP and it will work. _This_ is an example how to ensure API compatibility, how to keep users while improving and extending the API. JSF did not go this path initially. Well, I guess Craig M was not 100% sure that JSF would be accepted as default J2EE view technology when he started developing JSF...

> I like the ideas behind JSF, I just don't like the implementation

The ideas behind JSF are collectivelly known as ASP.NET

> Because JSF sucks.

Is it actually your opinion, or you just quoting a link? ;-)

> Struts Action 2 will be the best choice for developing
> Java-based web frameworks. Not only does it support JSF,
> but it's easy to learn, test and use.

http://marc.theaimsgroup.com/?l=struts-dev&m=115082440032215&w=2

Rob Breidecker:
> I would also go as far to argue that an action based framework
> should be used if the team contains multiple beginner level
> developers, while component based frameworks are better left
> to very experienced development teams.

I would argue exactly the opposite, especially if there are easy-to-use GUI tools and the build process is simple.

Posted by Michael Jouravlev on June 20, 2006 at 03:05 PM MDT #

"I would argue exactly the opposite, especially if there are easy-to-use GUI tools and the build process is simple. " Yeah, but there aren't, so his point is very valid. I also question the design of any framework that requires a fancy GUI tool to make it not suck.

Posted by Sam on June 20, 2006 at 03:23 PM MDT #

"I also question the design of any framework that requires a fancy GUI tool to make it not suck." Visual Basic? Borland Delphi? ASP.NET?

Posted by Michael Jouravlev on June 20, 2006 at 03:42 PM MDT #

Hi, great post Matt, yes, everybody sould try Click! I am moving from WW2 to Click. Even the more inexperienced trainee can learn click in few hours... I have created custom componentes with click, and is just awesome how much html click generates automatically for me :-) The event listeners makes your life easier, and it also uses convention over configuration. And click is very fast. It is not just a new web framework, it exists a long time (see the roadmap)... "Webapp framework blog" - Comparison of J2EE web application frameworks http://rlecheta.com.br/viewBlog.htm

Posted by Ricardo on June 20, 2006 at 06:29 PM MDT #

How can one struggle for years with Tapestry, Matt? I guess if one never wrote a line of Tapestry code... The big Tapestry learning curve is a complete myth. We hired a high-school graduate and within two-three weeks he was creating Tapestry components. You know, Matt, you've been receiving very kind support on Tapestry mailing list as well... Serge

Posted by Serge Dubov on June 20, 2006 at 06:32 PM MDT #

We found http://click.sourceforge.net/

Click passes our 10-minutes test. A new developer, student, able to use the framework within 10-minutes of reading http://click.sourceforge.net/

Why we like it:

  • Simple and intuitive web presentation model
  • Click is JSP and MVC Free; it uses Controls that are far more productive rendering tools with integrated html and JavaScript as needed
  • It uses Velocity

Worth looking at a different and simpler J2EE web application framework

Posted by J.F. Zarama on June 20, 2006 at 07:31 PM MDT #

Matt, I think your criticism of Tapestry having too steep a learning curve is a bit shallow. It does take some time to become proficient in Tapestry, but it is more than justifiable based on the unique capabilities of the framework. On balance, I have found the learning curve breaks even after a few weeks, and the returns grow from there. Tapestry sets a very high ceiling as to what can be accomplished. We have converted a sizable application from Struts to Tapestry and are seeing significant return on our invesment in both time and developer morale.

Posted by Ben on June 20, 2006 at 09:16 PM MDT #

The practice in which each major revision of Tapestry is not backward compatible is simply not something I want to deal with after making the investment to learn it. Even the documentation on the site is a mish-mash of version 3 and 4 docs. The authoratative book, Tapestry in Action, written by Howard Lewis-Ship (Tapestry/Hivemind mastermind) is outdated as it is for Tapestry 3. Hivemind, no comment but you should probably learn this if you want to realize Tapestry's full potential. Another mountain to climb on that learning curve. Even if you are willing to deal with all these obstacles, is it a wonder that the adoption rate is slow when the development team ostricizes it's user base with non-backward compatible updates? I learned Struts back before 1.0, I will admit I may not know all the latest features in Struts 1.2 but I can still develop in it. There is alot of value in that when you are trying to grow a user community.

Posted by Wayland Chan on June 20, 2006 at 10:32 PM MDT #

I worked with Tapestry for a while and built a couple of small apps in it. The problem I had with it was the page rewind thing was just too wacky and the documentation was not particulary up to par. I think tapestry tries to mix too much stuff in with the view. For instance the "for" tag in the template language interating over components creating multiple seperate instances of them is not the most elegant thing in the world. I like how JSF builds these dynamic components in Java code which seems to make more sense. Hivemind is not that well documented either and led to a lot of confusion. I also find it much easier to build wireframes out without code in JSF than in Tapestry. I guess the final nail in the coffin was the lack of interest at JavaOne and hearing from many developers at the conference who said that they were quite happy with JSF.

So I ate the JSF burritto and I don't see what everybody's problem with JSF is? It's a lot of work to understand it but that's because it's trying to do a lot more. I would recommend "Java Server Faces In Action" if you really want to "get it" and read the whole thing otherwise you'll fight the way JSF wants you to do things and have a hard time.

My biggest problem with JSF right now is that although it is good for web applications (where one logs in and manipulates and creates data), it is still not a great fit for Web Sites (where there is a lot of casual browsing going on) mostly because of the POST only nature and complex maintenance of the user's current view state. This makes it difficult to do view level caching, search engine optimization, have permalinks and otherwise deal with random navigation. I am trying to figure out a good web framework for this task and I want something less primitive than struts. Maybe I'll try the Spring Framework as it seems to be the lesser of the evils right now.

Posted by Justin on June 21, 2006 at 12:02 AM MDT #

I did not see stripes mentionned in this thread (it is mentionned in the original post from Tim and in the comments over there). You should check it out: it is tight, clean, well documented, and easy to learn.

The zero-configuration programming model is a joy, and should you try it, I bet you will enjoy a lot of these "wow, this is too easy!" moments. I still do, which is a testament to how good Stripes is and how "ancient" (i.e. "crippled") Struts is.

imho, it beats all the other contenders in the pure mvc space: struts, webwork2 ("I coulda been a contender" but missed the opportunity, harder to learn and use), spring mvc ("with great power comes...lots of XML!"), tapestry (too alien, to steep learning curve).
The others are pale imitators (strecks, vraptor) or not radical enough. I looked at Click's documentation and I did not experience the "wow!" feeling I had when I looked at Stripes' the first time.
When it comes to Struts2, well...Who understands the story there? I certainly don't: is it going to be Shale, Struts 2, Struts Action, WebStruts or StrutsWork ? ;-)

As for JSF, it is not worth the effort until 1.2 and facelets come out and fix it (hopefully...). As it stands now, you need to bring in Seam to make it productive - not exactly lightweight...

I urge everyone to take a good look at Stripes

Posted by Renaud Bruyeron on June 21, 2006 at 01:14 AM MDT #

Simply put the answer is somehow very simple: "same as till now. N (though, slightly changing) Java web frameworks, all trying to solve more or less the same problem". Who is gonna win from this? IMO, all consultants out there that will have more and more apps to fix and make 'em usable. Their life will be hard, because they will need to know more frameworks, but this will keep their incomes at a high level. I think, and once again this is just my opinion, for Java web frameworks is too late to unify. There is already too much effort behind all of them.

Another WebWork/SAF developer (that didn't make it to the list ;-),

./alex
--
.w( the_mindstorm )p.

Posted by Alex Popescu on June 21, 2006 at 09:01 AM MDT #

I'm definitely in the Stripes camp. I've been using Struts for years and never really liked it. I've tried JSF on a few occasions and abolutely loathe it. After reading the Stripes docs I simply couldn't pass it up. It is so simple, so elegant, and so straight-forward that after a little testing I immediately adopted it as my framework of choice. The other Java developers at my company had the same reaction and are now using it in their projects, too. If you're looking for a good framework, you really should check out Stripes.

Posted by Ben Gunter on June 21, 2006 at 09:16 AM MDT #

I have to agree whole heartedly with the comments given regarding stripes. I have done work with most of the main stream frameworks out there today. After much research and usage with struts, webwork, spring, tapestry, rails, and jsf, the only one that even piqued my interest was webwork. I ended up giong with stripes due to the fact that it is sooooo much simpler than anything out there. It has all the functionality and power I need and all programmers can understand it and be writing code in a couple hours not to mention it was a piece of cake to convert all of that old struts code. If you haven't given it a look, you should at least do that before you think "Just Another Web Framework". Make web coding fun and simple again. http://stripes.mc4j.org/confluence/display/stripes/Home

Posted by Nic Holbrook on June 21, 2006 at 09:49 AM MDT #

I have two projects on Tapestry3 in production. Tapestry is an excelent framework. Yes, it's little more complicated than Struts for simple applications, but very good for complex applications with many components.

Posted by Brychta on June 21, 2006 at 12:00 PM MDT #

We shall see my chick-a-dees...The documentation is currently more than a little lacking, but as with all things this too shall pass. All of my energy is currently focused on more important items (to myself), but when we release whatever those are in the next couple weeks I'll turn my attentions to these "learning curve" issues. I like good challenge :)

Posted by Jesse Kuhnert on June 21, 2006 at 05:23 PM MDT #

I am also among the Stripes camp after having used Struts for years, and heard stories about Spring MVC usages. The transition from Struts to Stripes in a corporation is also straight forward and cost-effective. It is by far the simplest but powerful framework that are not commonly seen in the Java world. I have also written up possible ways of integrating Stripes with other existing frameworks to simplify Java web-based application development.

Posted by Ray Tsang on June 21, 2006 at 07:22 PM MDT #

I've been extremely impressed with what I've seen of Stripes. I've spent some time converting an app from Spring MVC to Stripes and the reduction in the codebase & the increase in readability is remarkable. It also integrates very happily with a Spring app framework (my app now uses Spring & Hibernate with Stripes for the presentation layer). It's great to be able to properly leverage the power of Java 5 annotations to make the code simpler and avoid the XML config soup that other frameworks tend to lead you into.

Posted by Rob Fletcher on June 22, 2006 at 02:27 AM MDT #

I havn't really wanted to get involved with this debate as it just sounds silly if the framework creator is posting in the actual threads. Still, since this post is outside of that main one I guess there is no harm .. I do encourage people to give Grails a go (http://grails.org) we'd certainly appreciate the feedback if anything else. I would particularily be interested in what Matt, Jason and Patrick think about it given their experience with JVM-based frameworks. PS I recommend the 0.2 snapshots if you do try!

Posted by Graeme Rocher on June 22, 2006 at 09:56 AM MDT #

[Trackback] There are a couple great blog posts summing up the state of Java Web Frameworks right now in the Summer of 2006. First, let me say that I believe things will be drasticly different by this time next year. I...

Posted by Erik's... Hmm... on June 22, 2006 at 01:32 PM MDT #

A short entry about Stripes, provoked by so many comments in here: http://themindstorms.blogspot.com/2006/06/stripes-sounds-cool.html. ./alex
--
.w( the_mindstorm )p.
---
(http://themindstorms.blogspot.com)

Posted by Alexandru Popescu on June 23, 2006 at 04:38 AM MDT #

I am tired of trying to keep up of all these so called latest frameworks. Let's see. We have Struts, Shale, seam, stripes and Spring. Then ruby, rail, grail and JSF vs Tapestry vs WebWork The next framework shud be called Strike as new java developer looking to learn a framework shud simple strike until a winner emerges

Posted by j2ee_Dodo on June 26, 2006 at 02:29 AM MDT #

The other million-dollar question few of these frameworks seem to address clearly is - what about ajax?

Ajax support in frameworks seems to break down into two camps:

  1. "We have fabulous support for ajax - look, a component can update itself dynamically! But your whole architecture must still be based on the http request/response mechanism, that's the way it's always been and always will be", or:
  2. "Build a gui spring-like website with no javascript knowledge, and it will magically just work like any other gui tool. Scalability? Transparency? Simplicity? What are those?"

I'm still waiting for a web framework that lets you build applications in a sensible ajax style - using ajax calls for the majority of user interaction, and only making a new synchronous HTTP requests where you need to go to a different functional part of the site. But still with the simplicity and transparency of a typical java web framework, rather than an opaque toolkit that says "trust me".

Posted by Korny on June 26, 2006 at 07:41 PM MDT #

oops, "swing-like" not "spring-like" :)

Posted by Korny on June 26, 2006 at 07:43 PM MDT #

Korny: have a look at Click. Click uses Copntrols as self-contained rendering objects that offer a good vehicle to integrate AJAX in a simple and effective manner. http://www.sunvolt.com/examples/ http://click.sourceforge.net/

Posted by J.F. Zarama on June 26, 2006 at 08:11 PM MDT #

ThinWire is pure Server-Side Java framework that you might want to look at. It?s open-source under the GPL and will soon be listed on sourceforge. In any case, some of its features are:
  • Familiar event-driven GUI programming model
  • Reconnects the flow of logic, no request / response
  • Maintains state naturally via variables, not via session
  • Develop exclusively in server-side language only
  • Rich Set of Complex Widget Components
  • ThinWire downloads once, just over 100K
  • Zero footprint client, no applets, activeX controls or browser plug-ins of any kind!
  • All Major Browsers Supported: Firefox 1, Opera 8, Safari 2, IE6
http://www.thinwire.com

P.S. Korny: You don't have to "trust us"... download the source and take a look for yourself. Plus, ThinWire is used in multiple large scale applications, one with over 1000+ users.

Posted by Joshua Gertzen on June 29, 2006 at 03:11 PM MDT #

Korny: I looked at the thinwire and demo looks pretty neat. What is missing in documentation is thinwire architecture and user guide specially on session management. I would like to use thin wire as presentation layer and integrate it with spring services and acegi based security. How about porting appfuse with thinwire view? I believe this will give good traction to thinwire

Posted by Anil Sharma on August 17, 2006 at 02:09 AM MDT #

Great post Matt. I've been using Spring MVC with Spring Web Flow recently with large corporate customer. The first app was painful in terms of wiring everything together... but now I find it very flexible and powerful. Definitely worth a look for anything moderately complex.

Posted by Greg Ritchie on September 27, 2006 at 11:43 AM MDT #

Every time I read "generates code", I don't care if it's "generates just for you" or what. I hate generated code. I think generated code is a cop out for when the developer didn't really know how to solve a problem, and so instead made a tool to spit out a bunch of stuff.

Of course there are some exceptions (compilers). But most of the time I've seen code generated, it's because a person really didn't know how to solve it in any other way.

For example, generating getters and setters in Java vs. "free" getters and setters you get in Ruby. Or generating code for OR mapping, again, junk, in my opinion.

The only time it makes sense to generate code is when:

1. You are jumping a huge level of 10 of abstraction higher. For example, C generates ASM. I've used both, and C is miles and miles easier and higher level to write than ASM.

2. You will NEVER *return* back to the level of generated code abstraction. This means, once I use C, I pretty much never ever touch ASM again. In fact, many many people don't even know ASM, don't need to know it, and actually, could even *hurt* their ability to program effectively in higher level languages by knowing it.

This is never the case in web frameworks. For example, no matter how OO you get in your web framework, HTML+Javascript+CSS is not the same nice set of primitives as is ASM. You always have to go back to the level of HTML and CSS and Javascript, no matter what you say, no matter who you are.

Also, there is no significant jump in level of abstraction either. So the jump in level of abstraction is low, and the return back to the original level is pretty much guaranteed.

That means generation is flat out a *wrong* way to solve any problem in web development *right now*.

So, to all you generating fools, take this warning. :) And don't take it too seriously either. Don't burst a vein. It's just my 2c.

Posted by Leo on October 20, 2006 at 05:45 PM MDT #

What about Echo2 or alike? Any one using it with success? Comments?

Posted by Demián on November 21, 2006 at 10:28 AM MST #

I looked at the following frameworks. i was very interested in Tapestry until I stumbled on Wicket. Wicket is also component based but IMO simpler to use. Next came Click framework even simpler. Next I looked at Java Swing like AJAX frameworks which started at GWT (Google Web Toolkit) followed by Echo2. Finally we discovered Thinwire that was not as mature as Echo2 but has performance advantages and shows a lot of promise. Strategically GWT could be the wiser choice because of Google backing. Echo2 has community support and Thinwire is still very new. Current choice :-) is Thinwire.

Posted by Pieter van Onselen on February 02, 2007 at 12:45 AM MST #

[Trackback] up

Posted by yeth on April 03, 2007 at 10:26 AM MDT #

I submit an additional vote for Click: http://click.sourceforge.net. I had been set on Wicket, then WingS, but I finally found Click. It's what I'm going with. It is simple and fabulous and not cumbersome like Wicket. In Wicket you have to create your form objects in Java and also lay them out manually in your html. Click generates your HTML for you for about 40 different types of components - and for other basic layout you can use Velocity. Click is page based and component based. Click rules if you are looking for a page based and component based framework.

Posted by Philip Weaver on April 10, 2007 at 06:07 PM MDT #

Leo, Look. OK. Click renders html - forget about generates. The rendering can be overriden if needed. Java is an object oriented programming language.

Posted by 72.177.51.203 on April 10, 2007 at 06:10 PM MDT #

I used to work with struts + spring + hibernate, and I like this combination most, its give easy , fast and understandable implementation.

Posted by Renish Ladani on June 11, 2007 at 01:06 AM MDT #

Matt, thanks for your post, I read it a while back, and shame to me, didn't understand the issues at first. I started my career, in Java / JSP some 5 years ago, and switched to ASP .Net two years ago.

I had the occasion to go back to Java for my new job, so I decided to give it a try at JSF, hoping that the best from ASP world would be there. What a disillusionment.... Yes, some things are in there, and it's definitely easier to learn and use than Struts 1.2, but... gosh, it sucks. JSF and HTML are COMPLETELY incompatible: I'm not joking, this is infamous. You just can't take a layout in html/jsp, and build a component with it - this means that you won't be able to include a web designer's work at all - this is fixed in JSP 2.1/JSF 1.2, and thats my luck, i haven't found an implementation that works, almost one year after your post. I've been stuck on a simple - simple ! the same things happen in the whole Java platform, their developers apparently don't know what that word means - a simple html fieldset/legend usage... hours later, dozens of blogs visited (some really good ones), no real answer, just hacks.

And OK, it's a component oriented framework, but come on, you really need lots of work to get something to work. That's not the idea of the 'component' part for such frameworks... I mean, the whole navigation rules seem already redundant or boring for ASP .Net developers, but trying to compare the ugly XML syntax + Java properties in JSF versus C# separated classes... this is sad, sad. And let's not talk about the visual support in IDEs such as Eclipse, Creator, Netbeans... first of all, no visual support for Eclipse at all (unless you use a Netbeans/Creator customized plugin, as i read guys at MyEclipse did... lol). The problem with support from Netbeans 6/Creator is, that as a consequence from the XML/XHMLT syntax, there's no tolerance for mistakes: you try to edit some html, and bang, you've lost hours of work, and of course, as I said, you can't ever edit your former JSP applications.

Some light at the end of the tunnel, oracle asf really has some nice components... that you can't use outside their server. Oh, I tried to mix tobago/myfaces and the RI... won't work either. In fact, all implementations are all so 'standard', that they won't work together ! What's the meaning of that word, 'standard', anyways?

I'm pissed, and maybe I'm unfair, but i would have never thought to be brought to claim 'Struts was always better than something'.

Posted by Felipe Cardozo on June 15, 2007 at 09:14 PM MDT #

sad to find that tapestry is not good enough for us to use, It's true that tapestry is hard to learn. But,IMO,after tapestry 5.0 release,tapestry is good enough for us to learn.

Posted by Gavin on June 27, 2007 at 01:40 AM MDT #

I liked Echo2. Don't know why it is not getting as popular as others.

Posted by Nitin Khare on July 25, 2007 at 11:15 AM MDT #

Hello there! may I join your discussion. I want to share some experience on learning JSF framework. After some advice from the forum and some books, they said that JSF1.2 will be future framework. So I started to learn JSF on my own. Before, I build my web app using pure jsp2.0 and servlet without tagging with struts,hibernate and etc. When I want to learn java web framework, they said the best is JSF. I started building web component using html component tags and renderer. For the first time I think it will be a breeze for me, however things are getting to steep for me to adapt. Huge JSF API intertwined together upon my simple project, really make me tired. More I learn and more I need to learn. Plus JSF is somewhat restrict me for making complex layout. They force me to going deeper in JSF API for making such customization. damn,.. its really tires me

Posted by kiddies on August 24, 2007 at 01:55 AM MDT #

Nice informative blog,agree most of the point but i dont like that Tapestry and JSF were not referred to as the only Java component web frameworks.To make other code simpleis great to give proper leverage the power of jave 5. http://www.websites-design.com.au/

Posted by Steve M. on September 13, 2007 at 04:32 AM MDT #



FROM::

http://raibledesigns.com/rd/entry/re_what_web_application_framework

What Web Application framework should you use?