Welcome to JoshLong.com, home of my personal blog
<< Last | Next >>
August 27, 2009

A Survival Guide to Maven, OR, Why Maven's Still Cool

The Problem: Confusion

I've had a lot of small discussions recently with people where they were just absolutely not interested in using Maven. Has it somehow gotten a bad reputation when I wasn't looking? Am I missing something? When did I suddenly become the guy using a tool that was too slow, or not agile enough for everybody? I can still sing and dance and jump like you guys, too! Even if I do use Maven...

So, let old Josh tell you a little bit about Maven. Maybe we're not all talking about the same thing. Consider this a survival guide to Maven.

Maven, like this guide, assumes you're trying to solve the 80% cases effectively. Already, we have a point of confusion!

I'm pretty confident that your first thoughts on that last sentence were to what Maven considers "80%," and you're probably wondering what you might reasonably call Ant's "80%" cases. I would argue that Maven's "80%" is 80% of a much, much bigger pie.

I haven't met an Ant build yet that couldn't be cut down in complexity by using Maven. Sure, sometimes the resulting Maven pom.xml was more verbose (though, that doesn't happen all that often in practice, either), but that's not the same as complexity. Intrinsic complexity is one thing. Surface complexity is another. I define intrinsic complexity as the concepts required to effectively deal with a problem in a problem space. I define apparent complexity as the busy work a process presents you with to obtain a goal.

I'm pretty convinced Ant suffers from both of those kinds of complexities. I wasn't going to start any bar fights about it, but I was pretty sure. Then, Ruby On Rails debuted and made code generation popular again. It brought "convention over configuration" to the mainstream. Then, I knew I was on to something with Maven.

I might argue that when you download Ant and decide to keep it in your tool chain, you think of it as providing a solution, assuming you've configured it, to:

  1. compiling Java source files into classes
  2. copying resources to the right place, such as .XML files, .properties files, etc.
  3. generating .jar or .war artifacts from the aforementioned classes.
  4. generating JavaDocs. I'm adding this one as a "maybe." Does anybody still do this and actually keep JavaDocs floating around? Is the Eclipse or IntelliJ support for rendering in-popup the contents of the JavaDoc not enough?

The enlightened Ant user will also, maybe, add dependency management with Ivy to Ant's 80% cases. I mention this to be fair, though I highly doubt it's that common. I suspect that a lot of Ant users would still relegate that to the fringe 20% cases.

Alright, so we have our 80%. Most people have a sample ant build.xml that they've lugged around and, when it's time to seed a new project, they plop it into place and it's got some variables that need to be replaced and then it does most of the things above. Except JavaDocs and Ivy. I'd be surprised, anyway.

Maven's got all of those features - right out of the box - in 5 lines of XML and a standard directory structure. This is where it stops being a fair fight. No matter how much you tug or pull against that list above, chances are you're at least going to use Ant to compile. No way around it. Even the simplest Ant configuration requires more exertion to acheive that than Maven does. This point, and this point alone, is why I'm just not convinced people are taking a look at this and understanding it. If the goal is simplicity, then there's nothing simpler than nothing. If you've had to put even a moment's care into that list above, than you've already wasted time and could have been using Maven.

Now that I've gotten the soap-box speech out of the way, read on to understand a little bit about it, including how to set it up to do all the things in that list (and hundreds of other things) with a few directories and a 5-6 line XML file (the 5-6 lines comes from my formatting. It could easily be 3 lines of XML, if we're honest.

Things To Know

Where Can I get Maven? Maven is freely available, just like Ant, from Apache. Alternatively, many distributions have it in their repositories. For Ubuntu, it's

sudo apt-get install maven2
This version, as with all repository packages, is slightly out of date. But, at least you're off and running.

How Do I Install Maven? The simplest way is, like Ant, to unzip it, and add the bin folder of the directory to your system's PATH variable. Alternatively, skip to the next question and simply use your operating system's repository to install it, if possible.

How Do I Build a Maven Project Building a Maven project is easy, as the command never changes.

mvn 
install
This is true whether it's your project or somebody elses. It's predictable, and consistant. To use it, ascend to the highest directory in the directory tree that contains a pom.xml file. That's usually the parent project. Usually, Maven projects cascade downwards, so you might try issuing:
mvn install
This will generate a target directory in each project (if there are any). Inspect the target directory for your .jar or .war, or whatever you're expecting. If for some reason there's no target directory in the directory that contains the source code you're trying to build, descend into it to the point where you're adjacent to the pom.xml. Then, issue again:
mvn 
install

How Do I Bootstrap a New Maven Project The simplest setup requires the creation of directories as well as one XML file. But, you'd likely create these directories and at least one XML file with Ant, too.

Run the following on the command line. NB: I haven't translated for Windows. I'm sure it's easy enough, there, too.

mkdir -p 
myproject/src/{main,test}/{java,resources}
You can change myproject to whatever you want. This will create a directory structure like the following:
jlong@studio:~/Desktop/myproject$ find . 
. 
./src 
./src/main 
./src/main/resources 
./src/main/java 
./src/test 
./src/test/resources 
./src/test/java 
If you're just getting started and aren't test-driven, then you can ignore src/test/*. That leaves you with src/main/{resources,java}. Java code goes in src/main/java. Things you'd like on the classpath of the same artifact, such as Spring application contexts, go in src/main/resources.

Finally, you're going to need an XML POM file. POM standards for "Project Object Model," I think. It's the sole center for configuration related to your project. No need to do includes, or externalized configuration or anything. The simplest pom.xml looks like:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd"> 
 <modelVersion>4.0.0</modelVersion> 
 <groupId>com.yourproject.crm</groupId> 
 <artifactId>utilities</artifactId> 
 <version>1.0-SNAPSHOT</version> 
</project> 
You can copy and paste that into a file called pom.xml, at the root of the myproject folder created above. You're done.

From here, so long as you're just planning on using the JDK, etc, then this will work fine.

What do those directories and 5 lines of XML buy me? Think of that as being equivalent to hundreds of Ant targets. The project already has enough information to, among other things:

  1. Generate javadocs: mvn javadoc:javadoc
  2. Compile classes: mvn compile
  3. Compile and generate an artifact (a .jar, in this case): mvn install
  4. Generate a Checkstyle report: mvn checkstyle:checkstyle
  5. Or, in the alternative (and perhaps a complement): generate a PMD report: mvn pmd:pmd
  6. Build a web site with documentation on the structure of the project (anemic thing that it is): mvn site
  7. Build a cross reference of the project's sources: mvn jxr:jxr
  8. Setup project files for your favorite IDEs: mvn eclipse:eclipse, or mvn idea:idea (NB: if you're using IntelliJ IDEA 7 or later, or Eclipse with the fabulous m2Eclipse plugin, then you don't need these plugins. You can simply 'open' the project as you would any project by importing or opening the pom.xml. Netbeans also has incredible support for opening Maven projects directly.

How Do I Add JARs to the ClassPath? Short answer: you don't. You let Maven handle it for you. If you need a .jar, more than likely, it's already available in some repository, in the same way that a package might be provisioned by an operating system (such as Windows Update on Windows, apt on Debian distributions, rpm on RedHat distributions, port on OSX, etc..). For Maven, using a depdendency is as simple as identifying it and adding the metadata to the pom.xml.

There are many ways to "find" a .jar. The simplest is to start browsing a central repository and opening the pom.xml files. To add a dependency, you need it's <artifactId>, its <version>, and its <groupId>. These elements are usually at the top of all pom.xmls. To add a dependency on the Apache Commons Lang library to our project above, add the following lines to your pom.xml, right before the closing <project> element:

<dependencies> <!-- plenty of room to add 
dependencies --></dependencies>
Inside the dependencies section, you will add all your dependency information. The information you enter could be that for a third party .jar, or a .jar in your own project. Perhaps one team's project depends on another's. If Maven can't find the cached version of the .jar, it'll download it for you.
 <dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.4</version></dependency> 

To test, simply rebuild it as before: mvn install. Most of the IDE integrations will have suport for updating the project configuration in the IDE (i.e., the classpath) according to what's in Maven's configuration. If you'd rather not spelunk through the ibiblio repository site, you can always use one of the many Maven repository indexes. A good one is Maven Search. Type in a fragment of what you're looking for and it'll provide you with matches. Thus: I entered "commons-lang" and it found results. Additionally, most of the IDE's will have support for some form of repository browsing.

I'm Test Driven! This one's easy. If you do want to use JUnit (or TestNG), then fret not - that's Maven's default M.O.! By default, any JUnit classes put into the src/test/java folder will be compiled and run before proceeding with the build.

The Tour's Over, What Did You Think?

In this guide, I've given a walk through to the questions I can imagine thinking about when setting up a project with Ant. The result is that you can get a LONG ways with nothing (the minimal pom.xml).

The balance of a given effort is the 20% stuff. As they say, the 20% cases can take 80% of the time. I can't speak to whether this is true or not as Maven's never delayed me, for any particular length, except when I was pushing it to do stuff that nothing else, including Ant, could have done. Even so, if you hit the 20% cases, you can rest easy in the knowledge that Maven is built to be flexible and extendable. It's whole model is exposed as a lifecycle. If you want to inject custom logic at a custom point, doing so is easy. It's also insanely interoperable. In fact, even if you don't want to use Maven but wan't to get a very high quality build script, setup the project using Maven and then use mvn ant:ant. It'll generate an ant script that'll handle most things you'd want to do. Finally, if you decide you absolutely can't live without, or translate effectively, an Ant script, there's good support for running Ant scriptlets inside of Maven.

Go ahead and give it a try if you haven't tried it before or if you were put off. It's truly powerful. The most visible testament to this are the ideas (like Ivy) that are inspired by it in Ant.

August 24, 2009

Building Servlets With Spring

The Problem

Earlier, I wrote about having to build a solution using servlets to write out the contents of the RSS feed for my blog. I am using JSF on this site. There are solutions - like Pretty Faces - that work and provide a lot of flexibility for mouting JSF logic at a given URL. So, initially, my RSS and Atom feeds were being handled by a backing bean in JSF. Being JSF, this necessitated the need for a session cookie (even though, clearly, the RSS / Atom feeds are stateless.)

The cookie wouldn't have been so bad, except that - I think as a consequence - RSS readers consuming the blog were being constantly refreshed for the entire contents of the feed, because to them the resultant blog requested was "different" than the previous version.

The Solution

So, I planned to write a servlet that handled the requests and I expose that in my JSF application. This would be a clear differentiator between the new Spring + JSF version of the software running my blog and the old Spring MVC version: it's uselessly difficult to support stateless endpoints with JSF, where as it's as natural a goal as anything in Spring MVC.

Using a servlet meant I'd lose two advantages I'd had in the JSF application with Pretty Faces: bookmarkable URLs, and the convenient programming environment that Spring Faces afforded me, namely, configuration, dependency injection, etc.

Refinements

I decided to use URLRewrite to solve the boomkarkable URLs (yes, that means this site is hosting not one, but two solutions for bookmarkable URLs in the same .war!) and Spring's under appreciated HttpRequestHandler.

HttpRequestHandler is an interface that, when implemented, becomes serviceable by a Spring framework servlet. The interface looks like:

 
package org.springframework.web; 

public interface HttpRequestHandler {
void handleRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}

You then configure a Spring framework class (org.springframework.web.context.support.HttpRequestHandlerServlet) in your web.xml and name the servlet the same as the bean that implements the HttpRequestHandler interface is named in your Spring application context. By virtue of the fact that your HttpRequestHandler bean is a Spring component, you get all the advantages of using Spring or Spring MVC, without having to load an entire framework.

For my code, the implementation looks something like the following:

package com.joshlong.blawg.site.view.servlets; 

import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List;
import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.HttpRequestHandler;
import com.joshlong.blawg.BlogService; import com.joshlong.blawg.model.Blog; import com.joshlong.blawg.site.view.util.RssFeedCreationUtils; import com.joshlong.blawg.utils.LoggingUtils;
import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.io.SyndFeedOutput;
@Component ("feed") public class BlogFeedServlet implements HttpRequestHandler { static private String FEED_TYPE_VARIABLE = "feedType"; static private int START_FEED = 0, STOP_FEED = 500;
@Autowired private RssFeedCreationUtils rssFeedCreationUtils;
@Autowired private BlogService blogService;
@Autowired private LoggingUtils loggingUtils;
private SyndFeed buildEntryList (HttpServletRequest req, HttpServletResponse res, String type, int start, int length) { SyndFeed feed = ... // build up the SyndFeed however you want return feed; }
private void showAllAtomBlogs (HttpServletRequest request, HttpServletResponse response) throws Throwable { SyndFeed feed = buildEntryList (request, response, "atom_0.3", START_FEED, STOP_FEED); response.setContentType ("text/xml"); SyndFeedOutput syndFeedOutput = new SyndFeedOutput (); syndFeedOutput.output (feed, response.getWriter ()); }
private void showAllRssBlogs (HttpServletRequest request, HttpServletResponse response) throws Throwable { SyndFeed feed = buildEntryList (request, response, "rss_2.0", START_FEED, STOP_FEED); response.setContentType ("text/xml"); SyndFeedOutput syndFeedOutput = new SyndFeedOutput (); syndFeedOutput.output (feed, response.getWriter ()); }
public void handleRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String feedType = StringUtils.defaultString (request.getParameter (FEED_TYPE_VARIABLE)); if (StringUtils.isEmpty (feedType)) feedType = "rss"; if (feedType.equalsIgnoreCase ("rss")) showAllRssBlogs (request, response); else showAllAtomBlogs (request, response); } catch (Throwable th) { loggingUtils.log (ExceptionUtils.getFullStackTrace (th)); } } }

Thus, it's simpler than a standard Spring MVC controller or a struts controller (though admittedly lacking a lot of the frills - this happens to be a simple use case.

I then configured the web.xml for all of this:

 
   <servlet> 
       <servlet-name>feed</servlet-name> 
       <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class> 
   </servlet>
<servlet-mapping> <servlet-name>feed</servlet-name> <url-pattern>/urlPatternForFeedServlet</url-pattern> </servlet-mapping>

Note that we've used the name fo the bean (configured using bean classpath scanning, so the name is in the @Component stereotype at the top of the class - "feed".) for the servlet name. Sure, it smells a bit like engineered coincadence, but it works well.

From here, all that remained was configuring a URLRewrite rule to map the servlet to the endpoints visible on the site right now ("/jl/entries/blog.atom", and "/jl/entries/blog.rss")

Hope this helps somebody...

August 22, 2009

Quick Update to RSS

I just published a change to the code that should hopefully prevent readers (like Google Reader) from constantly requeuing all my old blog entries as "unread." �I don't know if it'll work (I've never had to debug this particular web client!), but we'll see.

I suspect the issue is something like the following: the spider hits the page which in turn causes it to get a cookie from Java Server Faces, which makes the blog feed look "new." I've checked the last modified dates and so on using Http Live Headers and the Last-Modified dates and everything look alright. Anyway, I'll post back with results once they manifest (or, hopefully, don't manifest!)

Succinctly, the change involved creating a servlet (sort of) and using that to write/render (I wanted to say "feed") the feed.

August 20, 2009

Component Oriented Architectures

Warning, this blog entry is as much a rant as a blog, and tends on the somewhat lengthy side. You've been warned. I'm looking for the secret of life, as always, and failing it, I'll settle for the secrets of software. This is a blog I don't know how to write, but have wanted to, for a long time. I suspect getting it out on paper will let me revisit with more clarity later.

Prompted by Brian Sam-Bodden's musing on the subject a week or so ago on Twitter, I've been ruminating on the notion of a "component." I think that the evolutions of modern day software development are embodied in the notion of a component, not a "service," or a "bean," or anything else. Those words don't convey enough.

Thinking about it, a "component" can be broadly defined as a thing which integrates readily into a bigger thing - that is, it's adapted to the thing that uses it, and any other such thing could be made to follow suit, with the same adaptations. The container is composed of components.

Getting more specific, we think about a component in software as a thing that is integrated into a container and that can only function as a subordinate entity to the container. In practice, this vague description manifests itself as class that implements an well-known interface. Sometimes, being a component means is simply a matter of letting the container control when the component starts working and when it is stopped. Here, you might not even need to implement an interface since object creation and destruction or (typically!) built into the language itself, and thus there's no need to codify it further.

This ends up quite often being too much of an abstraction. Something that is everything is also nothing. So, again, in practice it's a matter of establishing a common interface. In recent years, the "interface" for a component has evolved beyond the literal notion of a language interface and can be any number of things now. After all, all the interface does is distinguish an object as being a component in a sea of non-components. Such a distinction can otherwise be made, as with annotations or attributes in the Java and .NET platforms, respectively.

So, a component is something that belongs to a container and that so marks itself as usable in that container with an interface or some other distinguishing feature.

Now, when the component is deployed, it sustains some sort of behavior, perhaps over a period of time. There is often a setup phase and a destruction phase. This implies a lifecycle, to setup state to begin servicing requests and to stop servicing requests. This lifecycle might provide hooks tot he component unique the containing environment.

Because the component exists inside of a container, collisions are apt to occur. Language features like assemblies or packages help isolate a component, but often the container will provide addressing to further isolate a component from its siblings.

At this point, I think, the nuances are what qualify the application of a component. If we agree on the previous points applying to most components, then surely we agree that following aspects apply only to some components. The specification is where the term component is starts being prefixed, i.e., "web component," "service component," etc.

Analyzing these definitions, a HUGE number of things could be consider a component.

  1. the now-defunct Avalon framework had "components"
  2. Spring has a @Component stereotype that marks beans as "components"
  3. JCDI - the pending DI component model in JEE6 describes "components"
  4. Indeed, EJB's original documentation spoke of EJB "beans," which you might argue was Sun's jargon for "component."
  5. The web frameworks Tapestry, Wicket, Echo, etc, provide components for the user.
  6. The Java UI model, Swing, provides components
  7. The J2ME and Android mobile phone platforms provide "components"

The list goes on and on, but you can see plainly that the idea of a "component" is not new. A component by any other name...

These various notions of a component - though not all of them - share several more concepts which we might describe as key to any description of a component.

Most of them provide some way to export state. In Tapestry, Seam and JCDI, you can "outject" values, effectively binding an internal value to a client's state, so that the internal state is reflected in the external variable when state inside the component changes. This is often called just "binding," and is -usually -an abbreviated way of responding to some event and then synchronizing client state with the state of the component manually. JavaBeans themselves, a core tenant of the Java platform, provides this notion of properties, which are nothing more than accessor/mutator pairs by which state may be shared in a generic fashion. The Dojo JavaScript framework, Wicket, Echo, and Spring, ASP.NET, and Swing all provide support for broadcasting state changes as events. This tends to be very effective as it decouples the listeners from the component itself.

In this discussion I've lumped both events and properties as goals by which to achieve the same thing, and though these concepts are not present everywhere, they're key for good components in this author's experience.

In this respect, Delphi, C# and Scala and other languages that embrace these concepts and codify events and properties have the edge. Software development can't be about being able to bundle state and functionality, it has to be about components that play nicely with each other, not in a box but in an ocean. Promoting the ideas behind a component promotes decoupled, and well behaved, software.

Indeed, the trends in software development themselves beg for components. Grids, with many concurrences and actors at play, are very well suited to components -services exposed behind a publish/subscribe mechanism. Services so exposed publish functionality that other actors in the system can consume if they can address them. This sort of dynamism is already alive and well in things like Jini or GridGain. The components themselves comply with a life-cycle for their respective containers.

The very idea of a component - things out of which something bigger is composed - implies composition. The biggest thing to come out of SOA is the push towards service reuse and composition, which components encourage.

Clearly, I'm thinking this through as I write it, and so any input's appreciated (good, bad, or indifferent.)

The addressability part is key. Brian mentions the notion of a REST-ful component. In the specific, he was talking about a component on a page amight be addressable, but the question is equally well put to how to expose distributed components uniformally.

Is there an ideal way to build components and to model these concepts - what's the next generation of software going to bring us? Clearly, functional languages are here to stay, but they don't preclude the idea of a component, in fact I imagine it might work for it.

What do you think? What's the most succinct way to model software? Is your architecture composed of objects and services? Of global variables and functions? Or of components? What will the architectures of tomorrow look like?

August 16, 2009

You're looking at a work in progress..

Man at work

You're looking at a work in progress.

The software that runs this site - joshlong.com - is home-brew. I built it myself, not because I feel like I'm going to do an inherently better job than any of the numerous pre-built options - furthest thing from it, actually.

I built it myself to be able to eat my own dog food. If I had to learn at the same pace I take on a new job and get exposed to a new skill set by force, I'd know much less. Practice is the only thing that can be usefully attributed to improved skills. The previous version of this site was written in Spring MVC so I could refine my understanding of the @MVC model and truly get a feeling for how it works (very nicely, I should add). I've long been a fan of Tapestry and have built numerous sites with it. I figured, with all the new work going on in the JSF world that it was time for me to refresh myself on that platform, especially as JSF 2.0 creeps ever closer.

JSF has seen major "upgrades" (in lieu of actual upgrades from the specification) from JBoss, with Seam, and with the Spring Faces support from SpringSource. Additionally, RichFaces and numerous other projects have evolved their component frameworks so much that result is rarely portable, but usually very nice. In effect these component libraries are their own sort of framework and often carry their own specialized support for core framework concepts like component development, JavaScript, rendering (i.e., view templates), Ajax and internationalization. These frameworks can make JSF very pleasant.

Except... when it isn't. It turns out that JSF's many weaknesses - while in some places well addressed by some of these 3rd party solutions - are not completely surmountable, and in some cases you're forced to simply "grin and bear it." This includes things like statelessness (you'll be greeted with a JESSIONID on your first request, for example), binary responses, and SEO-friendly URLs. I've talked about solutions for some of these problems in Spring MVC before, but they were to augment a capability that was already there. Here, the solutions and the home-brew components I had to put together were to avail myself of these capabilities in the first place.

For SEO-friendly URLs, I found an incredible library called Pretty faces. I'm still using JAWR, as before, but because I'm also using RichFaces - which has its own CSS/JS compression mechanism, the solution's not quite as effective as I would have liked. Still, 2 heavily compressed, minified JS files and CSS files (one from JAWR, one from RichFaces) still beats 10+ HTTP requests on non-minified/non-gzip compressed resources required otherwise!)

The blog software itself has many components, only about 20% of which is the UI layer. Thus, porting to a new UI framework's pretty easy because the back end and most of the processing are divorced from the UI layer.

But... Why?

No good reason, really. I know what you're thinking - "what could possibly be more 'website site babysitting a database' than a blog?". Since I'm trying to experiment with things, I've hit a few different places where it's paid to invest in exploiting temporal decoupling, and thus in investing other technologies. Most of these features are part of the creation of blogs, thus, not something you'll ever notice. There are two ways to create blogs on this site. An administration section in which I can log in and post blogs and save drafts is the sort of first-blush approach. It works well enough, but it's not nearly as full featured as the equivalent functionality inside GMail for composing an email. So, I create a Spring Integration integration that polls an email and posts that. It's got a white-list on incoming e-mail addresses, of course, and I've had to do a few unconventional things to make it work, but it's actually the most fluid way to deal with my blog. Not surprisingly, this feature's available in other blogging software, too.

Once I do send in a blog, processing occurs on the blog entry itself. The act of creating the blog triggers a jBPM process that prepares the blog for final publication. The jBPM process is handled in a separate VM, with JMS serving as the transactional queue that pops tasks off of the queue and handles the work. This is useful because it lets longer running tasks happen with no apparent delay to the readers of the site.

Any externally referenced images in the blog are parsed and their URLs used to asynchronously download the image, which gets stored in managed file system. Then, in the published blog, you see a URL pointing to that managed image, not the original, which means if the original disappears, my blog will still look correct.

Another part of the process involves submitting pings to the various syndicates for a blog to let them know they should update their listing. This too is something that a lot of other blog software will do, but it can take a while which is why in my software it's modeled asynchronously.

The number one reason for building my own blogging solution is, simply, that I can say I did. Because the domain model and services tier are familiar, it's easy to gauge progress with a UI framework by how quickly I'm able to build for it.

Naturally, there are many (seemingly endless) reasons not to do what I've done. However, they all focus on practicality with respect to setting up a blogging solution. They fail as means by which to practice my craft.

Having said that, please excuse any inconsistency in this blog as I'm still tweaking things (as I tend to do every 6 months or so. The software's more or less at parity with where it was in Spring MVC, having ported the UI layer over. Missing are keywords and descriptions in the meta tags, a working version of the admin section (though, as I indicated, I use the e-mail integration more frequently and that still works since it has nothing to do with JSF or servlets), working titles (ie, each post's title should appear between the <title> tags in the browser window, and I'm sure there's more.

There are many fixes in this new software, too, but ideally, you'll never notice them :-)

If you notice anything I'm missing or you think might be worth experimenting with adding in a reasonably malleable blogging platform, leave a comment. Thanks!

July 22, 2009

Composite components in JSF 1.2.x

I'm trying to build a component in JSF that in turn has several drop downs that, with the magic of RichFaces, updates the server on the state via Ajax and rerenders the components "downstream" of the component whose state has changed. This is the classical idiom of a drop down has options depend on the previous selections made. The component's used in several places on the system and it would be magnificent if we could blackbox its internals.

With Tapestry, you could build a component that does its work and then "outjects" or writes a value to a property upon completion. Imagine, for example, a login form. The login form has two text fields (email, password, or anything like that) and a backing class. As the login form component is rendered, you might have preconditions to establish, so you use the Tapestry component life cycle to setup state on the fields before rendering. Finally the text fields are rendered. When the form is submitted the fields values are updated and you have a chance to read the values and perhaps do something with them. For example, if the credentials are correct, you might do a query and create a valid User object. The User object is then set on a property and that property can be bound to a property of the client of the component. If you use the same component 10 times on the same page, they all have their own internal copy of the property and they can all update the same one or they could update 10 individual properties. That is, the "backing bean" is scoped to the component, not the page.

The difference with JSF is that for any kind of composite components you have to do soething like building the tree or using Facelets. These components will in turn require some place to store the values they submit. For the above example of the login form, the user name and the password need some place to be stored. Since facelet ui:components don't have their own backing bean, you need to provide the backing bean for the values. Thus, it's up to the client of the component to provide storage for internal state of the component. Not very component oriented. And, more to the point, it quickly becomes untenable if you want to use the component more than one time in the scope the backing bean lives. That is, you can only use the component once per request or once per session (without creating new backing beans, at least).

I know that JSF 2.0 will feature better support for composite components, but I need this to work on JSF 1.2, and have not managed to find many good resources / examples on how to build a sophisticated UIComponent subclass so it can handle its own storage.

Anybody have any ideas?

July 19, 2009

JoshLong.com on EC2

This is my first working version of the system being posted from the EC2 cloud. Performance seems alright. I'll update as I dig more into the capabilities. So far getting things up and running has been relatively painless. There's something inherently awesome about being able to login and setup your own server without having to beg for certain extra capabilities.

I like most that this could eventually grow with a minimum of fuss.

June 15, 2009

My talk on Spring Integration At TheServerSide.com '09

I did a talk waaay back in March on Spring Integration for TheServerSide Symposium. If you're into Spring and want an hours worth of good wholesome ESB fun, may I humbly suggest you check out the talk. I'd love to know what you think so please feel free to leave a comment!

June 7, 2009

Tapestry 5.1

Recently, I've been playing with Tapestry 5. The experience has been extremely satisfying. Although there are issues that could be worked on, on the whole this is the most pleasant development environment I've ever use for Java Web development. Frankly, it started as just a way to keep my mind away from a main project I'm working on. I figured I'd give it the five minute test. Actually, this is the third time I 've given it the five minute test, and this time it took. What did it was release 5.1, which sports a few features that indicate that Tapestry 5 is becoming a very "practical" choice, not just the right one.

Tapestries 5.1 sports the ability to gzip compress, as well as consolidate, JavaScript files. It does other things with images and css, too. It's not just yet on par with JAWR - which, honestly, I love - because there's something freeing about knowing that if your page needs libraries x, and y, that there's a component out there that's doing everything possible to make the impact of inclusion of that library acceptable. CSS and JavaScript are to the web what "jars" are to the JVM: an encapsulated packaging of externalized, reusable functionality. Being able to optimize loading them, then, is crucial.

Knowing this, I decided to give it a look. I got into it, just a little. I used the Maven Tapestry archetype and created a separate project. Downloaded Tomcat 6 and even loaded Eclipse 3.4. I imported the Maven project using the m2eclipse plug-in, setup a Tomcat 6 server instance, and deployed my application to the instance. I configured Tomcat to "serve modules without publishing," and disable auto publishing. Then I crossed my fingers and hoped for the best. I loaded the browser and hit the front page. The site that's generated is pretty, but boring. It does, however, prove inviting. I returned to Eclipse, associated the HTML editor to *.TML files, and then started hacking. I started with a change to a .TML file. <h1>Hello, world!</h1>, placed in the middle of the Index.tml file. I refreshed. It worked...! I went to the Index class itself, and added

 public String getMyMessage (){
        return "Hello, moto.";
 } 

Then, on the Index.tml file, I added ${myMessage}.

Again, I just refreshed the browser, and it worked! In comparison to Tapestry 3 and 4, this was great. But I've blogged about Zero Turnaround's JavaRebel product and I've certainly seen Tomcat do some neat things with regular Struts projects or Spring MVC projects. I wasn't.. aghast, just yet. Finally, I started getting into it.

I have used the various versions of Tapestry before, so I knew - essentially - what components to expect and essentially what to imagine possible. I had programmer courage. So I was a little more ambitious and decided I'd tackle something a little more ambitious. I started with a component to provide a panel. The panel would have a parameter for a ValidationTracker, which is the object that keeps track of what validations have occurred on a @Form component (very much like ActionErrors/ActionMessages in Struts. The panel would turn red if there were errors in the form it contained. This was a hard thing to do before because Tapestry had issues with the order of the layout of the components.

Suffice it to say, it worked. It was also blissfully simple. No interfaces, not even annotations if I didn't want them. I was able to parameterize the title of the panel using a @Block (like a facet in JSF). In a package adjacent to my test page, I added a simple POJO, with a few accessor / mutators (a Customer class, with the usual sort of properties..). I declared an instance of it on my test page's class and added a @Property annotation to it - I didn't have to even create a java bean style accesor! I added a Form and a few TextField components to the class, too.

@Component (parameters={"value=customer.email"}) private TextField email ;
@Component (parameters={"value=customer.password"})  private TextField password ;
@Component private Form form ;

On my page, the I had:

<form t:id="form">
 <t:label for="email" /> <input t:id="email" /> <br/>
 <t:label for="password" /> <input t:id="password" /> <br/>
 <input t:id="signup" type="submit" />
</form>

This seemed like enough, so I hit refresh and .. unsurprisingly, it worked! Naturally, this doesn't do anything. I wanted to make the Form component do something on successful submission. I looked around, and the simplest way to do that was to name a method as though I was descrbing it in English:

  void onSuccessFromForm ()  {
    System.out.println ( new ReflectionToStringBuilder ( this.customer).toString ()) ;
  }
  

And of course, that worked! It's worth mentioning that during all of this - method additions, field additions, component adjustments, etc, I've not redeployed or published or even waited for more than a split second even once. The 5 minutes had become an hour. The reason I write this blog is because I'm now well into hour 7, and I'm thoroughly impressed. It's actually fun to work in. If you've ever had that wow! moment in a dynamic language where you just can't beleive how nice it is to hit refresh and work, then you'll appreciate Tapestry. I can't usefully compare it to another Java framework because there's nothing like it. It's liberating. Check out Neal Ford's amazing "On the Lame From The Furniture Police" to watch a discussion on keeping focus, flow while working. In it, he basically discusses just how damaging a minute idle time is when developing an application. Tapestry breaks that cycle for you. No more flow stoppages. I've become impatient with the browser's ability to repaint, actually!

I wholely recommend you take a look at Apache Tapestry 5.1.

June 5, 2009

My Los Angeles Musings, Seam, Tapestry 5, JavaOne, Spring Workflow, Spring Python and more

Hello, world.

My life has been utterly and completely busy for the last several months. I don't know about you, but I love it when that happens, even if it does take me aay from priority things like maintaining this blog. I'll take this post to sort of stretch my blog legs out again, and then try to establish a blog with more frequency.

When last I wrote, I mentioned that I had moved from Phoenix, AZ to Los Angeles, CA. I started work on April 1 (cool company, nice people, interesting software, moving on...). I worked pretty consistently and started looking for a place to stay as I was at that point lodging with my mom. My wife came from Phoenix, AZ a month later, May 1. She stayed back while I sort of scouted ahead and started work. We've found a nice apartment in Canyon Country, CA, which is, honestly, very pleasant. It's far away from Los Angeles proper that the prices seem acceptable, but close enough that I can make my 20 mile commute in about 24 minutes, which I appreciate. I've also enjoyed (surprise surprise) the weather, which has been beautiful of late. As an example, as I write this it's very, very early in the morning, just after midnight, on Friday, June 5. The temperature is 88F in Phoenix, AZ right now, and 59F here in Los Angeles, CA. Couldn't be happier. Nothing like being able to program with the air conditioning off in the winter. Frankly, I've really just sort of enjoyed the little things.

I don't mean to gloat, but it's amazing what you take for granted when you live here. It doesn't hurt that the economy's so bad it's sort of leveled out the prices, making parts of Los Angeles very approachable for somebody who's used to Phoenix prices. I'm a fan of AT&T's Uverse ISP here in Los Angeles. I had COX cable in Phoenix, AZ. I paid about $130 a month to get two DVRs, cable internet with very limited storage and no ability to share among the bedrooms and almost no channels. Not to mention, I couldn't get a static IP (the shame, the humanity!) without a business account, which given how little I liked them was out of the question as it would've compelled me to accept a year long contract. Needless to say, all of that's been improved, and I pay less, and I have a much wider channel selection, to boot!

Of Web Frameworks

I've had the chance to play with some very cool technologies in depth of late, one of which is Jboss Seam. I've had issues with Java Server Faces in the past, and have even spoken to some of the issues I've had, but nonetheless it works and, when taken together with something like Tomahawk, Facelets and the various Spring integrations, you can be productive using it. Naturally, JSF has it its battlegrounds, and really scalable, stateless applications with Google indexability is not one of them. Knowing that, you can get it to work. Seam rectifies some of this and worsens it, as well. I've had an amazing time sort of rethinking through problems, learning how to approach things the Seam way. If you let your mind wander, it seems like it's very easy to produce terrible code. Essentially, this stems from certain assumptions JSF, and Seam on top of it, make for you.

One of them is that the HTTP Session is infinite. Seam addresses some of these issues by providing a very cool concept called a "conversation" - which I'm sure we've all seen before, but which really is quite refreshing in its application inside of Seam - which models the idea that you have a unit of work that is greater than a single request but smaller than a session. This is fine as it allows you to keep state around and use it as required and then trust that, when the conversation's finished, Seam will reap all that session memory back. Additionally, because Seam components are basically stateful session beans (unless you're using Seam POJOs, in which case they're basically stateful session beans that you can't use on another framework or EJB3 stack..) there's very little clear separation of tiers. You need to find an entity inside of a JSF action listener? Grab an entity manager and issue a query, and then add JSF validation messages if you can't find it! It almost seems like a step back, honestly. This extra state, I find, has required me to whip out a debugger more times than I care to admit. In complex interactions it becomes very difficult to keep track of preconditions and postconditions for a given interaction.

The real shame to me as a person who is very fond of jBPM, Seam doesn't force the concept of conversational state far enough down the throat of the users. JBPM is definitely well integrated, but it's not required. It's also very possible to eschew altogether jPDL based Seam navigation, which makes for an application that has complex continuations and state without rail guards within which to advance. Anyway, giving it credit where credit is due, it's definitely better than raw JSF. I've also come to very much like Ajax4JSF and RichFaces. Part of me cringes when I realize that even simple Ajax requests are basically re rendering the whole page (or, rather, most of the body and several additional script tags), and in the process making the net burden of a given interaction with the server for certain pages on the order of several megabytes of un-cacheable Ajax JavaScript and HTML. The other part of me is utterly stunned with the richness of the results. It does, really, work. Taken together with some of the awesome features Seam itself provides (why couldn't they have just chosen Tapestry? Such apparently talented people working on JSF seems like a crime...)

I can't help but feel, sometimes, that we're heading down the path of ASP.net with JSF. ASP.net is a component based framework, and component based frameworks like Wicket, JSF, and Tapestry all fundamentally are familiar to somebody who knows ASP.net. ASP.net has a slew of components that you can use and which rammed a lot of state down the clients throat to keep the illusion that the programmer was dealing with a Windows Form application. This worked well until, one day, you wanted to override a style attribute on some component that had inline the CSS and no assigned ID. Now, you were fighting with the framework to restore your will. In this way, I feel like JSF is very similar. When I use Ajax4JSF, RichFaces, and Seam in general I am able to easily forget that I'm working n top of a statless protocol where every request has absolutely no idea what happened just one request before it but for the graces of a cookie or a state field in the request. This is why ASP.net MVC was birthed, to provide an approach for those that wanted more fine grained control. In this way, the .NET community has sort of reversed our evolution in the Java community, going from the action-oriented Strutses and Webworks and even Spring MVC, to the componented oriented JSF, Wicket, Tapestry and GWTs of the world.

Using JSF/Seam, I even forget about the cost of state a little bit. State's what it's all about. The Seam proponents will insist that storing state on the HTTP session is far more efficient than in the database, which is inherently less scalable. In theory, I agree with this. However, Seam still hits the database for non cached data (if you have that setup!), and you're still not excused from reconciling optimistic lock exceptions using Seam, and it leaves you with an HTTP Session brimming with state and a HTML that can easily grow to be several megabytes for midly complex UI interactions and their components.

I have met people who were under the illusion that servlets (raw servlets) had a session by default, that it was to be taken for granted. I've spent a long time building applications where the goal was to avoid the session at all costs, until absolutely necessary (make your Struts beans request scope, turn of JSP sessions, and if you're going to do redirect after post, either encode the state in the redirect request or be darned sure you use what's now being called "flash" scope, session persistance in the service of just two HTTP requests.

Anyway, having invested so much in understanding and learning Seam, I decided I might as well give Tapestry 5.1 a chance, as it's been a few years since I had a chance to work with Tapestry, and that was Tapestry 4. I always had a personal fondness for Tapestry. It's always been session friendly by default and to be efficient as a component oriented framework. This has led to some gimmicky approaches (the render/rewind cycle, and lack of support for dynamic (read: programmatic) component creation and attachment)

I spent a little time getting used to it. I have to tell you, given my experience with ZeroTurnaround's JavaRebel javagent for Java class reloading, I really appreciated the intrinsic support for class/component reloading in Tapestry. As a development environment goes, I haven't had this much fun since Python on a web application. Truly amazing. I was somewhat disappointed to see that Tapestry has slackened it's feverish refusal to use the session, and made everything redirect after post unless specified otherwise. The implication here is that there's some session. It's still very efficient, and I've not caught it trying to store an entire backing bean (page or component) in the session yet! If you have a chance, I wholely and completely recommend it. It's lacking support for the things JAWR (a JavaScript/CSS) compression filter) provides - though there seems to be at least some effort aimed at adding it at no additional technical cost to the developer. It just works.

The World At Large

I sat, jaw agape, as the rumor milled tossed around the notion that IBM would buy Sun, and wondered what would become of some of the interesting technologies inside Sun. Imagine my surprise when I woke to find the rumors quashed and Sun bought, by Oracle of all things! I couldn't believe it. Larry Ellision took the stage at JavaOne and reaffirmed interest in JavaFX. JavaFx is one of the few decent options we have in the Java client landscape, and even if I never write an application in JavaFx itself (I once tripped and learned ActionScript 3 and Flex programming, and I don't think I could see the value in switching now..), the work done to support JavaFX has been a boon for the JVM/JDK. Hopefully, this innovation will continue.

SpringSource has been doing a lot of great things of late. Spring Roo is a promsing mechanism by which useful prototype applications can be created on the fly, a sort of Spring-y version of Rail's application generarots. Spring IDE being released for free, which is a boon as somebody who's used OSGi without good tooling, and - most interesting to me - I discovered Spring Workflow, which looks very promising indeed. I am a huge fan of a good BPM engine, and it's something fundamentally hard to do correctly. Enterprise BPM engines are even harder. Hopefully, Spring Workflow will remedy some of this. Finally, I couldn't help but note the amazing progress of Spring Python. I adore Python, and have used it in anger many, many times over the last decade. It's never failed me. I'm pleased to see Spring's offerning not merely being a Java-Spring that happens to be written in Python. This framework seems to be geared towards the Python way, even going so far as to remind people in the (incredible) documentation that if nothing else, the libraries Spring Python provides can, and very well may be, used independant of any XML format!

Additionally, May saw the debut of Google Wave, which seems to be an incredibly cool platform on which to build. I'll be very interested to see what comes of this.

I wonder what the next month will bring. I'll do my best to keep this blog up to date. I've heads down on a lot of work, and a few cool surprises I'll share when appropriate. By the by, I encourage you to follow me on Twitter at http://twitter.com/starbuxman.

<< Last | Next >>