EJB Revisionist History… and a look forward

Floyd Marinescu has blogged about the history of EJB, which I find somewhat fascinating because in it, he makes the same common mistake that most EJB developers made when they first started working with it.

    I speak at conferences fairly often, and at some point during a talk I will ask the audience how many have used EJB. Usually, 90% put up their hand. Then I ask them, how many of you have used EJB as distributed objects, meaning, where you have a separate physical tier for your business logic and a separate tier for your presentation (servlets/jsp) tier? Usually only 15% of the 90% will put up their hand. These results have been consistent at conference I’ve spoken at in North America, Europe, and Japan. The result still never ceases to amaze me, since EJB was designed to be a distributed object framework, for use on large-scale systems, but most of the audience was using it as a local framework for their small – medium sized web apps.

Unfortunately, Floyd seems to have fallen into the same trap that everybody else did back then, which was to assume that since EJB built itself on top of RMI (or so it seemed), then EJB must essentially be a distributed object framework just as RMI was, just as CORBA was before it, just as DCOM was over in the Microsoft space.

The EJB specification, however, spent very little time talking about distributed objects, even as far back as the 1.0 specification. Instead, it spent most of its time, as it does today, talking about transactional behavior of session beans and entity beans (not to mention making vague and nonsensical promises about O/R mapping that eventually didn’t hold up in practice). If you look at EJB and compare it to most traditional Transaction Processing systems and then compare it to a distributed object toolkit like RMI, the relationship becomes much much more clear: EJB isn’t really about objects at all (just as COM+ isn’t really about objects, either), but about building scalable procedurally-oriented systems that happened to be wrapped into something vague resembling an object (largely because Java is an object-oriented system).

Floyd points out that lots of companies used EJB for small- to medium-sized projects, and this was true: lots of companies did largely because the Java vendors made it VERY clear that not doing EJB was the First Sign of the Apocalypse, and that if you wanted to Do The Right Thing in Java, you did EJB. (Failure to do EJB was tantamount to pasting an upside-down pentagram on your forehead… or putting a "COM is Love" sticker on your notebook, one of the two.)

He goes on to boil EJB essentially down to three things:

        Framework benefits? At the time, if you were doing any kind of web or enterprise development, you were living in a proprietary, confusing world, or you were using the nuts and bolts tools like RMI, Servlets, etc, and creating your own frameworks. Couple that with the fact that during the dot com boom, most software developers were new, attracted by the dot come boom – the industry was just waiting to be given a standard, agreed upon way to do enterprise development. EJB provided that – a standard framework for doing transactions, Security, stateful components, etc. Having a standard "framework" solved a real and present need – there was no open source movement, no web frameworks, etc.
        Distribution benefits ? EJB standardized a programming model and platform for building business logic with distributed objects. Hot on the heels of RMI and Corba, this too was needed. If you wanted to do distributed objects, EJB was the answer.
        Component Benefits – This is where things got nutty. In my opinion, Sun was reacting to the success of the Visual Basic component market and dreamed of having a similarly active market in the area of Java business components. You all remember all the component re-use retoric, and attempts at building online marketplaces for EJB components. As a result, EJB gained a lot of weight in the API’s, deployment and package semantics in order to have EJB components run consistently well across appservers. If it were not for the component aspect of it, wouldn’t EJB have been designed more like the modern POJO framework to begin with?

In response:

    Framework benefits. Frankly, EJB was created and shoved upon the Java developers largely because Sun desperately wanted an answer to Microsoft’s MTS, which was seen as "the" successor to TP systems in the "modern" era. It was widely believed that if Sun didn’t have a logical successor in this space, Microsoft would take home the majority of the large enterprise systems. As it turned out, neither really displaced any existing systems, but did claim new projects.
    Distribution benefits. A good distributed object model is a contradiction in terms, and anyone who’d done CORBA or RMI (or DCOM or OSF RPC, for that matter) knew this; Peter Deutsch created his "Fallacies of Distributed Systems" list, and Waldo and Wollrath wrote their "A Note on Distributed Computing" paper as far back as 1994. Unfortunately, the hordes of programmers who took up EJB never heard either of these items, and the vendors who pushed EJB were not about to tell them that creating fine-grained objects with fine-grained methods was a Really Bad Idea. It still is, and this is principally a factoid that most object purists would like to avoid, because it forces them to face up to the fact that objects are NOT the silver bullet.
    Component benefits. Yes, Sun got nutty, looking at the wild success of components in the VB space, but hey, so did everybody else, including Microsoft. (MTS "component markets" were going to spring up ANY day now.) But frankly, Sun never really "got" the power of components that COM actually provided, and this is an oversight that continues to plague them to this day–this lack of isolation is what leads Java containers to have to rely on ClassLoaders to provide isolation between components (or modules, or whatever you care to call them in the JEE space), and clearly that’s not been the best decision Sun ever made.

