20031016 Thursday October 16, 2003
Dueling IoC (Webwork 2 and Spring)

BYOM
My personal experiences with Struts BYOM (Bring your own Model) philosophy is that it frequently becomes Build your own Mess. Since there is no support for architecture beyond the (unfortunately concrete) Action classes, invariably a mixture of custom properties files, plugins, extended RequestProcessors or other solutions arise, leading to maintenance headaches later. So the Inversion of Control patterns that WebWork2 and Spring support is very appealing. So today I thought I would do a comparison of the two implementations, based on my experiences with them so far.

Bottom Line Up Front
In case you are short on time, here's the conclusions first, explanations will come later. So here are our competitors...

  • WebWork2/XWork (Type 1 IoC) - Enabler interfaces link Components to Actions. Xml file defines the Enabler->Component link
  • Spring (Type 2 IoC) - An Xml file links Javabeans (which can be either Actions or components) based on property names.
So the winners for my arbitrary categories, by order of importance. Now 1 and 2 I consider highly important, 3-9 are nice but not essential.
  1. Configurable Components (Spring) - Each bean can have its properties configured via Xml. Webwork gives zero configurablitly of properties.
  2. Multiple Components of Same Type (Spring) - Can have two components of the same class that can differ only by single property value. Webwork would need to add a new component and an new interface for EACH new variation of a component.
  3. More Flexible Components Lifecycles (Webwork) - Has Request, Session or Application vs Spring (Singleton i.e. Application and Prototype)
  4. More targets for configuration (Spring) - Any bean can be configured and retrieved. All parts of the framework can be targeted for components.
  5. Simple Configuration (Webwork) - For a small number of frequently used components, Webwork will require less configuration.
  6. AOP/Interceptors - (Undecided) Webwork is simple, but can only affect Actions. Spring is more full blown and can wrap any bean.
  7. Data Layer Integration (Spring) Good extension points for JDBC and Hibernate
  8. More IDEA refactoring friendly (Webwork)- Refactoring a property name will ripple to the Interface, however Spring's xml config files won't change
  9. Single Configuration format (Spring) - All config files use the same xml DTD.

