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

So Much to Do, So Little Time!

Spring 3.0's out (you didn't get the memo?), and there's a lot of interesting stuff. This release has been long in coming due in no small part to the specifications it tracks and to the intense furvor and emphasis placed on quality assurance and testing. One target platform - JEE6 (and with it the final versions of JSR330) - also just recently went final, and you'll find support for these technologies, as well, where appropriate. Now that it's out, you can start certifying applications in production on it. I've found that - aside from dealing with the new Maven imports - the upgrade process has been flawless. I've taken complex applications and merely fixed the jars and they continue to work. You will find, however, that there are a lot of reasons to go through and start selectively enabling new features, and namespaces.

In our book Spring Enterprise Recipes, my co-author Gary Mak and I discuss a lot of the new, exciting Spring 3.0 features. Spring 3.0 debuts slightly more streamlined scheduling / TaskExecutor / thread pool support. The idea is that you can more readily model asynchronous, repeating (at a scheduled time, rate, or both), and concurrent programming problems using these facilities and - in some cases - do so while leveraging more advanced facilities underlying a given target platform, like the WorkerJ implementations, the Java5 task executors, and thread pools and more.

I won't go into much of that here as the book ablely covers most of it, but one thing I did want to cover (which we couldn't cover in time in the book as the feature was not ready as the book went to press) was the very elegant task namespace.

Background