What bothers me more than anything, though, is this immediate assumption that POJOs are inherently better as a design approach, and that smacks of distributed objects again, with all of the inherent problems that go with it. I know, ranting against POJOs is like saying "Martin Fowler’s an idiot" (he’s not). But let’s be honest here, folks–Fowler never suggested that POJOs should be the next big distribution model. In fact, it was Fowler who said that distributed object models "suck like an inverted hurricane". (Bonus points to anybody who can identify where that quote came from.) POJOs will lead people to do "proper" object design, which flies entirely contrary to "proper" distribution design, so let’s just bite the bullet, and recognize that objects inside a process are good, objects across processes are Bad.

Floyd goes on, taking a look at these three axes in current tools:

    Framework – Now we have open source frameworks that provide transactionality, pooling, security, and all the other good programming model benefits of EJB. Tools like XDoclet, Spring, and methodologies such as AOP are bringing all the framework benefits of EJB to lighter weight environments. JBoss was an important innovator here as well.

JBoss didn’t really innovate anything, they just took an interesting age-old design pattern (Interception) and built a container around it. (Funny how the fact that MTS/COM+ did this too, yet that wasn’t "innovation", that was "proprietary lock-in".) But this is just a nit; for the most part, he’s right on this part.

    Distribution – RMI is no longer the defacto standard for distribution. Web services are now being touted as a way to do distribution, many frameworks for doing WS over POJO’s were maturing. In addition, other remoting protocols such as Hessian were picking up steam.

WS as a tool for doing distributed objects is entirely missing the point of Web services, and frankly anybody who tries to use WS-* tools as a replacement for RMI is going to end up in a world of hurt. The object-hierarchical impedence mismatch is just too large to overcome, just as the object-relational one is. RMI remains the central non-WS distribution protocol, whether it goes over JRMP or IIOP.

    Components ? Who cares? The Enterprise Component Market is dead. When Sun was eyeing the success of the VB market, they failed to notice that that marketplace consisted mostly of UI widgets and "utility" type components that are re-useable across projects. We did not see things like payroll classes or the notion of a "user" captured as a VP component. The fact is, business logic is generally not re-useable across projects, and so the market discovered, and so all the weight added to EJB was not necessary. Come on people, do you REALLY NEED binary compatibility between EJB-JARs on appservers? How often did you deploy EJB’s from one component into your project by deploying the already compiled JARS? I can’t remember hearing of a case, what was common was simply adding the EJB source to your build and packaging it at build time. If building re-useable components were not an objective of the EJB 3 team, perhaps we would have had the equivalent of EJB 3 back in 2001.

So close… and yet so far, far away. We need components NOT as a means to allow code to "port" between containers, but as an isolation barrier between your code and mine and the next guy’s. In a distributed system, we want to remain loosely coupled across layers because we’re never really going to revise all layers at once except in the smallest systems (which probably didn’t need the separation anyway, then). More importantly, the "weight" of EJB is not in the API itself, but in the implementations the vendors sold us. Where was the lightweight EJB container that runs in-process, a la COM+? Turns out, there is one, an open-source one, from Exolab (OpenEJB), and it works pretty good at doing unit testing of EJB components–at least as well as unit-testing your servlet/JSP code works, anyway. The worst part of all this, though, is that Floyd misses out on the absolute number one requirement of making EJB look like EJB 3 is being proposed to look: annotations, which Sun simply didn’t recognize the need for at the time. (You can’t blame Sun, really–it’s something that most everybody didn’t see a need for until .NET came out and we could see how it greatly simplified the situation.) No annotations, then no EJB 3. The rest of EJB 3–the "common-sense defaults", for example–really isn’t all that impressive.

Floyd continues:

    Now, bringing the survey question I started off this blog with back into perspective, notice that the majority of people were NOT using EJB for it’s component benefits, or it’s distribution benefits. The majority of people were using it for it’s framework benefits, and those benefits were better served by light weight open source. In 2003, I think the only real value proposiiton EJB brought to the table was it’s use as a distributed object framework, for real large scale systems, which was where it was originally intended to be used to begin with. Thus, as I would tell the audience at th talk: "you’ve all misused EJB".

Well… yes, they’ve misused EJB, but largely because they were looking to design distributed objects. Distributed objects do not scale, period. If you choose to design your distributed object model around service-oriented principles (as EJB does), then you can scale, but how much OO-ness are you giving up in turn? If you write classes with one big method that drives everything, are you still doing OO?

    So where are we today? Well, I have to applaud Sun and the EJB expert group and all the vendors that support EJB. They made the hard choice, and acknowledged that the community really wants a standard framework for doing business logic in objects, with ORM instead of persistent components, and that is the direction that the expert group is taking. Why is this worthy of applause? Because Sun and the vendors are taking a risk in supporting this new lightweight EJB, they are risking their own revenue models by standardizing what is already widely being used in the open source world. They will NOT be able to compte on the programming model alone (and they know this), it will have to be their "transparent middleware" services, such as clustering, XA, management and monitoring, etc.

