Bear Bibeault's Front Man™ is an implementation of the Front Controller and Command patterns that serves as an ultra-lightweight framework (if you could call it that) for quickly creating web applications of all sizes.
The purpose of Front Man is to provide an ultra-light-weight web framework that adheres to the principle that the answer to the question "How big should a framework be?" is "Barely enough".
Well, I originally created a light-weight framework named Atlas after using Struts and getting thoroughly disgusted with it. I'm not a big fan of over-engineering and the creation of Rube Goldberg contraptions to bang in a nail when a simple hammer will do.
I then decided that even Atlas was too heavy-weight and invasive. I also wanted something that was better suited to the JSP 2.0 environment. Front Man was the result.
Stripes looks to be a good lighter weight alternative to behemoths like Struts and Spring MVC, but since I'm completely happy with Front Man I have no reason to switch.
I posted Front Man not only so anyone can use it if they like, but also to serve as an example of the implementation of the Front Controller and Command patterns.
First, I like this a lot. It's much cleaner than what I've been doing.
Question, have you considered keeping a map of the command objects around; either by lazy loading them as they are used or from a contextListener at startup?
It looks like you use forName to load and instanciate each command when they're requested. Maybe thinking this way is a red flag indicating premature optimization but it seems like a lot of object creation and destruction could be eliminated with something like this.
Actually, I did flip-flop on that design choice a lot. The colleagues that I confered with decided that among all the other object creation that goes on, that instantiating the Command each time would just be noise. That assumes, of course, that the overhead of the reflective instantiation was not significantly greater than that of "normal" object instantiation.
Instantiating a new instance each time removes any need for a Command to be written in a thread-safe manner, though I find myself doing so anyways out of habit. That doesn't mean that command pooling could not still allow this by creating and managing multiple instances as needed.
Pooling a single instance of each unique Command class would probably be most efficient, but require thread safety. Not too onerous, I would guess, since most people are used to writing servlets that way in the first place.
Do I detect someone volunteering to conduct a study?
Do I detect someone volunteering to conduct a study?
When I started the project I'm on now (2001), I did a lot of things right but one thing that I regret is not having a central front controller. There are between 50 and 100 components in the app, each has it's own controller with commands (or monolithic servlet with a big switch statement, depending on when it is written).
We're getting ready to release the next version and I'm thinking about the one after that; which means that this is a good time to consider the grunt work involved in converting everything to use a front controller.
Most of what I've written is threadsafe. The components that have a controller all have a map with the commands; the instanciation of which is hard coded in the the controller's init method.
So.... Right now I'm in the build/buy decision process and FrontMan is looking pretty good.
It may be the case that, with the improvement in the HotSpot compiler, that keeping and reusing commands doesn't really improve performance that much. It may also depend on how often a particular component is hit.
Another question: Have you stacked or chained controllers/commands with Frontman? Again, I've already got multiple components, each with their own controllers. There is enough component specific code in each controller that I wouldn't want to merge all of the controllers into one. Instead, I'm picturing having a front controller that forwards to the controller for each component which then forwards to that components commands.
Because you're passing all of the functionality along in the CommandContext object (really nice idea), I could probably just convert my component controllers into Command objects (chain commands instead of chaining controllers (servlets).
Thanks. That decision solved a whole mess of problems and messiness and...
The messiness that I'm trying to swim out of right now.
Exactly what I was going to suggest...
With regards to command creation, now that I think on it, it probably should be pluggable not only for versatility but for testability.
I think we have the primary feature of FrontMan 1.6.0.
If it's pluggable, then it should be able to work in any of 3 ways.
Preload, lazyload, use on demand and drop (current). It would be nice if this could be configured 'per component'. This would allow the really busy components to be preloaded, the 'sometimes used' ones to be lazy loaded and the 'rarely used' or non-threadsafe ones to be loaded and then freed for GC.
All this being said, one of the things I like about FrontMan is its simplicity and smallness.
The other is that it doesn't try to abstract web development.
This feature would affect the first in a small way (as feature creep usually does) but not the second.
Again, a good test might show that all of this is unnecessary. [ June 27, 2007: Message edited by: Ben Souther ]
BTW: I built a small guestbook app with Frontman for my simpleServlet site. It needs to be cleaned up before going up there. I'll send you a copy for your approval, comments, and suggestions before I put it up if you like.
Like all the simple.souther stuff, the war file can be dropped into a running instance of Tomcat and run without configuration..
Originally posted by Rahul Bhattacharjee: Why we need CommandBroker from within a Command object?
I think that that may be an artifact of earlier designs when the CommandBroker did some of the work that has now been moved to CommandContext. I don't think it is useful anymore. Good catch, I'll probably deprecate this in the next version. [ July 07, 2007: Message edited by: Bear Bibeault ]
I need a small clarification about your front man. In the doPost() of CommandBroker, you find the command every time, load the class, create an instance.
I tried a small scenario where in which i created instances of all the command classes, put them to a map and then each time the client request came in, took the object from the map, cloned and returned to the service the request.
I think i have no issues as of now. And also there cannot be problem of references and thread safety as i have analyzed.
Can you speared some more light on the same and tell me if my approach is appropriate?
There's almost certainly nothing wrong with your scenario, but I'm unsure why you're asking about it -- there won't be any significant difference in performance between the two approaches, and your requires the extra bit of code to make the command objects cloneable. Did you find that there was a performance issue you're trying to correct?
I felt that rather than loading the class on every request and creating an instance, cloning was a better option as it avoided the overhead of loading the class everytime (But i am not sure how internally java does a clone ).Currently i am working on testing if there is any performance improvement. I believe that there should be some improvement.
A little history... before Front Man I created a framework that I had named 3 Chiles Atlas. (It's the framework that is still used by the web application that we work on at my day job).
It is a lot more heavy-weight than Front Man (though nowhere near as heavyweight as something like Struts) and in its first version, I thought as you did and instituted Command pooling. It didn't do cloning as you describe, but once a command instance was created, it was pooled for reuse.
We ended up runing into some problem with the pooling (I forget exactly what) and surmised that with all the other object creation that's going on for each request, that instantiating one more command object would just be noise. So we changed it to create the command instance each time and we carefully watched our very heavily used web application for detrimental results.
As we had thought, the pooling turned out to be a case of premature optimization. We've observed no performance issues with the framework even though the load has increased more than a hundred-fold since then.
That doesn't mean you wouldn't see a difference in performance numbers between the two implementations. But whether those numbers are meaningful is another matter.
Thanks for the info. I too feel the same. If its a very minor improvement in performance then no use in implementing the same. And also the frontman current code is tested and proven. Better i'll stick on to the same. . Thanks again for your wonderful job. I am seeing its power and simplicity now .
Hi Bear, Remember we have recently talked about this stuff? I had guessed right what your next move was going to be. This whole idea has also been going on in my mind, and well, I haven't even tried RoR but its principles are inspiring. It turns during this time I have also been developing my own lightweight front controller / command framework. Though I'm already using it in a practice project, I still consider it in the works. I'm gladly surprised to see (in the comments here) that you have a CommandContext, because I came up with the exact same idea, in a class with exactly the same name I have chosen to load the commands on demand and keep them alive. (Edit: bullcrap, I just checked and I don't keep them alive. They are created and discarded.) There is never more than one instance of a command, and of course they must be thread safe. They're not supposed to keep state. I think this restriction doesn't hurt a good design with the command pattern, the commands do minimal stuff and delegate to platform-independent service objects. (The CommandContext ideally should abstract the commands themselves from the web platform but I don't think I have quite achieved that!) I have also chosen to have no URL-command mappings at all, commands are always inferred. A root package is defined as a servlet parameter in order to let the front controller find the right class. This was my original idea, but I have made it to support subpackages. So you have the restriction of having all your commands under one package but they can still be organized. OK, I guess I now should take a good look at what you've done. I kind of feel like reinventing the wheel with so many frameworks out there, but I couldn't resist making it (it's not big anyway). Whatever I end up using, one thing I'm sure of, I will never chose a design with multiple servlets. I have only been through that experience once (it wasn't my choice) and I've had enough! [ November 08, 2007: Message edited by: greg buela ]
Joined: Sep 04, 2007
OK, looking at Front Man's javadoc, I have a couple of suggestions to make. The first is something I mentioned in the previous post: your CommandContext is tied to the web environment, as it knows about HttpServletRequest's, etc; therefore so are your Commands, which take a CommandContext. I don't know if anybody would be concerned about it, we are most likely never going to need to port our apps to a non-web platform; and if we do, we'd be happy to reuse service and persistence layer, and just rewrite the MVC. Still, I thought it would be cool to minimize, or avoid, ties to the web at the Command, if only to help with my jUnit tests. My CommandContext, just like yours, has access to scoped variables, and things like request path, etc., but only the HTTP implementation has ties to the web platform. (Actually I need to get this better, but that's the idea.) A second thing I'd like to suggest, and maybe this is sounds more useful, is to have an overloaded forward() or redirect() that instead of taking a String argument, takes a Command class argument. This is better for refactoring when a class changes name. I have calls like this: getContext().setNextActionRedirect(HomeCommand.class); In the method calls that take a String, I also thought it wasn't necessary to distinguish between a View target or a Command target. The front controller servlet has the means to tell a command string from a view string, and the string itself should also be easily identifiable as a view or command to a developer. These are my 'next action' signatures: setNextAction(Class) // forward to command setNextAction(String) // forward to command or view setNextActionRedirect(Class) // redirect to command Here's another principle that I'm enforcing, from a best practice: no direct client access to a view, always go through the controller. That's why I don't even have a redirect that takes a String. Also I take views to be by default under WEB-INF, which makes them inaccessible to the client directly. I hope this feedback is of any use, it's also open to criticism, of course [ November 08, 2007: Message edited by: greg buela ]
... your CommandContext is tied to the web environment, as it knows about HttpServletRequest's, etc; therefore so are your Commands, which take a CommandContext.
You're thinking of the commands as being part of the Model in MVC. Don't. Instead, think of them as a part of the controller. Your model objects, as you've suggested, should not be bound to the web environment.
Think of the "Front Controller" pattern as a breaking up of the Controller in MVC; separating the servlet from the individual commands. Those commands are what would interact with your model components. [ November 16, 2007: Message edited by: Ben Souther ]
Joined: Sep 04, 2007
Originally posted by Ben Souther:
You're thinking of the commands as being part of the Model in MVC. Don't. Instead, think of them as a part of the controller.
Hi Ben, No, I wasn't thinking of them as part of the model. They are of course part of the controller. I was thinking more of reusing the commands to work with a different servlet implementation, maybe one that isn't a HttpServlet. In that case, commands shouldn't be dealing with anything that is HTTP specific. My framework has a CommandContext interface and the implementation HttpCommandContext. The commands, however, only work with the interface. It gives you access to the usual things you'd do with http request and response, but indirectly. Like I said before, this point I'm making may prove to be of little value in the real world: for a different environment we might find it more useful to deal directly with our service interface, or to build a new kind of commands. So it's definitely not a serious objection... One problem I have with my approach is that, as I find, my commands need to be aware of redirection after non-idempotent operations (I even want to enforce the post-redirect-get pattern). These concepts are inherent of the request/response architecture as in HTTP. Dealing with these things in other scenarios could be meaningless, although it should still work.
Cant wait to check this out. I want a basic thin layer over the servlet API. On the front man site it sais
FRONT MAN ...
...Doesnt require millions of maven commands to get up and running (i.e. its not like TAPESTRY)
...Doesnt have too much indirection regarding the servlet api (i.e. its not like GRAILS)
...Doesnt require not 1000 layers of goo (i.e. its not like SPRING)
I HOPE youre framework really can live up to this ! Below are my experiences with the "big 3" in my eyes (Grails, Spring/Struts, and Tapestry).
An introduction : Im a java programmer, and I build data driven, scientific software applications. I love the apache commons libraries . I might even love maven, someday.... I love hibernate and ibatis, as well as the apache DbUtils suite. I think JSPs are a nice convenient way of building dynamic content into a web application and Servlets are a great MVC complement. I dont want a wrapper to all web developement. Just a wrapper to my servlets and jsps. I already know how to use hibernate for a wrapper to the database. And I'm already a good enough programmer to build my own reflective API's when necessary for simple tasks. All three are probably manageable if you have a massive operation, or for a hobbyist interested in building CRUD apps for fun. But the lack of standardization makes them treacherous for small groups or individual developers with real deadlines supporting real applications.
1) I heard that "Grails" was Java's answer to Ruby, etc.... and that it was much easier than the "heavyweight" frameworks like Spring, etc. So I gave it a shot. The first thing I had to do was muck with my /etc/profile to get groovy and grails on my path, easy enough. Then I typed a command that created a web application in ten seconds. Wow. A complete web application that did CRUD against a bunch of autogenerated tables from my groovy classes (which I didnt fully understand yet,,,, but I was feeling optimistic). I went and decided to start building my own app. looked at the code, and tried to add an enum as my first variable in my own freshly written Grails app. Grails choked. I spent three hours on it, posted to forums, etc. Then I learned that GROOVY IS NOT JAVA. Duh. I should have realized this when I saw that NONE OF THE SYNTAX IN GROOVY IS ANYTHING LIKE JAVA. So what if it understands java. I understand spanish.... That DOES NOT make me a mexican. I decided groovy was TOO cutting edge for me. Give me some real JSPs and Servlets. Something that I can actually compile and test. Something that EXPECTS a human engineered data model. Something that seems like it has a good following.......... So I tried Spring.
1) So I tried Spring : Took me a few minutes to get an application working. I got a hello world application working, and I used the tutorial here : http://static.springsource.org/docs/Spring-MVC-step-by-step/part1.html.... GREAT tutorial on how ridiculously COMPLICATED it is to setup a SIMPLE application in Spring. There are 100s of lines of XML. They even make you manually configure your apache-tomcat xml files and build scripts. I've NEVER had to do that for a small application ! Ive never seen so much XML in a hello world tutorial in my entire life !
With SPRING, by the time you get all of the XML/class files configured properly and get your IDE set up properly, you realize that all Spring is really doing for you is providing a little bit of indirection and decoupling, and externalizing strings for you. BIG DEAL. I could code a framework to do that in an afternoon, from scratch. Then, I figured I would go and look into the code to see if I could use it as an application template, and realized that I had NO IDEA how to add a new page's data content. And as far as the whole "inversion of control" thing went, I had no idea where to add the "inverted code tidbits". So I decided I would try Tapestry, which proclaimed it was much simpler.... becuase it relies on convention and pure java classes for everything.... Here goes.....
2) Okay.... so in TAPESTRY, I read a tutorial. It looked great. No JSP, just plain old java. So I went to the tutorial here http://tapestry.apache.org/tapestry5/tutorial1/. And I did everything exactly as specified.... And I just got a Maven build error, saying that 4 of the jetty libraries were missing. Then I went and realized that the tutorial I was using was copied from another tutorial, which used other , slightly different, maven configuration parameters. So finally I found a webcast about how "easy" it is to create a tapestry application. I followed it up until an annotation which was part of the webcast made my eclipse IDE choke. It turns out that the webcast was using an annotation called "ComponentClass" which was part of tapestry 5.0 but not 5.1, or something of the like. Then I realized that all the "Screencasts" are for 2006 !!! Meanwhile, tapestry 5.1 and 4.1 are supposedly completely different...... but both stable ? This seems like an absolute nightmare. Is there any single definition as to exactly what Tapestry even IS ? Worst of all, when I got a tapestry application working, I just saw a bunch of nested folders with an awkward variants of html. It seems like the original theory behind tapestry (just write java code, it will generate the app for you) , is getting replaced with a GRAILS like approach, with lots of non-java syntactical sugaring which is, essentially, like learning a new language.
So I briefly considered using Struts, out of desperation. And then after reading more from the tapestry folks about how STRUTS is pure HELL.... I realized, web frameworks are, for the most part, pure hell. Unless you have a month of full time to dedicate to their intense study, or you are an expert with ant, maven, hibernate, and all the dependant technologies, and even then (I'm relatively comfortable with hibernate and maven) you STILL may not have any success.
3) Im going to look at Front man. If it is what you say it is.... I might finally have found a simple wrapper to Servlets that saves me some time !!
Sorry Jay but I don't agree with you.
Groovy syntax is Java syntax (well if you exclude some syntactic sugar like how you create some data structures, Closures ...)
It is totally digestible.
What SpringMVC version did you checked?
Maybe you have to check Spring 2.5 or even the better Spring 3
Any way, you can't be wrong with the FrontMan!
Joined: Aug 30, 2005
1) No Groovy is NOT Java. I assert this because the following line of code, which compiles
in Java 1.5 and above, does not compile in groovy
And, from a practical perspective, I took me about 5 minutes into writing my first Groovy app to learn that at least one standard java statement not accepted in Groovy. This leads me to believe that if I kept writing code in Groovy, I would find several more "non-java" like features, or worse yet, more unaccepted java syntax that is in fact part of the official java spec.
I have nothing against scripting languages. I just don't want people to be mislead.... Regular Java developers with full time jobs working in a service oriented environment will not easily be able to morph sophisticated applications into Grails projects. At least, not as of the time that I'm writing this post.
2) Regarding Spring ? I tried 2.5. I wasnt that disillusioned by it.... But it seemed like ALOT of bloat, most of which had little or no sufficiently significant improvements to be worth the cost. The last Java developer I knew who switched over to Spring wound up going back to PHP. And I see this as a trend..... We program in Java because we like Java. We like the type safety, we like that everything compiles cleanly. We like build errors (as opposed to run time errors). If we didn't, we probably would have switched over to PHP or Python A LONG time ago :]
First off, I want to say that FrontMan is very useful. I have it up and running and I like it a lot as it satisfies by server-side Java MVC needs.
I am considering using RESTful web services for modifying and retrieving data from the server (which will be stored in a database).
My question is, how does FrontMan work with a RESTful web framework?
Currently I have all requests from the web (client) coming in through the CommandBroker and being dispatched to the appropriate command I have
developed. It all works nicely and as expected.
I have the following in my web.xml to handle the FrontMan configurations:
So if I had a page in which I wanted to display a list of employees, I would have a URL like: http://www.myapp.com/myApp/command/getEmployees which would would get
dispatched to my getEmployees command class which would retrieve the employees data and send it back with the response.
I am somewhat new to RESTful architecture, but it seems like with REST, I would be issuing a GET request like:
GET /employees HTTP/1.1
How does this fit in with FrontMan?
For the most part I expect the REST requests to come to the server via a jQuery triggered AJAX call.