It should be noted that these features are not, exactly, novel. Spring has shipped with a Quartz scheduling framework integration for years. Among many other niceties included therein was (and still is, for what it's worth) a MethodInvokingJobDetailFactoryBean that allowed you to schedule future executions of a method on a Java bean using Quartz.

A few years later, EJB 3 debuted support for a limited form of scheduling using the Timer mechanism. One major limitation was the lack of support for CRON-like expressions and for asynchronous methods. Naturally, you could use JMS to acheive the same effect, in a way...

The JBoss gang debuted JBoss Seam support for scheduled and asynchronous method execution on a Seam component as well as a proprietary mechanism to do the same with EJB 3. In Seam, using these features was simply a matter of adding the appropriate configuration (as we do in Spring) to enable the executor (they have a few, including one based on the EJB3 Timer and one based Quartz.) The usage here is familiar to what has recently been debuted in Spring 3.0.

Clearly, the need for such features is common enough that they've both been fully incorporated into JEE6 and EJB3.1. There, you can specify CRON expressions as well as defer the invocation of a method using the @Asynchronous or @Schedule annotations. A simple example looks like:

package com.joshlong.ejb.timer ; 
import java.util.Date; 
import java.util.logging.Logger; 
import javax.annotation.Resource; 
import javax.ejb.Schedule; 
import javax.ejb.Asynchronous; 
import javax.ejb.Stateless; 
import javax.ejb.Timeout; 
import javax.ejb.Timer; 
import javax.ejb.TimerService; 
@Singleton 
public class PeriodicGreeter { 
 // you could use this to schedule things manually 
 @Resource TimerService timerService; 
 // or use the annotations to do so automatically 
 @Schedule (minute="*/3", hour="*") 
 public void sayHelloPeriodically () { 
   System.out.println ( String.format ( "Hello, world, at %s" , new 
Date ()) ) ; 
 } 
 @Asynchronous 
 public Future<String> sayHelloAsynchronously () { 
   System.out.println ( String.format ( "Hello, world, at %s" , new 
Date ()) ) ; 
   // ... 
 } 
}

Spring 3.0 Implementation

The task namespace let's you declaratively configure a TaskScheduler and a TaskExecutor instance using XML. From here, you can configure beans that have scheduled, or asynchronous, executions using the XML or - my personal favorite if you can get access to the code - via Java annotations.

Here's an example Spring application context featuring this namespace and configuring a scheduler and executor with default-ish settings:

 
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:task="http://www.springframework.org/schema/task" 
   xmlns:context="http://www.springframework.org/schema/context" 
   xsi:schemaLocation=" 
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
       http://www.springframework.org/schema/lang 
       http://www.springframework.org/schema/lang/spring-lang-3.0.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.0.xsd 
       http://www.springframework.org/schema/task 
       http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 
 <context:annotation-config/> 
 <context:component-scan annotation-config="true" 
       base-package="com.yourbasepackage.scheduling" /> 
 
 <task:scheduler id="scheduler" pool-size="10"/> 
 <task:executor id="executor" pool-size="10"/> 
 <task:annotation-driven scheduler="scheduler" executor = "executor" /> 
 
</beans> 

What you do from here is up to you. You could simply start defining tasks inline with your XML. That approach certainly has its redeeming qualities, not the least of which is that your code is more readily "documented" and conceivably adjustable at runtime with some refresh trickery... sure.. you could.

 
<task:scheduled-tasks scheduler="myScheduler"> 
 <task:scheduled ref="greeter" method="sayHello" fixed-delay="5000"/> 
 <task:scheduled ref="greeter" method="sayHello" fixed-rate="5000"/> 
 <task:scheduled ref="greeter" method="sayHello" cron="*/5 * * * 
* MON-FRI"/> 
<task:scheduled-tasks/> 

...In practice, however, the annotation approach just FEELS soo much better! So, here is how you might write a scheduled or asynchronous bean in Spring.

package com.joshlong.spring.timer ; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 
import javax.annotation.PostConstruct; 
import javax.annotation.Resource; 
import java.util.Date; 
@Component 
public class SpringPeriodicGreeter { 
 // you can do everything you normally would using Spring, obviously 
 @Autowired CustomerService customerService ; 
 // this runs once every 5 minutes 
 @Scheduled (fixedRate = 1000 * 60 * 5) 
 public void sayHelloEveryFiveMinutes () { 
   System.out.println ( String.format ( "Hello, world, at %s" , new 
Date ()) ) ; 
 } 
 @Scheduled (cron="*/5 * * * * MON-FRI") 
 public void sayHelloOnlyOneWeekdays () { 
   System.out.println ( String.format ( "Hello, world, at %s" , 
new Date ()) ) ; 
 } 
 @Async 
 public void doSomething (String s) { 
  // this will be executed asynchronously 
 } 
 @Async 
 public Future<String> returnSomething (int i) { 
   // this will be executed asynchronously, but you can get the 
   // result by blocking on Future.get 
 } 
} 

Thus, this is nothing too strange - very simialar in fact to what's in JEE6. Obviously, I've not mentioned every permutation of the features from the various technologies, but hopefully this gets you past the initial cognitive "hump" of adapting a new technology. It helps that - at least in the Spring case - it's dead simple to start using it if you're already using Spring. I wonder if there will be support for working with the JEE6 annotations that describe the same things? The major takeaways are that you can get this simply by updating your version of Spring, which should be painless if you're not tied to Java 1.4. You can get the JEE6 functionality by updating your version of the platform and server, if the platform/server are ready (Glassfish is!).

Use

Now, as to where this stuff might be used, well, I can only think of a few thousand things...

  1. Quartz is probably still more powerful, but the implementation and usage are hackneyed - this new approach will feel much more elegant. You could probably get away with removing the old Quartz code and using this for most of your implementation needs.
  2. Because Spring's implementations are swappable, you could back this functionality with varying TaskExecutors/TaskSchedulers of your own implementation, if you wanted.
  3. The obvious use case is that you can now remove CRON, Autosys, Flux and any number of other third-party, dedicated middleware schedulers from your architecture (if you're only using them to run Java services.)
  4. As with Spring itself, this abstraction is useful because you can deploy it inside of a web applicatior or any other place you can imagine Spring running, so you don't need to install a scheduler if you just want something run periodically inside your web container
  5. If you have a Spring Batch job, this might be an ideal way to kick the jobs off periodically. You need to start processing the billing batch every night at 2am, but only on weekdays? This is a match made in heaven! How you get a Batch job to start running is left mainly as an exercise to the user. I recommend using an ESB (like Spring Integration) to react to events, or using a scheduler like this task namespace (or Quartz) to kick the jobs off.
  6. Spring Integration has a gateway mechanism that lets you front what is essentially a send (and/or) recieve operation on a channel (think: JMS queue/topic) with a method on an interface. I love this feature and use it a lot because I don't want to surface JMS queues / topics to the client (that's a little too loose and decoupled an API!). I also use it because it allows me to model fire-n-forget messaging using Java interfaces, which is exactly what the @Async annotation does. The other benefit of the Spring Integration feature is that the processing leaves the VM and goes somewhere to finish (ostensibly, wherever the consumer for the topic/queue lives) the job and then return the result. This provides scalability benefits to both the client and the server, whereas the @Async annotation would only increase the thoroughput of the client, in this case: processing still takes place on the node with the @Async annotation, it's simply deferred... Deferment is a valid way to increase capacity while decreasing thoroughput.
November 28, 2009

Spring Batch's MultiResourceItemWriter

If you've ever had to do batch processing, then you know how tedious it can be to write all the infrastructure code surrounding retries and error recovery and usefully handling long running processing and all the other tedium that surrounds a typical batch application. For these types of applications, I use Spring Batch, a batch processing framework from Dave Syer and the fine people at SpringSource.

The basic idea is that you setup jobs that have steps, that have tasklets. This the normal use case, but by no means the only one. You use jobs and steps to string together sequences of processing input and writing to output via a reader and a writer. Spring Batch has implementations for both reading and writing that will likely meet most of your needs: XML, files, streams, databases, etc. There's so much interesting stuff here, so of course I humbly recommend you take a crack at the documentation or read my book, Spring Enterprise Recipes.

That said all said, there's no obvious way to read from an input source and then write to multiple files. The use case here, in my case, is Google's Sitemaps. These are XML files that describe the pages on your site. You list every URL possible. If you have more than 50,000 links, then you must create many files and list those files in a Sitemap index file. So, I wanted to read from a database and derive all the URLs possible for content, and then write those to sitemap XML files, where each sitemap could not exceed 50,000 entries. Spring Batch ships with an adapter writer that serves exactly this purpose. It's called org.springframework.batch.item.file.MultiResourceItemWriter. You define it just like you might any other writer, except that you wrap another writer with it.

Here's the salient bits from my configuration. Most of this is boilerplate. I don't include the configuration of the Spring Batch environment, or the configuration of the reader, because those are pretty typical. Note that here we configure the writer for the job and in turn configure its delegate property, where we have the real writer implementation. In this case, there's no need to configure the delegate writer's resource property.

 
<beans:beans xmlns="http://www.springframework.org/schema/batch" 
             xmlns:beans="http://www.springframework.org/schema/beans" 
             xmlns:aop="http://www.springframework.org/schema/aop" 
             xmlns:tx="http://www.springframework.org/schema/tx" 
             xmlns:p="http://www.springframework.org/schema/p" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation=" 
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
http://www.springframework.org/schema/batch 
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd 
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 
    <beans:import resource="batch.xml"/> 
    <job id="batchForCreatingSitemaps"> 
        <step id="sitemap"> 
            <tasklet> 
                <chunk reader="reader" writer="writer" 
commit-interval="${job.commit.interval}"/> 
            </tasklet> 
        </step> 
    </job> 
    <beans:bean id="siteMapLineAggregator" 
class="com...sitemapscreator.SiteMapLineAggregator"> 
        <beans:property name="domain" value="${sitemaps-domain}"/> 
    </beans:bean> 
    <beans:bean 
class="com...sitemapscreator2.ResourceSuffixCreator" 
id="resourceSuffixCreator"/> 
    <beans:bean id="writer" scope="step" 
class="org.springframework.batch.item.file.MultiResourceItemWriter"> 
        <beans:property name="resource" 
value="file:#{jobParameters[outputResourcePrefix]}"/> 
        <beans:property name="resourceSuffixCreator" 
ref="resourceSuffixCreator"/> 
        <beans:property name="saveState" value="true"/> 
        <beans:property name="itemCountLimitPerResource" value="50000"/> 
        <beans:property name="delegate"> 
 
            <beans:bean 
class="org.springframework.batch.item.file.FlatFileItemWriter"> 
                <beans:property name="encoding" value="UTF-8"/> 
                <beans:property name="shouldDeleteIfExists" value="true"/> 
                <beans:property name="lineAggregator" 
ref="siteMapLineAggregator"/> 
            </beans:bean> 
 
        </beans:property> 
    </beans:bean> 
    <beans:bean id="siteMapUrlRowMapper" 
class="com...sitemapscreator.SiteMapUrlRowMapper"/> 
    ... 
</beans:beans> 
November 21, 2009

'Spring Enterprise Recipes,' from Apress

Warning: Shameless Plug

I am pleased to announce that, after a long time and a lot of work, my first book Spring Enterprise Recipes (which I co-authored with the indefatigable, epic and extraordinary Mr. Gary Mak, author of - among many other things, Apress' Spring Recipes) has been released and is now purchasable. It should be hitting book stores soon, but in the meantime, you can buy the e-book at Apress.com, or you can pre-order it on Amazon.com.

The book discusses Spring 3, but also accounts for the many "modules" surrounding Spring with an eye towards building elegant, scalable systems with a minimum of fuss. Many of these modules have come from SpringSource, and some are independent third party projects that integrate well with Spring. Spring Enterprise Recipes introduces concepts like business process management (BPM), enterprise application integration (EAI), distributed computing and messaging and then grounds these introductions with real-world examples using Spring and lead open source frameworks.

This book discusses both the why and the how. It starts with a discussion of the usual suspects, exploring the quintessential tools in any developer's toolbox: RPC (RMI, Hessian, Burlap, Web Services, HTTP/Invoker, EJB 2 and 3, and more), messaging (via JMS), database access (JdbcTemplate, and a few of Spring's numerous supported ORM abstractions), transactions (e.g., various transaction abstractions supported by Spring), and numerous services like e-mail, JMX, worker pools, and scheduling infrastructure.

Then, we progress into more advanced solutions. This book includes the first-in-print or most updated coverage of a lot of technologies, including Spring Integration (a lightweight ESB-like integration framework for EAI), Spring and jBPM 4 for business process management, GridGain for grid computing, Terracotta for clustered state managment, Spring Batch for batch-processing solutions and OSGi to bring modularity to your application.

In the large, this book is a gentle, but comprehensive introduction to the best-of-breed solutions for tomorrow's architecture using Spring and other lightweight, powerful tools. Having said all that, I hope you'll consider it for your next purchase and that it helps you solve some interesting problems and build even more interesting solutions!

November 17, 2009

Understanding Go

Go, a new language from Google, has created quite a stir. It has a great pedigree, owing to renowned experts like Rob Pike (a member of the Unix team, and a creator of the Plan 9 OS from Bell Labs.) The language is a procedural language (like C, or Python) which offers a strongly typed, but flexible type system (not centered around object-oriented facilities as we know them from languages like Java and Ruby). The syntax is a strange mix of C and Python. Honestly, it feels like C when you read it, but it writes more like Python - lots of features in the syntax that are designed to be consistent, predictable.

One blog entry prompted a very lively discussion of the language: it made the comparison that Go seemed awfully similar to Algol 68, a language 40 years past irrelevance. The blog entry said that while Algol 68 was a nice language, Go might be considered an efficient language. It claimed that efficient languages are the ones that - ultimately - propagate. Witness COBOL, C, C++, and Java, for example. Go, thus, may very well be a very efficient language, but it's not even close to a nice language. It's a lost opportunity.

Programming languages tend to come and go, but they all advance basing their innovation in some small part on their predecessors. Programming languages have to evolve slowly. Languages do not exist in a vacuum. They must respect the work that's preceded them, while innovating. They must strike a careful balance, never alienating the existing community, the legacy base, and always advancing the state of the art. Doing so incorrectly can be the biggest sin a language can make. Kowtowing to the legacy of C crippled the evolution of C++, leaving it a confusing mix of phantom requirements and artificial features. Conversely, Java achieved meteoric propagation because it looked and felt like C++ without many of the warts. This made the transition to Java easy. Compatibility is a double edged sword.

Most recent languages look and feel like C/C++. They've innovated ever so slightly, inducting into the syntax features formerly handled by libraries. Or, the language is flexible enough to support requirement-specific DSLs. You can see this with Scala and Groovy, Ruby and C#. They're all fairly familiar, but offer advantages in their grammar over their predecessors. C#, for example, introduced LINQ, while Scala surfaced its concurrency facilities as an Actors DSL. The idea of a language syntax as a differentiators is even more relevant of late. The .NET runtime popularized the idea of a multi-language run time. It meant that choosing a language did not mean forsaking libraries. The JVM has matured, and there are many languages implemented atop it, as well. Other infrastructure VM projects have emerged, like the LLVM.

So, I don't blame Go for looking so much like its predecessors. That's the cost of doing business. It's intended to be a general purpose language, after all. It does have a few unique features surfaced as language constructs, like intrinsic concurrency facilities, which it calls gorountines.

I don't understand why they have built another virtual machine. If Go is going to innovate, it will be in its Virtual Machine. Why not the CLI, JVM, or LLVM? The language has strong support for interop - easily wrapping native code much like you might using C++. The .NET CLI supports this sort of thing, though. I understand the language needed to run on Unix (at the moment, you can't run it on Windows!), and perhaps Mono wasn't sufficiently advanced. Why not the JVM? Would building that kind of infrastructure be that hard? What about the LLVM? It seems well suited to working on Unix and to handling interop. Perhaps interop is not the only concern. The implementation of the goroutines seems to have been a priority. The language does not yet have assertions or exceptions specifically because doing so would be awkward with goroutines. This language, as Mr. Pike explained it, was created for Google to build servers. Cheap, and efficient threading was priority #1. This piques my curiosity. Why could the JVM - which hosts Scala and Clojure - not be used to build goroutines. Is there some fundamental flaw that makes concurrency on the JVM a non starter? I don't understand.