The hard choice is to realize that EJB’s "heavyweight" or "lightweight" factor isn’t in the API at all, but in the implementation of that API. And frankly, the big vendors have ALWAYS competed, at least with one another, on their "transparent middleware" services. That story doesn’t change.

What DOES change is that the Java community has come to recognize that not every project needs EJB, and now the vendors need to figure out how to tailor their containers to address the needs of smaller projects. Spring did that, successfully, and now we need to see a vendor-supported world where either Spring goes into the JSR process to become part of the JEE space, or else the containers start looking into hosting more than just "transactional processors", which they’re also doing. JBI is ripe for inclusion, if not outright merger, with EJB, to create a "generic Java component container", and we should probably just accept that a servlet container and EJB container really aren’t that far apart from one another to begin with, and just unify the two.

The secret sauce in the Java space–as with any middleware space right now–is in the container/component relationships. The sooner we unify that space and create a coherent story around it, rather than creating lots of specifications that fundamentally do the same thing, the better off we’ll all be in the Java space.

 

Good tips, JZ

Just got the latest "Core Java Technologies" Technical Tips email, and in it are two interesting little tidbits:

    Three Swing "Urban Legends":
        "Create threads for long tasks from the event dispatch thread." Problem is, as it turns out, the event thread runs at a higher priority than normal, so threads spun from the event thread also run at a higher priority level. Set them back to NORM_PRIORITY before starting them.
        "Use SwingUtilities for running tasks on the event dispatch thread." Turns out that SwingUtilities is just a wrapper around EventQueue, so just use those methods directly.
        "Synchronize methods for synchronization." Turns out that synchronizing on the method is dangerous for AWT Components, so prefer to use an internal lock object instead.
    From Runtime.exec() to ProcessBuilder: Stop using Runtime.exec() (which was always problematic anyway), and start using ProcessBuilder instead, which gives you more control over the launch, environment, and reading/writing to the stdout/stderr/stdin streams anyway.

It’s been a long time since I saw tidbits in here that weren’t rehashes of existing documentation, so kudos to John Zukowski, the author of the Tips!

 

Now THERE’s real conviction…

I find myself amused by the anonymous poster(s) who continually berate me for my dual Java/.NET stance; this most recent comment is just but a precious sample of the accumulated levity (and high technical persuasiveness) of those who refuse to even put their name to their opinions:

    yeah, keep bitching. Dude, you should get over Java and concentrate on .net since you’re an annoyance in our space.

Precious.

Don wants to know how Indigo can avoid EJB’s fate

Don recently asked,

I’d love to hear from the EJB alternative camp what they’d like to see from us in Indigo to keep them from reinventing the wheel over here in .NET land.

which was in response to his earlier comments of

I’ve spent some time thinking about whether we’ve taken adequate steps in Indigo to stem the need for dozens of alternative "containers."

Based on what I’m seeing, I think we’re on a good path. Here’re a few things that make me believe that:

  • We don’t mandate a process/appdomain host, so you can host Indigo services in any AppDomain or process you chose.
  • Our dispatch and instancing pipeline is fully pluggable (and replacable) and is wired up to our metadata/contract engine.
  • Most important data structures are extensible without resorting to subtyping.

 

Philosophically, we’ve done a good job at building simple and reliable mechanisms and not imposing a lot of policy on top. This is similar to the approach taken by .NET Remoting (albeit in a somewhat different domain) and quite the opposite of the approach taken by MTS, COM+, and EJB.

So I thought I’d take a stab.

 

One of the critical flaws of the EJB Specification as it stands, and the principal benefit behind the lightweight containers (until they start to get too heavyweight, anyway) is that of composability, the ability to "pick and choose" which parts of the container you want to apply to your particular project. For example, under the current regime, if all you wanted was the ability to start a transaction and kick off some processing each time a message comes in, you either have to write the host yourself, complete with JTA code (which means bringing in some kind of open JTA framework), or else you install EJB and write Message-Driven Beans. There’s no "middle ground" until you start to consider the lightweight frameworks, but even there, there’s a growing tendency to want to be all things to all people. I want a container that gives me the very basics of container-managed inversion-of-control and then gets the rest of the way out of my hair. No automagic pooling (unless I ask for it), no automagic resource management (unless I ask for it), no automagic transaction management (unless I ask for it), and so on.

Proponents of the current crop of lightweight containers will be very quick to pipe up and say "but that’s exactly what we do!", but there’s a difference–in several of the formerly-lightweight containers, they started out this way but have grown to encompass almost all of what an EJB container does, with similar complexity involved. Give me a very basic container-managed relationship, and a raft of services that I can pick-and-choose from, but let the traditional C++ mantra: "Don’t pay for it if you don’t use it" be the guiding principle here. Sometimes all I really want is a simple container in which to put a remote object, and sometimes I want the full nine yards of a middleware container (a la COM+ or EJB). Build a simple container with a ton of hook points, then give me things built on top of those hookpoints that I can take or leave as I wish–not stuff already built in that I can choose to use or not (but still have to pay for in terms of code loaded, processing steps taken and so on), but things that don’t ever get referenced or used unless I explicitly call or configure for them.