So who wins? On a pure IoC component model, Spring is far more robust and expressive framework that can act as IoC, a registry or even a generic object factory. XWork is a simple (and fairly effective) solution to IoC. Not being able to configure the components in the Xml, like I can with xwork's actions is big handicap for Webwork. But since XWork's component model is integrated nicely into Webwork 2 (which I'm currently using), I'll probably use it until its limitations cause me to integrate Spring. Ideally (if the world revolved around me, which last I checked, it does not), XWork would replace their IoC implementation with Spring's, or at least add xml based configuration for the components.

So Explaination with an Example
Lets establish a small example to help explain these concepts. My favorite example is the PenguinStore, a ficticious online penguin retailer. So for today, our application has one component, a Data Access Object (PeguinDao) and an action. (ListPenguinsAction).

(Listing 1) The Component, same for both WebWork and Spring...
public class PenguinDao {
   public List findAll(){ // Do database stuff}

   public Penguin find(Long id){ // ....}
}
(Listing 2) For Spring, the java
public class ListPenguinsAction implements Controller {
   private PenguinDao penguinDao;
   
   // Spring needs getter/setter for JavaBean based config
   public PenguinDao getDao() { return dao;    }
   public void setDao(PenguinDao dao) {  this.dao = dao; }

   public ModelAndView handleRequest(// ...) throws ... {
      List all = dao.findAll();  
      // ...
   }
(Listing 3) And the xml, from application-context.xml.
<bean id="penguin-dao" class="com.penguinstore.PenguinDao" singleton="true"/>

<bean id="urlMapping" 
 class="org.....SimpleUrlHandingMapping">
<property name="mappings">
      <value>/list-penguins=/penguins</value>
   </property>
</bean>

<bean id="penguins" class="com.penguinstore.spring.ListPenguinAction">
    <property name="dao"><ref bean="penguin-dao"/></property>
</bean>

(Listing 4) Now for WebWork, the Java
public class FindAllPenguinsAction implements Action, PenguinDaoAware{
   private PenguinDao dao;
   public void setDao(PenguinDao dao) { this.dao = dao; }

   public String execute() throws Exception {
      List penguins = dao.findAll();
      //....
      return SUCCESS;
   }
}

public interface PenguinDaoAware {
   void setDao(PenguinDao dao);
}
(Listing 5) From xwork.xml
<action name="list-penguins" class="com.penguinstore.ww.FindAllPenguinsAction ">
   <result name="success" type="tile">.penguin.list</result>
</action>

(Listing 6) And from the components.xml
<component>
   <scope>application</scope>
   <class>com.penguinstore.PenguinDao</class>
   <enabler>com.penguinstore.PenguinDaoAware</enabler>
</component>

Configurable components
For our PenguinDao component above, there is no configuration being done. But what if I want to add something as simple as an order by price for my findAll() method. In Webwork, I need to embed the behavior in the the code or create a subclass and new component listing.. In Spring i can modify Listing 3 to become...

<bean id="penguin-dao" class="com.penguinstore.PenguinDao" singleton="true">
    <property name="orderBy"><value>price asc</value></property>
</bean>
In both case, changes to the PenguinDao are needed, but using Spring, I can put the details (which are more likely to change) into the xml. A trival example. What if PenguinDao also sends emails? Do I want to code the SMTP host directly into the Java or in the XML, like...
 <property name="smtpHost"><value>mail.penguinstore.com</value></property>

Multiple Components of the Same Type
Lets add the case where I have two different kinds of penguins, Rockhoppers and Emperors. The only difference between them is a single field in the database, penguin_type. What I want to do is configure two different components, using the same PenguinDao. I want the findAll() method to return only those types of penguins. Modifying Listing 3 above, Spring lets me do this.

<bean id="rockhopper-dao" class="com.penguinstore.PenguinDao" singleton="true">
    <property name="type"><value>rockhopper</value></property>
</bean>
<bean id="emperor-dao" class="com.penguinstore.PenguinDao" singleton="true">
    <property name="type"><value>emperor</value></property>
</bean>
Webwork would require 4 more classes, RockhopperPenguinDao, RockhopperPenguinDaoAware, EmperorPenguinDao, EmperorPenguinDaoAware, along with plus 2 more configurations in the components.xml file. Yuck.

More flexible lifecyle
This a nice touch by WebWork, particular the Session scope. I can create a ShoppingCart component, declare it as a session scoped, and not worry about it at all. Better yet, the actions don't even need to understand the scope the component lives in (I.e. a persistant database base Shopping Cart or a session based one.

More Targets
In XWork only Actions can be end targets of components. As far as I can tell, while components can link to each other, interceptors can't get them, nor can you just pull fully configured components from the component manager (like a Registry). I have also used Spring as a generic object factory. So lets say we want to populate our store's database with a couple 100 penguins. Rather than inventing my own data import format and parsing code, I can create an spring formated xml file, use Spring's BeanFactory to populate the beans, then persist them out with Hibernate.

Simple Configuration
The example above is fairly small. Add 3 more actions to both (with three more config entries to both), and Spring requires each of the actions to explicity wire up to the PenguinDao. Where as WebWork can just declare each new action implements PenguinDaoAware. Adding new targets (i.e. the action) in Spring adds more overhead than Webwork. However, new components have more overhead in Webwork (2 classes, enabler and component + xml entry)than in Spring 1 component class and 1 xml entry).

AOP/Interceptors
I really like Webworks implementation of Interceptors. Easy to grasp and put to use, but it's is limited to wrapping actions. Spring goes a more indepth, which allows it to do neat things like handle Hibernate tranasctions and around a Dao component. So its a case between simplicity vs complexity right now. I need to play with Spring's version more.

Data layer Integration
Spring is a clear winner here as out of the box, it comes with some nice tools to plug both JDBC and Hibernate into the framework. Webwork doesn't yet do this. Spring Hibernate integeration should (if I understand it correctly) take most/if not all the exception handling, session lifecycle and resource management away from the Actions/Components, simplify them. I believe this is some that Jason is working on for XWork (as part of the Conductor project), but I'm not sure where that is at.

More IDEA refactoring friendly
Under Webwork, a small nicety to be sure, but if I rename the PenguinDao field from

private PenguinDao dao;
to
private PenguinDao penguinDao
using IDEA, it will change the PenguinDaoAware interface too. For Spring though, it's not smart enough (yet) to know that the application-context.xml file needs the
name="dao"
to become
name="penguinDao"
I need to manually do that or my 'automatic' refactoring just broke my project.

Single Configuration Format
The Spring xml syntax is expressive enough that can use it instead of properties files to configure any Javabeans. This is a mixed bag, its great for generic configuration, as it can configure ANY Javabean. But a nod to explicitness - I happen to like Webworks explict configuration syntax (xwork DTD) for the action and interceptor configuration. I expect the bulk of the config code will actions, so an explicit concise syntax for that is a help.

posted at (2003-10-16 05:32:44.0) # Comments [1]


20031008 Wednesday October 08, 2003
If Voting is good, Voting all the time must be better.

Arnold Schwarzenegger wins the California recall election. To loose quote the Daily Show's Steve Colbert, "lets have an election once a month, or better yet, just embed politicians with little electrodes that we can zap them with everytime they do something we disagree with."

posted at (2003-10-08 06:50:05.0) # Comments [0]


20031003 Friday October 03, 2003
Ant Debate - Still looking for an argument

Based on Kyle's comments to my Maven post below, I'm still looking for a real firestorm directed against Ant. The posts on the Marc list were indeed complaints about Ant, but there were from folks who appear to be fairly new to Ant, coming from a Make background, and were wondering why Ant doesn't have feature X that Make had that they liked. Frankly I have no idea if their concerns are valid, because I've never used Make. And ironically, most of thes post were followed up by helpful folks who give (as far as I could see) useful answers to the problem the original poster had. In any case, correct me if I'm wrong here, but I'd say the Ant vs Make debate is pretty much solved. Is there any one out there who has uses both Ant and Make enough to make a rational comparison, and has gone back to Make because it work better?

Where's the Fire?
So the question is, given that Ant is the standard java build tool in use today, what else is there? What I didn't see on the MARC list was a lot of postings by java folks who were very experienced with Ant and have decided that Ant just doesn't cut it anymore because of reason X, Y or Z. So what I'm really looking for are well laid out arguments for why Ant is really so terrible, and why something else is better because it is simpler, more productive and/or more powerful.

Update
Based on ade's comments below....
* Targets aren't components which can be reused, parametrised, extended and composed.

I can agree with this, one of the reasons I tried out Maven was the lack of resusablity that Ant provided. Well, this should be improved now as Ant 1.6 includes an import task that can pull other build files directly into the current file. This should allow for a good level of reuse of targets.

* It doesn't prescribe a folder structure for Java projects. So writers of tasks or reusable targets can't assume anything. If you can't assume anything then you can't build a library of targets for reuse.

The trouble with there is the fine blurry line between prescribing and demanding. Assuming is dangerously seductive idea, and is where I feel one of the places maven gets into trouble. Maven pretty much demands a certain directory struture for your project and if it doesn't follow you end up having to rewrite goals, which defeats the point of reusable targets. Case in point, I had to rewrite a bunch of goals dealing with server-side stuff (especially the war goal) as the built in goals assumptions were wrong about my project set up. I'm not sure how likely a good solution to this is, as few projects look alike.

posted at (2003-10-03 06:04:16.0) # Comments [2]


20031002 Thursday October 02, 2003
Ant 1.6 Beta is out

Since I'm all about Ant advocacy today, just wanted to let you know that Ant 1.6 Beta is out. It appears to have a couple neat changes that I'll have to look into. At first pass here are some highlights (for me anyway, your own mileage may vary)

  1. SCP (Secure Copy Protocol) and SSH (Secure Shell) task are now built right into Ant as first class tasks. Makes keeping servers upto date easier.
  2. Ant libraries - Haven't quite grokked this completely, but it appears to be an effort to extending Ant more streamlined. I.e. package the tasks and xml descriptors into nice neat jars....
  3. Updated class loading behavior - Should be able to load other task (optional) jars without needing to dump everything into ant/lib folder.
  4. Xml Namespace aware - Again, not completely sure of the implications as this appears to be related to 2, but this is probably good, right?
  5. JUnit tests can all share a single classloader - If i read this correctly, it means now if i have 3 unit tests that use Hibernate, it wont need to configure 3 session factories. This should make it easier to do my unit tests without a bunch of hackish work arounds.
  6. More Perforce tasks - My favorite source control tool gets a bit more loving.

Why I love IDEA, reason 845
While on the subject of ant... IDEA is smart enough to know all the properties my ant file is using, giving me autocomplete for them, just like any other variables. In addition, It also scans through all the properties files I load using <property file="local.properties"/> and give code completion on them too.

posted at (2003-10-02 15:53:49.0) # Comments [2]


Where there is Smoke, there's usually fire (Maven releases)

Apparently Maven has a release candidate out, as detailed here. This also promoted a wave of criticism that spilled out on both the TSS thread above, as well as the obligitory BileBlog follow up here. Having tried maven out early this year, and frustratingly abandoning it, as I talked about here., I don't have much new to add, other than a periodic warning.

Smoke spotting
Now for a new developer choosing between say Ant and Maven as your build tools, you need to decide for yourselves whether or not its worth it. So consider the storm of criticism, that while you might not agree with them in general (cough.. Hani) doesn't mean there isn't something there. Case in point, when was the last time you heard somebody complaining about how awful Ant is and how hard it is to work with. Maven is very, very invasive for your build procedure, so when you jump in and decide its not helping, climbing back is not easy. So the motto for the day is...

Keep it Simple, Keep it Ant.

Update With regards to Jason's comments below....
I guess it comes down the lesser of two evils argument then. I'm sure some people consider Ant terrible (and I've done some minor complaining myself), but for the most part, the developers I know and have contact with consider it an acceptable (and fairly risk free) solution. But If there are any good public threads about Ant's flaws, I'd certainly be interested in reading them.

posted at (2003-10-02 06:49:48.0) # Comments [3]


20031001 Wednesday October 01, 2003
Half Baked Beans

Cedric brought this article on Half-Bean's by Brian Slesinsky to my attention. Brian had a solid, well laid out solution, that I plan to rebut here. The problem he propose to solve is constructing immutable beans, especially those with lots of parameters. Consider his problem domain, which at it's simplest could look like this.

public class Album {
    private final int albumID;
    private final String albumName;
    private final Artist artist;
    private final List tracks;
 
   public Album(
      int albumID, 
      String albumName, 
      Artist artist, 
      List tracks){
    // setting properties
   }
   // no setters (immutable)
   // getters excluded
}
Personally, i could live with this, if i really needed too. But as the number of fields grow (say to 20), the constructor gets longer and longer, or more constructors get added. And what if some or all of the fields were optional? (Picture the next developer wondering - "So do i call the 12 argument constructor or the 8 argument one?"). My next step would be this.
public class Album {
    private final int albumID;
    private final String albumName;
    private final Artist artist;
    private final List tracks;
 
   private Album(){

   // Well named, descriptive static Factory methods to construct valid Albums
   public static Album newBasicAlbum(
         int albumID, String albumName, Artist artist,  List tracks){
      // wire-up an album
   }

   public static Album newTracklessAlbum(
      int albumID, String albumName, Artist artist){
      // wire-up an album
   }

    public static Album newEmptyAlbum(){ // }
}

Encapsulation: Keep the logic under one roof
His solution was to create second class that acts as factory (AlbumBuilder) to set all the properties, validate the state of the Album, and returns a fully initialized copy the Album. I too am not a big fan of long (hence brittle) constructors, which is the reason I plan to steer clear of PicoContainer. But in this case, I think a 2nd class is a bit of overkill, and is really just spreading the problem around. Some wiring code class is going to call all of the setXXX methods anyway, either on the AlbumBuilder or the Album, and presumably pass the Album around as a value object. So why not do this instead?

public interface Album{
   public int getAlbumId();
   // rest of getters, but no setters
}

public class AlbumImpl implements Album {
   public void setAlbumId(int id){ this.id = id}

   public void buildAlbum() throws IllegalStateException{
   // if in invalid state, throw exception
   }
} 

Pass the interface, not the implementation
Album is an immutable interface (no setter methods), which is what gets passed around, so no client code is the wiser. And in either this solution or Brian's, the wiring-up class is going to need to know about all the setters and the buildAlbum() method anyway, so why not keep the logic in one class rather than two? The developer who shows up 6 month later will thank you for making their lives easier.

For the Truly Paranoid
If you worry some malicious client code downcasting and wantonly calling setXXX methods, you can embellish AlbumImpl to look like this.

public class AlbumImpl implements Album {
   private boolean initialized;
   public void setAlbumId(int id) throws IllegalStateException{
      if(initialized){
        throw new IllegalStateException(
            "You know you aren't supposed to do this. Why are you?"
         ); 
      }
       this.id = id
   }

   public void buildAlbum() throws IllegalStateException{
      // check state
      initialized = true;
   }
} 
posted at (2003-10-01 04:59:55.0) # Comments [1]


20030925 Thursday September 25, 2003
Feedback! I don't need no stinking feedback.

Actually, I do, and now you can. Thanks to Matt for letting me know my comments were broken. The problem was a missing jar file which i have added now. This is a new install of Roller on a new server, so bugs are definately to be expected. If you find something, feel free to email me at patrick@browsermedia.com.

posted at (2003-09-25 07:23:32.0) # Comments [1]


Tiles + WebWork

From my comments logs.... >I am also considering alternatives to Struts, but I'd hate to leave Tiles behind: I looked at SiteMesh, which could be used with WebWork, but it's not the same thing, it has a very different philosophy and implementation. How do you plan to work with the Tiles concepts in your newly chosen framework?

I don't plan to leave it behind either.

I too have a great love for Tiles. WebWork 2 supports the concept of Result types. Basically after the action is complete, different types of views can be selected, including Velocity, regular old servlet dispatching (i.e. JSP), etc. So I've implemented a TilesResult, that works the same way as Tiles integrates with Struts. It was actually pretty simple implementation, all I'm doing is wrapping around a TileRequestProcessor and using it to select the tile and render it. Best of both worlds.

Update
Base on comments below...
1) At some point, probably. But I need to make sure I understand Webwork well enough that I can stream line it abit. But the whole class is only about 10 lines of code, so its nothing complicated. 2) The beauty of it is that Tiles Controller continue to work exactly as before. The TilesRequestProcessor builds the TilesContext and calls any Controllers for me. All my code does is act as an Adaptor to the TilesRequestProcessor.

posted at (2003-09-25 07:19:51.0) # Comments [1]


20030924 Wednesday September 24, 2003
Choosing a replacement for Struts (Webwork/Spring)

That I am considering moving away from Struts may come a surprise to some folk who have read my previous defenses of it. However much experience and investment I have in it, doesn't mean I'm completely closed to new ideas. Frankly, after about 2 years of Struts coding, I found myself hitting the limitations of it more and more. So I started reaching out for alternates, and I found WebWork 2 and the also recently released SpringFramework, both of which had good documentation on how the worked, and more importantly why they were structured the way they are.

I talked of this in a previous post on MVC frameworks here. One of the first things I did was try to incorporate some of the ideas I liked from both into some existing Struts projects early this summer. Here's what I took from each of them.

Spring
  • Generic bean factory configuration for components
  • The type 2 style Inversion Of Control - For those not familiar with this it means an xml config file that explicitly links beans together. See Spring's docs for more details, as well as Pico's Type comparison on the IoC types
WebWork 2
  • Action Based Interceptors and Stacks
  • ThreadLocal Action Context

Oh ya, the Wheel, Been there, Reinvented it myself
So why rewrite these to play well with Struts? Well, at the time, neither Spring nor WebWork 2 had stable releases. (Spring was actually still in a sort of limbo from Wrox folding). Also, I wanted to validate how valuable these concepts were, using a familiar context of Struts projects. Overall the biggest reason however was Test Driven Development. I found it very hard to properly unit test Struts projects, so as I found a test hard to write, I say, wow wouldn't an interceptor make this easier. And so on.

Learning so far
Based on my wheel-reinvention, here are my takes on the concepts above.
  • Generic BeanFactory - I think this concept absolutely rocks for generic configuration. It is completely noninvasive into the code, as all components are pure JavaBeans and require no interfaces of any kind. Places nicely with hibernate as well. However, I draw the line at using its syntax for configuring the entire application. Its much more explicit (hence readable) for me to use Web Work 2's style to configuration for actions and interceptors. Luckily, Spring's BeanFactory implementation is super easy to drop into a project. (So I can use it side by side w/ WebWork.)
  • Type 2 Inversion of Control - This is the most flexible solution for IoC, at the trade off of having to specify things more than WebWork2's Type 1 style. (I'm going to discuss this more tomorrow)
  • Interceptor/Stacks - Kudos to the WebWork guys on an extremely practical implement of Aspect Oriented Programming. Even my half-assed copy of an implementation for Struts dramatically cleaned up my projects' architectures. No more Deep Action Hierachies, excessive Action Chains or cramming stuff into the RequestProcessor.
  • ThreadLocal ActionContext - Worked well at reducing the long parameter signatures that Struts developers are used seeing. Ugly methods that look like doSomething(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse) get reduced to doSomething().
Conclusion
So based on my proof of concepts, I'm starting down the path of converting of WebWork2 as the Web MVC, with some touches of Spring where needed. I'll also try to explore what a Struts user is likely to find complicated about adopting WW as well.
posted at (2003-09-24 10:05:41.0) # Comments [4]


20030923 Tuesday September 23, 2003
Back on the Air!

Well after a long summer hiatus (and our server being down for a good portion of the summer), I'm back and ready to be blogging. Here's the 10 second story my summer highlights.

Amsterdam's Red Light District, an involuntary trip to Fort Leavenworth, Musical Servers (a similiar but more painful version of Musical Chairs), Big Red Balls and excessive procrastiation.

Short todo list
posted at (2003-09-23 11:36:23.0) # Comments [0]


20030707 Monday July 07, 2003
The Art of .star.wars

For any that might be concerned for my safety, my recent lack of posts is not because I've been hit by an rogue garbage truck or anything similarly drastic. The simple truth is that I have mistakenly purchased some digital heroin Star Wars Galaxies. And by mistake, I mean it was a mistake to think I would have any unconsumed free time after taking my first hit installing it. Needless to say anyone who likes Massively Multiplayer online games, and isn't concerned about ceasing to exist should go check it out. I haven't been a big fan of MMORPGs, trying some of the top titles like Asheron's Call and Dark Age of Camolet. They just haven't been captivating for me. SWG gets a lot of the essentials right, so two thumbs up.

posted at (2003-07-07 14:04:18.0) # Comments [0]


20030614 Saturday June 14, 2003
Book Store Jackpot!

I went to the Falls Church Borders today, and after a dry spell of a couple weeks, I found a bonaza of potentially interesting books had shown up on the shelves including...

  • Struts Pocket Reference - OReilly
  • Using and understanding Java Data Objects - APress
  • Java Data Objects - OReilly
  • Eclipse in Action - Manning
  • Unit Testing in Java - Morgan/Kaufman
  • Extreme Programming with Ant - SAMS
  • Developers guide to Eclipse - Addison - Wesley
Off the shelf and into my grubby paws
I ending up picking up the Addison - Welsey eclipse book. My current research is looking at microkernals, so I want to learn more about Eclipse's plugin structure. It also has a couple of chapters on SWT and JFace which is another feature I'm interested in. No intent on switching though, as I'm already a committed IDEA user.
posted at (2003-06-14 22:34:29.0) # Comments [1]


20030613 Friday June 13, 2003
Set up a Standalone page for Struts Anti-Patterns

Just to keep track of Anti-Patterns I'm working on, I've created a separate table of contents page (on the left menu) where I'll post them. Since Roller isn't yet quite a wiki, I'm going to link directly to the posts from there.

Setting up new pages in Roller
This probably isn't news to anyone who has used Roller for more than say, two minutes, but I figured out how to use the macro to include the header, left and right menus on the Anti-Patterns page. This works OK, avoiding my having to copy and paste the layout. It works just fine mainly because the number of pages I have to manage is small. But it got me thinking about two different styles of page composition.

Roller includePage "pull" vs..... Tiles "push"
Roller's includePage() is akin to jsp:include and c:import taglibs. Any page that wants to include other content adds a statement that says "bring that content to me!". Works reasonably well, but the result this that now every pages NEEDS to know about the navigation, which results in lots O' duplication.

Push Content
Contrast this will the push methodology that Tiles and wiki software uses. With Tiles, the content of page is created as separate file, knowing nothing of the site around it. The overall layout structure is declared once in an xml file, with only one place to change. The config file matchs pages with the site layouts, and if the skin changes so does that page. In wiki's its even simpler, when I add new content, it just gets the basic skin of the site, no extra effort involved.

Solving the common problem
I'll bet the odds are about 90% or greater that when any user adds a page to a site, via a CMS or other tool, they just want to add the content and have it look more or less like the rest of the site, with ZERO extra effort. Asking users to specify categories, layouts, or any other details is probably excise and just makes it harder. And the harder you make it, the less likely it is that people will do it. And Dave, don't interpret this as real change request for Roller, I know you've already stated that you don't want to turn Roller into a Wiki, and the current includePage() syntax works quite well enough for the limited number of pages that I plan to create.

posted at (2003-06-13 08:14:15.0) # Comments [3]


20030610 Tuesday June 10, 2003
Struts Anti-Patterns

Every piece of software has it's own set of idiosyncrasies. Struts is no exception. After a couple of projects that use it I've noticed natural "lines of drift" where the code "wants" to go. Some of these patterns work out pretty well, others just cause endless headaches and manageability problems. Some of them can be worked around within the scope of Struts, other may require outside ideas. (Hence, outgrowths like Tiles).

Assigning myself some homework
If I don't set some goals for myself, I don't get much done. That goes for Blogging too. With that in mind, I'm going to focus on putting together a number of blog entries regarding Struts Anti-Patterns. The idea is to document the places where Struts really falls down, or makes things harder than it should. I have a couple in mind that I'll start with, but I'm sure others in the blog-o-sphere have run across their own. If you have an idea for one, let me know.

My Intent
A great framework should make simple things easy, and hard things possible. Struts is likely the most popular MVC framework, but its certainly not the only game in town. There are many more to choose from, each of which bring their own good ideas to the table. So for a lot of these anti-patterns, I'm going to end up reaching outside of Struts for a solution, looking at other MVC's for how they solved a problem.

Getting Started
Initially, here's my initial list of ideas off the top of my head, which will hopefully grow and get more colorful, snappy sounding names. I'll try to flesh these out over the next few weeks, plus any good suggestions on other ideas that I get.

       
  • Deep Action Hierachies - A tall inheritance hierachy, in order to perform pre/post processing.
  •    
  • Concrete Class Coupling - Adding functionality require extending of classes rather than implementing interfaces.
  •    
  • Overweight Web Tier - Struts is strictly bring your own model. Which in reality often means no organization beyond the Actions.
  •    
  • Code Explosion - A large number of action classes, some of which handle related behavior.
  •    
  • The Action Train - A number of chained actions, coupled together.
posted at (2003-06-10 12:03:31.0) # Comments [4]


20030606 Friday June 06, 2003
JBoss invents Content Management

The buzz around the blogosphere these days is Marc Fluery's article tuesday on Nukes, a new Open Source Content Management Systems (CMS). The summary is that JBoss.org didn't like postNuke, a Php based CMS, so they wrote their own, Nukes. The biggest area of contention is several statements that basically say..

  1. There are no Open Source Java CMS's
  2. So Nukes is the first one. Ya for us.
Having done a bit of research for our own CMS's solutions, I can say these aren't true. Mike and Anthony have already pointed this out, so I'll skip to the point I wanted to make.

Sticking to your Core Compentency
Manageability wonders why JBoss would drift away from it's core compentency into CMS's. That's a good question, maybe JBoss should be sticking to what it knows. But I if I alter statement one above to...

  1. There are no Open Source CMS's that use JMX for the underlying architecture.
Now that's probably true. Is pushing the bounds of what JMX/microkernal architecture to new solutions a Core Compentency of JBoss? Maybe. I guess it depends mostly on the level of effort they put into it. Web design/Graphic design is not a Core Compentency for them, so one man-day of browsing the web for OS Java CMS's could have been effort better spent.

Rolling your own CMS
The not invented here (NIH) syndrome strike's most developers from time to time. As a web development company, we've looked at a lot of CMS products, including some of the CMS's mentioned here. It's been a mixed experience. The ugly truth is that most organizations have needs that are different enough from current CMS's either...

  • Don't meet their needs, and require extensive hacking to do so.
  • Meet their needs, but cost Ungodly sums
It is for these reasons that many clients we seen have/want their own custom CMS, that matchs how they work exactly. And as much as I hate NIH, since Web Development is our Core Compentency, we've gradually arrived at the conclusion that for we too need our own CMS. Using a third party CMS as our main service offering is a risk. JBoss however invented Nukes for their internal website, which is a very different situation.

Watch your tone mister
My guess is that if Marc's tone had been "look what we can do with JMX" rather than "I invented Java CMS" it might have be better received. Too bad, there are some interesting concepts that are overshadowed by a poorly chosen tone.

posted at (2003-06-06 09:15:54.0) # Comments [1]



Today's Page Hits:18105