I would agree that the language is not particularly novel. What I don't understand is why the VM is novel. Clearly there are requirements I don't understand, and this is why I think Go will be worth paying attention to, in much the same way Erlang is.

There is also something refreshing about a genuinely new language. New platform, new libraries, new syntax. Programs written in a language like that represent advances. Shortly after the debut of the language, a command line Twitter client emerged. The example is promising - by definition the implementation was from-scratch. It was quick, and the result is imminently readable.

Perhaps I'm over thinking this. Perhaps the language will be successful because it's simple, and efficient. Perhaps the VM is some how unique and better served by a custom implementation. Only time will tell.

September 10, 2009

CRUD's Not The Answer

I was really glad to see Udi Dahan's, "Don't Delete. Just Don't." I wholely agree with the main premise - that deletion is rarely, if ever, a valid business state and that care should be taken in dealing with it. He cites various examples, saying, "The real world doesn't cascade." His example is of a marketing department that deletes an item from the catalog. Should all orders containing that item then be unlinked? Should they redo the company's profit and loss statments?

His example's a perfect illustration of a valid case where care needs to be taken both in modeling the case and dealing with it in code. I fear a lot of people have gotten hooked on instant-models or CRUD "frameworks." The idea that you can annotate a few entity classes and suddenly you have a model and business logic all taken care. A lot of this became popular with Ruby on Rails and has only gotten worse in the JEE world. It's now common to expose EntityManagers to the web tier (both the Seam and Spring Web Flow examples, not to mentino the Open Session in View pattern itself, speak to this) and to let web frameworks handle the lifecycle of entities and committing transactions on that EntityManager to persist those entities. We now think of record creation and managment as so mundane that we've automated it and surrounded it in scaffolding.