That’s the pipe dream, anyway. 🙂

Richard Monson Haefel waves farewell to books… and describes how authors offer up their soul

Richard Monson Haefel, the author of one of the first (and best-known) books on EJB, has announced that he’s getting out of the book-writing business:

    I’ve been writing technical books (and some articles) for seven years and I’m ready to move on. Its been a lot of fun and my books have done a lot for my career, but they are a lot of work and at this point in my life they are not worth the effort.

He goes on, though, to say something that I think deserves underscoring and support, because he calls it "corny" but I think is very very true and needs to be reinforced:

    Of course this wasn’t an easy decision for me. As corny as it sounds, each book and every edition is a part of me. Think about it. An author (or at least me) spends as much as two years writing a book, not including subsequent editions. I’ve been working every year (over four editions) since 1998 on the EJB book!. There is a lot of blood sweat and well ? sweat (I’m not big on crying over work) in those books. When you buy one you get a chunk of my soul. Sorry. I warned you that this would be corny.

That’s not corny, Richard, that’s the author’s life. For those who’ve never written a book before, you have to understand the dynamics: you spend at a minimum six months (in my case, more like two years) trying desperately to figure out how to best convey the material, beating it and hammering it in various ways to make it clear, precise, accurate, and so on. You carry this thing with you everywhere you go: it’s on your laptop, at a minimum, sometimes it’s in your notebooks and your scribble notes on napkins and most of all, it’s floating there in your head, demanding attention. And then, when you finally publish them, they’re out there for the world to take potshots at. It really is a piece of you out there, and it’s terribly vulnerable because there’s nothing you can do once the book hits the shelves; somebody didn’t like the way you explained a particular concept? You can’t call it back, you can’t try to spin "what you meant" that didn’t come off correctly, you can’t edit it (unlike a web page) once it’s in dead-trees format. The best you can hope for is a second printing and the chance to fix a few errata.

Leon Uris once said, "Becoming an author is easy: just get out some paper, and open a vein." Each book becomes your baby, a little piece of you floating out there for all the world to take a whack at. And man, it’s tough the first time, like parents watching their first kid go off to kindergarten.

That’s not corny, Richard. That’s just being an author. Best of luck to you at the Burton Group.

Can’t let Floyd get the last word… More EJB history

Floyd and I are in a jenn-yoo-ein blog war now, as he responds to my post accusing him of EJB revisionism. This can only mean that I must now respond with vigor and extreme hostility, ripping his arguments to shreds and leaving no doubt in anyone’s mind about our respective ability in blogging, Java, or technology in general.

Not. (Gotcha, Floyd. 🙂 )

Truthfully, Floyd was right when he said

    While Ted phrased his points as corrections to my own, for the most part I don’t think they are, two people of different backgrounds can certainly see and interpret different aspects about why things are, especially historically. We are talking about history, not code. 🙂 …. Perhaps I should have been more upfront on my last entry, but the perspective I was giving was based on how things would have looked like to the developer at various points in history, and how that then affected adoption and growth, etc. It perhaps should have been phrased "a brief history of EJB adoption from the developer’s perspective", not the spec designer, book author, or specification implementor’s perspective. If I am being revisionist, then so is Ted, as we are both revising history with our own interpretations. 🙂

Exactly. I read Floyd’s post to mean that he was describing the development of EJB from its creators’ intent, rather than an interpretation of how developers saw–and largely misinterpreted–what its intent was. After all, it’s fairly obvious in hindsight, I think, that developers, and their management too for that matter, really really screwed the pooch when it came to EJB. Using it when it wasn’t really called for, and expecting that simply using EJB in of itself would provide the scalability and performance desired, will leave any development project pretty grossly screwed up.

Floyd’s also right when he says

    … it is obvious that people reading Ted’s blog will think that every point I made is wrong (Hani certainly did), so I feel compelled to respond …

        Unfortunately, Floyd seems to have fallen into the same trap that everybody else did back then, which was to assume that since EJB built itself on top of RMI (or so it seemed), then EJB must essentially be a distributed object framework just as RMI was, just as CORBA was before it, just as DCOM was over in the Microsoft space.

    I suppose that I invited this by saying early that EJB was designed to be distributed object framework, but take alone that sentence is out of context – as I mentioned later on in the blog, the distributed object framework was just one of the three major categories.

Yes, Floyd, you DID invite my blog-wrath when you said that, because unfortunately I think that’s a mistake that people continue to make unto this day, not just with EJB, but with some of its intended successors, too, the principal one being Spring.

The problem I have with the industry right now is stated rather simply: Not every problem we face lends itself to an object-oriented solution. For a large percentage of developers working today, that is an uncomfortable feeling, and thus gets repressed with a brutality normally reserved for hideous personality defects that we don’t want to own up to. Whether we like it or not, however, the design space that EJB–and Spring–operate in is a space that doesn’t lend itself to the object-oriented paradigm, and trying to pretend otherwise can lead us into all sorts of dangerous places.

Consider another technology whose major architectural principles also don’t follow an O-O slant, that being the HTTP and Servlet space. When you consider the major tenets of object-orientation, usually consisting of polymorphism, encapsulation and a methodology that demands fine-grained methods and objects ("No method should be longer than a page in your editor" and "No class’ responsibilities should exceed what can be written on an index card" being two of the common aphorisms used to describe proper O-O design and implementation), it slowly dawns on you that servlets don’t really follow that approach at all. In fact, if we were to compare a servlet’s overall design, it smacks much more of a 3270 session, which is essentially a procedural space: requests are processed, per-session data used as part of that processing, generating results that are returned. We can put an object-ish veneer over the whole thing, as frameworks like Tapestry or JSF try to do, but the underlying driving forces are still the same, essentially procedural in nature. The Servlet API, then, is an object facade over a fundamentally procedural task, and the way in which we write servlets reflect that: we don’t generally access fields in servlets (that creates a synchronization concern), for example, but instead access data stored in an entirely separate object that the container manages for us (that still has synchronization concerns), that being the Session, of course. We don’t expect to be able to inherit one servlet from another, since each servlet tends to be single-purpose and single-minded; we don’t usually look to polymorphically substitute one servlet in the place of another. (Note that this isn’t to say that servlets aren’t devoid of polymorphism entirely, only that we as the development community using them don’t make use of polymorphism in our usage.)

I find it particularly telling that, for all intents and purposes, the Servlet API looks astonishingly like the ISAPI or NSAPI APIs that predated them, which were intended for procedural languages (by which of course I mean C) instead of object-oriented ones. In fact, to a large degree, they’re identical. The .NET HttpHandler API, the logical equivalent is even less object-oriented:

public interface IHttpHandler
{
  void ProcessRequest(HttpContext context);
  bool IsReusable { get; }
}

You don’t get much more object minimalist than that.

(For the Java developers in the crowd, the Java translation would look like:

public interface IHttpHandler
{
  public void ProcessRequest(HttpContext context);
  public boolean getIsReusable();
}

where HttpContext is an object that contains methods to access HttpServletRequest, HttpServletResponse, Session, ServletContext, and a few other interesting tidbits. The IsReusable property is just whether or not instances of this thing can be pooled, something which the Servlet API defines on its own terms; I suppose you could see returning false from this property as the equivalent of implementing SingleThreadModel. Sort of.)

All of this isn’t to say that the Servlet API isn’t useful or interesting, but simply to say that we pretty much silently rolled with the fact that it was a procedural space, and adjusted our use of the object-oriented approaches accordingly.

Enter EJB. And MTS/COM+, for that matter. Web services guys, listen up–you’re likely headed down the same path if you’re not careful. Ditto for anybody contemplating Indigo.

EJB and MTS/COM+, unfortunately, were perceived to be object frameworks that required a usage model that followed the object tenets. And in each case, as time went on, patterns emerged that sought to debunk that idea and show that taking a strict object interpretation was doomed to failure. Effective COM and Transactional COM+ led the charge here in the MTS/COM+ environment. I hope I did the same with Effective Enterprise Java, but others came before me (in a much less "effective" style, of course 😉 ) saying much the same thing. And before us all came Deutsch’s "Fallacies of Distributed Computing" and Waldo and Wollrath’s "A Note on Distributed Computing" as basic foundation for the later works. (Hint: if you want to make a name for yourself, write an "Effective Web Services" book and say pretty much the same thing. You’ll be hailed as a hero.)

Herein lies my concern: Spring, as well as the other POJO-based containers, tend to lead developers back to an "objects-first" approach, and that tends to encourage object-oriented behavior, such as fine-grained methods, small-scale classes, inheritance, polymorphism, and so on. While I won’t go so far as to say that such things *can’t* be done in a Spring container, my worry is that developers will seek to do it both within the container (which I couldn’t care about in the least) as well as across container instances, which has Badly-Ending Story written all over it, as developers make the same mistakes that the CORBA crowd made, which is the same mistakes that the DCOM crowd made, the same mistakes the RMI crowd made, the same mistakes the OSF RPC crowd made, and so on.

Eventually, some day, we as an industry will recognize the truth of the statement "There is no such thing as a good distributed object model", but until that day, we have to remain on our guard against technologies that will–either by intent or by accident–lead us down that dark and stormy path. And thus the virulence of my reaction to Floyd’s comment; by characterizing EJB as a distributed object framework, even just to say that this was how it was perceived, reinforces that perception and puts us back in the danger seat all over again. So Floyd, maybe you weren’t wrong, per se, but you walked into an area in which those of us who’ve had to try and rescue EJB projects from themselves are a little sensitive, perhaps overly so.