Unfortuntately, this misses the true value. Objects in a system have state that has dependencies. Just because an entity has a (required) no-args constructor, it doesn't mean that you should not write a constructor with dependencies. A lot of this stems from the "active objects" or "naked objects" pattern, where objects are open books whose state can be mutated on the UI tier directly and those changes propagated directly. We tell ourselves that we can apply Hibernate validations (or validations in any other ORM framework) and that we'll guarantee valid business constraints thus, but it rarely works out that way. Prescribing the valid creation and destruction of an object is critical.

The most insidious part of this abuse is that it rarely ever occurs in the first iterations of a project, only in maintenance. People "forget" how an object is created, or destroyed. They forget details. Consistancy with other parts of the system is forsaken because, after all, how much could there be to it? This happens more often than you'd expect: new people come on to the team and are assigned to rework an existing feature and screen in a system. Institutional knowledge is important but it's not always easily transferred, so safe-guards need to be taken.

Plus, as business evolves, object creation is often only part and parcel with a larger process. If a new customer is added to a database, and nobody does anything with it, did it really get added? Put another way: if a new customer gets added to a database, there's an implied lifecycle that customer must follow. Perhaps a trial period window and then a follow up email? Perhaps a monthly subscriptio fee? Who knows, but the act of instantiating a Customer object and then issuing entityManager.persist ( customer ) will rarely, if ever, be enough.