Where Floyd and I do still disagree, however, is in this bit (him quoting me first):

        The hard choice is to realize that EJB’s "heavyweight" or "lightweight" factor isn’t in the API at all, but in the implementation of that API. And frankly, the big vendors have ALWAYS competed, at least with one another, on their "transparent middleware" services. That story doesn’t change.

    As mentioned before, I think the implementation is also a factor, but the entire light weight container / Dependency Injection / POJO "movement" directly contradicts the point that the weight of the API isn’t a factor "at all".

Au contraire. Just as JNDI is lookup via explicit method call, Dependency Injection is lookup via implicit method call (we’ve just reversed the direction)–effectively the same thing, just changing the API, reversing the direction of the invocation. The Spring interfaces that are available for implementation (for lifecycle control, etc) are pretty much equivalent to the EJB interfaces, it’s just that Spring makes them optional where EJB required them (admittedly an error in design). Spring’s major innovation wasn’t the POJO-based design model, or even the Dependency Injection approach, but in the lightweightness of the container. Think about it this way: would Spring developers be so excited about Spring if they had to run it as an external process, a la WebSphere or WebLogic? My casual anecdotal experience suggests no, thus leading me to believe that the API isn’t the major issue here. (Is implementing the SessionBean or MessageDrivenBean interface really THAT costly? If you truly dislike having to implement the methods you don’t care about, write a GenericSessionBean class that does the same thing the GenericServlet class does–provide common-sense NOP defaults. Message-Driven Beans are even simpler, and probably don’t even need a GenericMDB class, but your mileage may vary here.)

Floyd and I will probably disagree on Spring’s contributions, and this wouldn’t be the first time he and I have disagreed, nor would it be the first time I’ve clashed with people on the subject of Spring. Bruce Tate and I have had this discussion on a number of occasions, as have Justin Gehtland and Mark Richards (at the most recent NFJS show, in Des Moines). My point isn’t that Spring isn’t useful–far from it, I find Spring to be entirely useful–but that the efficacy of the tool is in its in-process nature, not its API. To more deeply understand this point, I strongly suggest anybody in the Java space play with COM+, which offers both an in-proc and out-of-proc model (known as "Library" and "Server" applications, respectively) as well as an annotation-based configuration scheme that will likely be similar to how EJB 3 works. (COM+ Queued Components are a bit like MDBs, and in this case, I prefer the EJB approach, but that’s neither here nor there.)

Oh, and by the way: welcome to the blogosphere, Floyd. 🙂

Spring, objects, and scalability

Keith Donald has picked up on the Floyd-and-Ted discussion, and weighs in on a few of the points that I raised. In particular, he goes into some of my assertions regarding Spring:

    I believe it is accurate to say that Spring leads developers back to an internal, in-process "objects-first" approach. I think it is wrong to say Spring encourages a "distributed-objects-first" approach, or even the use of distribution in the first place. I imagine anyone working with Spring for any length of time will back me up on this. Surely anyone who has read J2EE Design and Development by Rod Johnson…

I wish that were the case, Keith, but too often I run into developers who are of the "objects uber alles" mindset, and any technology that allows them to go back to their basic O-O principles is obviously a Good Thing. Will Spring developers suffer from this same mindset? Possibly not, but I’m not worried about the guys who learned Spring from Rod and/or his immediate camp directly. I’m more worried about the folks who pick up Spring second-hand and use it after reading a few tidbits about POJOs and such. THEY’re the ones who’re going to give Spring the bad name… because in many respects they’re the same ones who did it to EJB.

    First of all, the Spring container itself does not address the problem of distributing objects at all, period. The container has always been about providing a solution for the management of the internal structure of a software system. It is a sophisticated factory for local, in-process application objects (services) based on POJOs. This factory lets you develop the internal components of your app in a object-oriented, test-driven fashion, yes. You can easily have finer-grained strategies that execute polymorphically, you can develop in parallel and you can test in isolation. You use Spring to manage the assembly of these local components into a working system by providing it instructions about what implementations it should instantiate and how those implementations should be configured and wired. You do all of that before you even start thinking about which services you’ll export over remote transport and how you’ll export them…

ALL containers have been about providing that same solution. They manage a variety of resources on your behalf, including (but not limited to) threads, network resources, database resources, messaging resources, object lifecycle, and so on. The fact that Spring chooses to express its application code via POJOs is dangerous, moreover, because it leads people down the slippery slope that distributed object models can become. (Don’t believe me? Go re-read the Distribution chapter of Fowler’s PEAA book–it’s not just me saying this.) Fact is, Keith, YOU may think of Spring in that fashion, but that’s actually a fairly distribution-oriented way of approaching the problem, and wasn’t the point of Spring to get developers back to thinking in objects, because EJB clearly wasn’t an object-oriented system?

    Most good software developers I know care most about building business components that contribute to solving a domain-specific problem: that actually carry out business-differentiating work. With a POJO-based approach, you can focus on building and testing that core business logic first. You don’t need any container to do that–Spring or otherwise. Just give us JUnit and the new operator. We like that.

Agreed. So, then, what I hear you saying is that Spring doesn’t directly enable easier building and testing, because the focus here is for people to build POJOs and front it with… whatever. And thus the actual container into which the POJO is deployed is more or less irrelevant, yah? After all, if it’s socially acceptable for people do this for Servlets or Spring, why not for EJBs? But again, I’ll say we need to be careful here, because once again we’re approaching this via the "objects uber alles" approach, and I submit that in a number of scenarios, you can’t start with your internal data structures (which we both agree that your object model is, unless you’re advocating that it’s OK to expose that object model across processes, at which point we disagree).

    But that’s only one half of the puzzle and without mentioning the other half I’m being completely naive. You still need the ability to apply enterprise services to your POJOS as (if) needed. You may need to secure them, make them transactional, selectively export them to the server for remote access or management (perhaps over a variety of mechanisms), etc. Spring’s container, using the techniques of 1. Dependency Injection and 2. proxy-based AOP, combined with 3. its service abstractions, gives you a mechanism to do that in a externalized, decorative fashion without impacting your mainline business logic. In addition, you can execute first-level integration tests that exercise the interaction of much of this stuff without having to deploy to a full-blown J2EE container–essentially, you fail faster.

Dependency injection *only* saves a single function call, that of the JNDI lookup, and unfortunately you cannot control when the dependency gets injected, unlike in the JNDI case where you control when the dependency gets resolved. This means that if the system administrator changes the JNDI entry (yes, they can and should be able to do that, at runtime, without you knowing!), the next JNDI lookup pulls back the modified entry. When, exactly, do you ask for Spring to re-inject your dependencies? Plus, proxy-based AOP is essentially what CORBA, RMI, DCOM, and other remoting tools do already–Spring simply joins a handful of other technologies (unfortunately NOT EJB prior to 3.0) that expose that interceptor stack to you. Guys, I hate to say this, but .NET even builds this in, via ContextBoundAttribute and friends. (Frankly, doing interception really isn’t AOP, as I’ve said before, but people seem determined to take the term and co-opt it into whatever they want, so I’m about to give that up as a lost cause. Sure. Interception is AOP. Go ahead. And VB was object-oriented, too. Whatever you want.) As to the "integration tests that exercise the interaction of much of this stuff without having to deploy to a full-blown J2EE container", dude, that’s a failure of the open-source community to write an in-process EJB engine. If JBoss were embeddable (hint, hint, Marc Fleury) or if OpenEJB were more popular (hint, hint, Keith–there is one), then we could mock the EJB parts up around it and do exactly the same kind of in-proc integration testing that Spring can also do.

    As an aside: Ted, I agree with you to a point regarding API. If an object is a MessageListener, you better believe it should implement a MessageListener interface! The Spring team does not subscribe to this belief that everything in the world should be abstracted away. We believe an object’s non-core concerns are a good fit for externalization. So the API is important to us from that point of view: we don’t want our application code full of extraneous non-core concerns that clutter our main-line logic or introduce hardcoded dependencies on expensive resources. Also from an API perspective it needs to be easy to test application code in isolation: a heavyweight API that bakes in a first class dependency on a expensive-to-setup deployment environment is not acceptable.

Now you’ve lost me–an interface is good, but EJB is somehow a "first class dependency"? Dude, an interface is an interface is an interface! If you’re going to argue that JNDI or JTA/JTS is somehow that "first class dependency", then I’m afraid that I’m going to have to turn around and argue the same for MessageListener and the rest. If MessageListener is "a good fit for externalization", then I’m going to have to suggest that the SessionBean or MessageDrivenBean interfaces are the same–you can’t have your cake and eat it too. But more importantly, it *is* possible to do your testing without the heavyweight container. And let’s call that out more carefully, that the J2EE interfaces are NOT heavyweight APIs, because by definition they are interfaces, and interfaces are no more heavyweight in EJB or JMS or Servlets than Spring’s are.

    Bottom line: Spring enables a non-invasive, scalable up+down POJO-based design model and that is the major innovation that has brought agile J2EE into the mainstream.

Sorry, no. Spring is a reinvention of the EJB concept designed to run in-process, more or less a reinvention of the old JavaBeans model. It is no more scalable than the code that’s written to run inside of it (as is EJB, quite frankly), and the major design emphasis of Spring–that being the POJO and all of its object-orientedness–are a slippery slope that will, if Spring achieves the kind of mainstream deployment that EJB achieved, eventually come back to bite us all.

You cannot do a "good distributed object model", because if you build a good object model, you are creating a model which requires a great deal of cross-object communication and therefore spends a great deal of its time over the wire. If you build a good distribution model, however, you find yourself making serious compromises on your interface design, passing DTOs instead of making property-set calls and so on. The two are logically at diametrically opposite ends from one another from a design perspective.

The evilutionist site is a sham

OK, OK, enough people have pointed out to me that my earlier rant about the "evilutionist" site is a sham and a satire, that I feel morally obligated to admit that I was snookered and take my lumps accordingly. But, in true weblog fashion, I admit my guilt even as I defend my reasons for reacting so. 🙂