Indeed, I've seen many projects build their models using only a GenericDao<T> variant. This is dangerous. Transitions from one state to another for an entity can often cost money.

Do things the old fashioned way, building services that handle the business operations, not merely Create, Read,Update and Delete objects. Using Dao's in a view tier is almost as ghastly a sin as making JDBC calls from the view, and encourages the same kind of copy-n-paste code reuse we prided ourselves on having moved away from.

While the services approach isn't exactly code-generation friendly, it can pay off in the long run. As soon as you decide to use your services in a phsically separated tier, you'll be glad. It's easier to build services that express every dependency as a method parameter. There are several reasons why this works out. While web service support is getting better, object marshalling is still the number one headache. Most toolkits make interoping with primitives a brease, though. It may seem like your losing ground by not taking advantage of the POJO you have floating around in the view tier, but in point of fact it's rarely that big a burden to unmarshal the relevant fields and use those instead. On the services side, reloading the relevant record is painless because the entity's usually cached and thus refetching it is cheap.

Take for example the idea of a shopping cart which surfaces methods for adding line items to orders, orders to shopping carts and shopping carts to customers. A clean version of this might look like:

 
 public interface ShoppingCartService { 
     ShoppingCart createShoppingCartForCustomer ( long customerId, 
                                                 Date 
whenShoppingSessionStarted ) ; 
     Order createOrderForShoppingCart ( long shoppingCart ) ; 
     LineItem createLineItemForOrder ( long orderId, long productId, 
int quantity) ; 
     void removeLineItemFromOrder ( long orderId, long lineItem ) ; 
     void startOrderFulfillment ( long orderId ) ; 
     /*  other methods for loading and removing the various 
         objects, as appropriate 
     */ 
  } 

In these methods, you can do sanity checks, care for business cases, handle the state of the various objects and not worry about having a transactional resource like an EntityManager or Hibernate Session open in the client thread. In this example, you might imagine the Order won't officially be fulfilled until it's paid for, at which point it'll move to the PAID state. Simialarly, adding a LineItem might require a check to an inventory, decrementing how many of those Products are in stock. The same is true of the inverse operation: removeLineItemFromOrder should appropriately restore the inventory count and update the totalPrice field on the Order.

This requires one interface method declaration's work more than if you had simply obtained the EntityManager from your Seam backing bean and executed the logic there, except now the logic's codified and reusable.

September 3, 2009

Setting Up jBPM 4's XSD File In Eclipse

I've recently been playing with jBPM 4.1 and, while I haven't quite gotten into it, I did manage to break an Eclipse setup of my "old" jBPM 4.0 code. This is definitely a user error. So, trying to ensure I have a reproduciable baseline, I start setting everything up again (I don't have the jBPM plugins or anything installed -- I keep it mean and lean, if possible. )

I got to the point where everything was running fine again from the IDE, but I noticed I no longer had code completion for my jBPM .XSD file. I'm not sure if I ever did, or if I did, then I've forgotten how. So, I stumbled through getting it working with the Eclipse Resource Catalog. Here are the steps to reproducing it if you have the same issue.

  1. You'll need a copy of the .XSD itself. For me, the simplest option was to just download the source jar and use the XSD file therein.
    mkdir ~/xsds; cd ~/xsds ; 
    wget http://repository.jboss.com/maven2/org/jbpm/jbpm4/jbpm-api/4.0/jbpm-api-4.0-sources.jar 
    ; 
    jar xvf jbpm-api-4.0-sources.jar ; 
    
  2. In Eclipse, go to Window > Preferences
  3. Search for "XML Catalog," under the "XML" node.
  4. Click "Add..."
  5. Fill out the dialog, using the values below.

I hope this spares somebody some pain. Once you've got it working, go check out the awesome new jBPM 4.1!

August 29, 2009

My Christmas Wish, OR How the JVM Will Outlive the Cockroach, and .NET

It started with a Tweet from Miguel De Icaza. Miguel's the leader of the Mono project, whose goal's to bring .NET to Linux. He's also the former leader of the Gnome project. Generally, he's whip smart and not usually prone to flame baits. So, I tend to read his words carefully, as it usually pays off. He said: "I wish Java tried to compete with .NET, but they seemed to have given up a long time ago: http://tinyurl.com/mfxmqm"

At this point I wanted to write him a terse letter stating my point of view, stating how he had clearly missed the obvious. I resisted, hugged the wife, cried a little, sat on the beach with candles, attended a book club meeting, found Jesus, and then came back and reconciled that I was just sad because he was right. He was also pointing out the obvious. (There, at least I can say that! in the anonymity of my blog, far, far away from where he might see it...)

The link points to integrations in Project Coin, a project that's taken the JDK and aggressivey evolved the language to try certain features out in an isolated fork. In general, I'm supportive of the movement, but it's a sad truth that any final edition of JDK 7 is already late, and will likely not incorporate many of those integrations in Project Coin, or even many of the originally announced - big ticket changes coming straight from Sun. JDK7 is the Windows Vista/Longhorn of the JDKs.

You remember Longhorn, right? It was the code name for Windows Vista for a few years. If I recall, there was talk of integrating 4 pillars or waves of technology into the then-hyped next generation of Windows, including WinFS (Am I wrong in thinking that it was called something else, then? Avalon? Or am I thinking of the now-defunct Java DI container?) Indigo, and a slew of others. As the roadmap slipped further and further, more things were dropped. In fairness, in 2009, some of those pillars have subsequently shipped, sort of, as parts of .NET 3.0-3.5x. Some are lost to the annals of history.

With a heavy heart I proceeded to code, ignoring what he said. I'm tougher than that. I can handle having the rug yanked out from under me. "Why would he say that about my precious Java??" I thought, typing as I thought it. "I wish I could come up with something to refute his claims!", I moaned. Something elegant, quick, crazy fast, and future proof. Something's got the best of C#, F#, Python, JavaScript and more. I tend to ignore skills I've built up over years of use and revert to primitive, conveniently blog-friendly samples from tutorials when I'm stressed (don't you?). And boy was I stressed! I looked at my screen. I was really in a tizzy at this point, thrashing away at the keyboard! (Like in those movies where they feature somebody running their hands along the home row and suddenly they've infiltrated the FBI's secret-most files.)

Here's what I had typed:

object Maps { 
 val colors = Map ("red" -> 0xFF0000, 
 "turquoise" -> 0x00FFFF, 
 "black" -> 0x000000, 
 "orange" -> 0xFF8040, 
 "brown" -> 0x804000) 
 def main (args: Array[String]) { 
 for  (name <- args) println ( 
 colors.get (name) match { 
 case Some (code) => 
 name + " has code: " + code 
 case None => 
 "Unknown color: " + name 
 } 
 ) 
 } 
} 

It was a Christmas miracle! A language on the JVM that already had most of the proposed changes in Project Coin and great deal otherwise and was very fast and that worked on all platforms, just like Mono! Errr... that is, just like Java!

This language, Scala, has gained a great deal of traction in the Java community and even people you'd expect to offer otherwise have endorsed it. People like James Strachan, creator of Groovy, and James Gosling, creator of Java.

I just hope that other people can find out about this wonderful language. Why, wouldn't it be nice if -for Java 8 (will we ever get to have a Java X? How cool would that be??) - we just shipped Scala?

And that, boys and girls, is how Java outlived the cockroach, in our hearts.

The End!

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.

<< Last | Next >>