Why did I fall for it so completely? Because this is the direction our society (at least here in the US, can’t speak to the rest of the world) seems to be headed: a greater and greater polarization of people around specific hot-button topics that appeal to them. This in turn motivates them (because they are surrounded by people who are obviously "right-thinking people", namely, that think like they do) to act on their beliefs, in whatever fashion seems appropriate or "right", justifying it against some kind of "higher moral order". Look at the Ellie Nesler case of a number of years ago: a mother, whose son was sexually molested, watched as the molester went through his trial, and when it looked like he was going to be found innocent of the charges, she up and kills him. The community around her cheered her actions, because in their minds, the man was already guilty despite having not yet reached a legal verdict. This woman, this vigilante killer (whose motivations, I admit, I can completely understand) was hailed as a hero, because her moral beliefs happened to coincide with those of the community around her. What if those moral beliefs change to mean, "Anybody who wears a turban on their head must be Muslim and therefore must be allied with that stinkin’ Osama Bin Laden, so let’s round ’em all up and kill ’em all before they get to us!". Remember, it happened once before in this country, when we socked away the Japanese-Americans in "detainment camps" (leaving the German-Americans to mingle freely around us, despite FDR’s and Churchill’s agreement early in WWII that Germany was the greater threat). Think it couldn’t happen again?

The problem is, quite frankly, the greater communication we have worldwide, namely, the Internet. Believe me, I wouldn’t give it up for anything, but the Internet allows for widely-scattered people to congregate and spew their favorite brand of weirdness. Google for "white supremicist" sometime if you’re stomach is feeling strong to your stomach but you feel need to throw up. Or pick some equally ugly topic and just watch the links scroll across the page as your skin starts to crawl with them. Christian fundamentalists looking to find abortion doctors to kill off "in the name of God". Militia groups looking to meet and train against the day when the government steps on their "rights" too much (remember TerryTimothy McVeigh?). Anarchists who believe that the government needs to be destroyed so we can all go and leave in peace with nature in grass huts. Hell, there’s probably an activist Communist site out there still hawking the old Communist party line advocating violent overthrow of bourgeoisie governments. And so on, and so on, and so on.

And for that reason, I bought into the hoax, hook, line, and sinker, because to me, it’s entirely too credible that there would be a group motivated to try and shift the material taught in schools to something that’s more "right-thinking", in their mind, and the best way to do it is (still) spin the topic.

Look, this is a sensitive issue for me, particularly the material taught in schools; kids are wide-open sponges, with no filters installed, ready to absorb whatever is fed to them. And once they leave for kindergarten (home-schoolers aside), they spend more time in the company of their teachers–and the approved school curriculum–than they do their parents or family. (Which reminds me–when’s the last time you took a look at your kids’ history books? Or their reading materials lists? When’s the last time you looked into that curriculum at all?) What the school teaches them is what they will believe, until such time that they’re able to form their own opinions (assuming their schools teach critical-thinking skills at all, which some don’t). It’s our responsibility as parents and citizens to protect the material in schools from becoming politicized. If not, we risk being torn into lots of little groups that viciously cling to half-formed half-baked ideals that lead us into stupid conflict, and there’s so much we could do together if we just learned to respect others’ ideas and opinions. But that’s not going to happen if we don’t actively seek to protect against the politicization of school materials.

And that’s all I have to say about that. Next couple of posts will be technical in nature, I swear. 🙂

Update: … and if any Java or .NET commenter DARES to suggest this or this as an example of that polarization of "right-thinking people" into a rabid political action group, I swear, I will do something truly nasty to you…. 🙂

Further update: Typos corrected. 🙂

How could I miss this? The Architecture of the World Wide Web was released

According to its release date, Architecture of the World Wide Web, First Edition shipped on the 5th of November, last month. I’m somewhat surprised that it didn’t gather more of a ripple in the blogosphere, but I’ll also freely admit that it may have and I just missed it. In any event, it seems (from an early reading) that this is must-read material for anybody who wants to grok what REST systems are like and how the Web grew to scale the way it did. Of probably the most importance is the "List of Principles, Constraints and Good Practice Notes" right after the table of contents; if ever there was an "Effective REST", this might be it.

Buy me and help the tsunami victims

A group of .NET consultants, including yours truly, have volunteered hours of their time for bid on eBay, with all of the proceeds to go to AcehAID.org, an organization working to help the tsunami victims in Southeast Asia. It’s an awesome opportunity for people looking for just some short advice-type consulting (or short project work, though that’s probably harder to pull off in this short a time period) to get both the attention of a world-class consultant (c’mon, when else are you going to get a chance to chat one-on-one with Jeff Richter, Clemens Vasters or Kimberly Tripp?) and help out some victims of Fate’s fickle hand all at the same time. Details are on the eBay page; if this works, we already have some tentative plans to extend it into the Java space, as well–if you’re a Java "celebrity" (their term, not mine), drop me an email if you’d be interested in helping out.