Why I Hate Frameworks (2005)
discuss.joelonsoftware.com
discuss.joelonsoftware.com
I haven't worked first-hand with a web framework that I would consider "enterprise" (and therefore encumbered by the kind of nonsense that is being pilloried in the article) in ages, certainly at least five years.
Most frameworks I have worked with in the past five years focus on helping me get my job done while not fussing with annoying details. That is precisely what I want them to do.
Better yet, the most modern of frameworks do that plus have put focus on performance, so they both solve stupid problems I don't want to deal with and do so quickly, giving me nearly the full capacity of the server's CPU to be wasteful/experimental/rushed with my coding style at first. Then I can optimize later to have a high-performance system because the framework itself is no longer the bottleneck it once was.
I love frameworks.
Why I hate badly designed frameworks with unnecessary abstractions.
I teach a Java web dev course that gradually works up from the servlet API through a bunch of different abstractions. I keep a drawn representation of the current stack at all points of the course, and keep a count of the lines of code required to do any particular thing. At the beginning, we need about 10 lines of code to process a basic GET request, and there are lots of explicit dependencies (inheritance, dependencies on HttpServletRequest etc.) and at the end, there are maybe two or three lines of code, and no explicit coded dependencies (several implicit, provided by the framework).
Once you add in a few pieces of actual work (DAOs, collections, CRUD functionality, database connection pools, query abstraction), the code is an order of magnitude simpler when you use a framework than when you don't.
It boils down to this: Using a smaller technology stack makes for an easier learning curve, but your day job after learning the basics involves ten times as much code ( == ten times as many opportunities for bugs, reinventing the wheel, antipatterns etc.), but investing in how to use a larger stack means your day job becomes much, much easier; you write less code, you focus more on your business logic, and you leave the dependency management and plumbing to the framework.
Sure, you might have to use the word "Factory" a few times, but that means you don't have to write the code to implement your object pools and collection handlers. That's already done for you.
This has been my experience anyway. Even recently, I've had this kind of problem (not to name any names, but socket.io), but only because what I'm working on is somewhat more specialized than in the past.
> Using a smaller technology stack makes for an easier learning curve, but your day job after learning the basics involves ten times as much code ( == ten times as many opportunities for bugs...
I think you're implying here that not having written the framework abstractions yourself or in-house will reduce bug count. First, to be a bit pedantic, the opportunities for bugs is roughly the same over a given feature set between coded-with-framework and written-from-scratch. The the number of discovered and undiscovered outstanding bugs over that same feature set may be lower, but this doesn't necessarily reduce risk.
By using a framework you're making the assumption that most major bugs have been found and fixed by the sheer volume of people testing the framework in the wild. In a general sense, this is often a valid assumption. However this is in no way a guarantee of good testing coverage.
In my day job we decided to make further use of an open source tool to satisfy a particular security requirement. The tool in question has a community of nearly ten thousand users. However, it turns out that the advertised feature we wished to use was never really adopted by anyone in the community. Because of this we found a major "barrier to entry" type bug that had been outstanding for close to four years, and we lost nearly a month before deciding to scrap the effort and use something else.
Beyond bug count, it's been my experience that when framework bugs do crop up they're more likely to be very costly or time consuming. I say this for a few reasons. First, let's make two fairly reasonable (I hope) assumptions:
Assumption #1: Most people use frameworks to avoid having to worry about the details for which the framework offers a solution. This usually is the main value proposition of a framework (and the quote above alludes to this). This means that when you plan and design your software, you typically assume that the framework is correct. Most people don't budget time/expense for learning the framework's internals.
Assumption #2: If the framework is battle-hardened, most of the bugs you'll probably find are in oddball edge cases and/or are very difficult to track down.
In the best scenario your framework code is open and you can fix the bug yourself if need be. However you pay for this this with the original perceived value of the framework (no need to be an expert in its inner workings), and a lot of unbudgeted time. And let's face it; when we're in a time crunch, we don't do our best work. The probability of introducing new bugs when this occurs is quite high.
Aside from the specific application details that you're now worrying about, you now have new unplanned-for operational overhead. How do you maintain the change to correct the bug? You'll either need to figure out the correct procedures/coding style/etc to submit a patch/pull-request, or you'll need to maintain your own fork of the framework.
Or in the other case where you're working with a closed-source product you're just up a creek. Oh you paid for support? Isn't that cute...
I don't say any of this to attack frameworks. I use them myself quite often. However I do say this to attack the idea that frameworks make it safe for developers to remain ignorant to the inner workings of their system, regardless of which parts were designed/built in-house, as the fact that something is made and supported by a third party, commercial or community, has no bearing on its quality alone.
The issue I have with frameworks is that the Factories tend to be too tightly coupled to the problems that the original dev or dev team saw, and they aren't flexible enough for me to re-imagine their purpose. They are a perfectly abstracted a solution to a concrete problem, and implementing their [collection|object pool|routing] "API" will only let you change the steps in the process that they thought needed changing.
Factories are a fixed-arity solution to an infinite arity problem. I can't recompose factories like I can functions (in a language with first class functions). Not to mention that the APIs created to marshal data between the objects created by these factories tend to be poorly thought out because, let's face it, we're all monkeys banging out code and none of us can think at the proper level of abstraction to consider everything. But instead of using simple data types and "assume-nothing" interfaces, they try to create an abstract interface with a sample size of one problem. That's never going to work.
Enterprise Frameworks typically say factory when they mean "configuration". And when they say pluggable there should be a footnote that says *with any of our handful of implementations, don't try to write one yourself. They're very good training wheels, but they aren't the panacea to everyone's problems. Use them when they make things easier, ditch them when they get in the way. Fix them when you have the time ;-)
A boss once asked me the difference between a library (API) and a framework. Hmmm, had to ponder that one.
Besides the inversion of control -- eg don't call us, we'll call you -- I decided a framework is a prototypical (archetype) app, and you extend it.
Whereas a library is standalone that makes few assumptions about your app's "architecture" (eg the visible set of design choices).
I've written my own infrastructure (eg database wrapper, HTML generation, DOM & xpath, HTTP routing, logging, etc). I wouldn't call my loose collection tools a framework.
I'm trying to update an Eclipse RCP plugin for 4.x. (Hot damn what a struggle.) The RCP is a framework. It makes a huge number of assumptions (for better or worse) and there's the Eclipse Way of doing things.
Also, you are correct, many of the collections of software packages we today, out of convention, call a framework are actually just collections of APIs. DropWizard on the JVM. Gorilla on Go. I recognize the academic purity and the difference in approach (like you said: don't call us, we'll call you). But in practical matters, I find it easier to just consider these collections a framework.
At the very least doing so allows you to communicate with others more easily.
"What framework did you use to build that web app?" "DropWizard." "Cool."
Or, you could answer, "No framework at all, but rather a collection of APIs." "You're some kind of smart aleck, huh?" :)
The modern language known as Java (and most importantly, the coming Java 1.8) is not necessarily an enterprise language. Many people use modern Java to rapidly implement systems that, thanks to the maturity of the JVM, tend to perform very well without much effort--oftentimes none--put into optimization.
Large projects need a complete solution that Java has to offer (Java as a platform, language, and its ecosystems).
Over the last 20-30 years, there's nothing out there in the market that really increase programmer's productivity other than Java (and its GC + tools like Maven, FindBugs, Jenkins, IDEs) and Rails (not Ruby, but Rails, Ruby itself is "meh").
I have yet to feel that way with other tools or programming languages yet (one of the reasons why they all failed the "mainstream" tests: only a select few thought that their niche tools are the most productive tools ever, the rest still aren't convinced and have yet to see big projects build on top of the said tools).
I'm not sure that as true as it is popularly perceived to be; I think it may be more true that there is such a history of use of Java and similar platforms (e.g., .NET) in the environments that produce large systems that there is a cultural bias to thinking it is necessary and that much of the current experience of large systems is centered on that kind of platform.
Arguably, building large systems with less dependence on the kind of pervasive system-wide compile-time interdependencies fostered by Java and similar platforms and instead relying on smaller components with minimal compile-time interdependencies integrated at runtime using well-documented communications protocols and interaction standards -- a real platform agnostic, potentially heterogenous, decoupled Service Oriented Architecture (without, particularly, the return to compile-time interdependency fostered by the approach to SOAP/WSDL common on Java and similar platforms) -- would be better for large systems, particularly when the large systems have components that need to adapt rapidly to changing needs.
The last time I used it in JavaEE6, it was surprisingly very easy and pleasant to work with.
Server-side ===========
1. Write the services
2. Prepare your DTO classes, annotate them
3. Run through JDK command line utility => output: XSD, WSDL
Client-side ============
1. Grab that WSDL+XSD
2. Run them through JDK client-side tool utility
3. Consume the generated code (if you use maven, you can also prepare a JAR and make em as dependencies)
You can automate all of these via maven plugins easily for both sides.
Yes, you'd have to recompile them but it gives you a bit of security/guarantees unlike REST. I thought my experience was not painful enough to warrant to ignore this solution depending on the use-case/situations (i.e.: you could always go overboard).
Compare that to some random Netflix.rb (ruby based) library that internally relies on XPath... feels a bit shaky for me.
But YMMV and definitely it's more of my preferences than other people's.
I do aware of SOA-based solution by breaking down a big system to multiple services with the hope of each system can be independent of others and hopefully can be re-used easily by other services as well. The assumptions here is that each service has its own team (of 3-4 people) that maintain such systems. Sure, you can definitely write these services using anything you want and you certainly invalidate my opinions on that. But there's a price to be paid going toward this model: traceability is harder, collaboration effort also increases, more failure points, etc (I'm sure you're aware of these).
No magic bullet I suppose.
I hate how, instead of being good at "technology X," employers are requiring people to be skilled at "company Y's version of technology X."
I agree completely with this, the best antidote to this IMHO are the ideas from the lecture "Simple Made Easy" by Rich Hickey http://www.infoq.com/presentations/Simple-Made-Easy
He argues for an approach to framework development where all the different parts of the framework need to be 100% independent and interchangeable. Essentially, instead of a framework you should have 20-30 different libraries that can fully stand on their own but can be combined to give a framework-like result. You can call it the "Chinese Menu" approach to frameworks.
To see this approach in action, look at the different libraries for Clojure server-side development (Ring, Compojure, etc) which consist of tiny interchangeable libraries for specific tasks.
The new full-stack Pedestal framework also follows this philosophy (and in fact I am sure the Pedestal designers expect large chunks of this framework to be discarded as new approaches are tried withing their system, but the plug-and-play nature of all their libraries allows for effortless swapping of component libraries.) http://pedestal.io/
So, the UNIX folks had a good idea, then.
Oh, and I'm thinking of using Laravel for my latest project. Seems to do a lot of what I need without building factories. I think frameworks have evolved since then.
In that case I suggest you stay away from most literature, film, and the humanities in general.
> And, if you want to kill your ex-girlfriend, there's really no substitute for a ball-peen hammer.
> (Maybe they've never had ex-girlfriends. Or maybe they killed them with icepicks instead.)
My gut level guess, is this being an extremely old argument, the headline for this one was adjacent to a Reiser headline, so its more of a bad taste style of the times than a long term trend or hidden social bias.
I'm not sure what Hans Reiser has to do with anything and it's a little strange that you brought him up. Wikipedia says Nina Reiser's disappearance was in 2006, a year after this post was made.
On the other hand I think we are going to have to disagree on your first paragraph. I think you have a perfectly good axe, I just wouldn't grind it there. That component of the original article sucks as a writing strategy without bringing male/female drama into the picture clouding the overall issue of using images of violence inappropriately. I wouldn't downvote you for it, but someone apparently is doing so, which is too bad.
But that approach seems absurd, what we really need is a more generic factory factory factory factory that can produce tool factory factory factories and battery factory factory factories, as well as all the other factory factory factories we might need in the future!
(On another note, try reading that fast ten times)
"I don't want to start yet another religious war, but for a nice respite from the complexities of J2EE frameworks, check out Ruby on Rails. I'm playing with it now and it is a pleasure to work with."
I was actually surprised to see this is from 2005 too...
A framework should help you do your job, not get in the way.
*edit: Perhaps "writing my own" was not the best usage of words. There is a way to provide server services without writing everything from scratch. I use a number of open source libraries but I refuse to fall into the usage of factory factory factory blueprints that bundle tons of features I don't need.
I'm not saying your tradeoff is wrong, just that there is one.
Perhaps you never heard of this thing called libraries...
It's not "reinventing the wheel", it's designing and building the kind of house you want (with tons of tools at your disposal), instead of living in some customized trailer construction.
Not to mention that "reinventing the wheel" is very useful in itself. I wouldn't want to use the wooden wheels of 1800 horse carriages in my car.
Yes, and that may be a fine decision. If it's your house, and you want ringing the doorbell to play a symphony, and you want to store your cereal in the closet, that's fine. Whatever make s you happy.
The issue is when you ask other people to live in the house with you. How hard will it be for them? Is the cost worth it?
Maybe yes, maybe no.
A framework DOES include stuff that you're not gonna need, and also makes several architectural decisions for you. That's a given.
A custom build (with libraries) site does not imply it will be done in some bizzaro way ("cereal in the closet", etc). That's NOT a given.
So that particular accusation against frameworks is definitive, whereas what your particular accusation against projects not using frameworks is a maybe.
(Not to mention that some frameworks, e.g a lot of Java ones, do enforce themselves a "cereal in the closet" --or AbstractFactorySingletonFactoryProxy -- mentality).
On the other hand, if you store your cereal under a squeaky board in the kitchen, that's not helping anyone.
You could easily walk into my house and find the kitchen. The stove and sink are both there as expected. But despite how carefully I thought it through and built it, and despite the fact that it made perfect sense to me, I doubt you'd find my custom-built intranet app easy to navigate.
On the other hand, my last Rails app has a structure familiar to any Rails developer. The actual business logic is unique, but that's the part that has to be unique. "How do we update the database schema?" is a given.
And if it's unfamiliar, there's plenty of documentation and blog posts to help you. With custom-built code, there's no help on the web.
You see this sort of engineering all the time. Why does that device you just got use a non-standard power plug? What is it doing that's so special that any of the half-dozen standard types wouldn't work?
When you go and custom make something, you better have a good reason for it.
Experience a couple "framework emergencies" then you'll hate them too. And I thought they were supposed to make things faster and easier, not the reverse.
Your homebrew framework is going to have to go through all the same growing pains as any other, but you won't have anyone to lean on when the going gets tough.
If it's an open-source framework you're using, you can always fork and fix or monkeypatch if you've got problems. Most of the time your issue will be patched already in a pull-request, it's just a case of applying it. Rarely do you have a situation so unique that nobody else has experienced it.
Except, of course, when you're using your own framework.
I've seen so many projects flame out in a spectacular way when developers get it in their head that they can write their own framework, or that they don't need a framework at all. That's the first step towards unmitigated disaster. The next step is to fall into a hole that you can't get out of without a whole lot of work, and have to solve a problem that those frameworks you should've used in the first place have already addressed.
Don't forget that code you understand today quickly turns into code you don't understand in the future. Don't think just because you wrote it you're automatically golden when it comes to making fixes.
I've spent a long time in Rails and it solves most Web + CRUD problems well enough. When it doesn't you have options.
Recently I've been doing more NodeJS stuff which requires a completely different mind-set. If you try and do Rails in NodeJS you will fail, and vice-versa. Same goes for something like Django.
This is why picking a framework that approximates your requirements and matches with your philosophy as closely as possible is essential.
Going without a framework is almost always a disaster. At the very least pick one that's thin enough it doesn't get in the way.
I think you're overgeneralizing on the last point. I've shipped things without a framework that have been some of the most stable pieces of software I've written.
And that is the fundamental mistargeting of most framework marketing. The ideal short demo or short tutorial for a framework is probably a noob-friendly simple "CRUD plus a little bit". On the other hand that is a horrible actual application for a framework, all that complexity for little reward. And its such a noob magnet. Never programmed in ruby before? No problemo, "rails new crud-demo" and good luck.
I'll agree you need a framework to do something complicated. Not everything is complicated, or grows to become complicated.
This may be the hidden meaning of the original article from 2005. Superficially the joke is frameworks are hyper abstracted into factories for factories for factories (well maybe yes, maybe no). But the more fundamental interpretation of the story is I don't want to enter mass production, I want a fast simple reliable one-off. It will never be the next twitter and it will never be used by more than 1000 people. And sometimes, that's OK.
Especially if there is a demarcation point or highly detailed definition, but multiple incompatible interpretations simultaneously exist.
If the concept of the failure mode doesn't even exist when the unit test is being written, or is in direct opposition to the stated business plan at that time so "it can't happen" then unit tests can't help.
Even worse is political issues. Yeah sure I promised in writing our demarc point is I'd send you an ASCII file but it changed at midnight to UTF-16 strings inside an XML file and you're either going to like it or work elsewhere and I can make this stick. Oh, well, when you put it that way, then I guess that's why I'm working at 1 AM. A contrived example for short simplicity, the real world is much longer and more complicated.
(My statement isn't really ALWAYS true, but neither is yours.)
It's almost like common problems have common solutions ;).
Of course they will implement framework-like features, that's inevitable. You'll still need routing, authentication, etc.
The win is that they'll implement them for their SPECIFIC use case, and only as much of them as they need, instead of having to accept the whole garbage that comes with a framework.
And you can cherry pick the best libraries for the cause, enging with even better ones that what any framework offers built-in.
But what happened, is that Java lost just enough power and abstraction, so that the cost-benefit of burgeoning software tooling was still a net win. What Java lost in power, it made up for by writing more code. This is why Java web application servers, Java IDEs, Java messaging middleware became these lugubrious and unwieldy monstrosities, while we in the Smalltalk camp marveled at how we had equivalents that had start up times and enabled edit-test-debug cycles orders of magnitude faster while being comprised of less code -- and yet we were the ones saddled with the "legacy" label and the reputation of being slow. (And entire kinds of tooling like Spring and Maven -- just entirely absent and unnecessary!)
Summary: beware of the situation where something is hyped, but you still wind up with more tooling and writing more code than you would have otherwise.
Most likely, you can do it with less code.
I've been picking on Java here, but this applies to the majority of cases. It even applies to some things in Smalltalk. What are you really trying to accomplish, and can you get most of the same effect with less?
In the early days there were general purpose toolmakers. And tool users had to develop the skill to use general purpose tools. They could then tackle a variety of tasks.
Today it appears that the most effort goes to making special purpose toolkits (e.g., frameworks). The only "skill" that the toolkit user must develop is mastering the toolkit. But the kits are enormous, the documentation is enormous and the time commitment is, relative to the number and variety of tasks she will be equipped to tackle after mastery, enormous. I'd venture to guess most users of frameworks only use a small fraction of the toolkit. Hence they can only tackle a small fraction of the tasks that the toolkit could permit them to tackle were they to master all of it. To learn how to use every feature (every tool) within these specialized kits would seemingly take a "lifetime".
Is learning a "framework" worth my time? What happens when the tasks change and the toolkit I've mastered is replaced by a different one? What if I spent my time learning how to use the general purpose tools (still available on every computer running UNIX) that can be used to build special purpose toolkits instead?
Measured in terms of learning and skill development, maybe the greatest benefactors of frameworks are the folks that build them. That is a thought I had. Presumably they must themselves know how to use more general purpose tools. Thus they can build frameworks of more specialized tools. If this is true, that is a skill that is worth the time investment, in my opinion.
Joel on Software was a great forum. I only wish Joel was a UNIX programmer. His frame of reference always seems to be Windows.
But if you're building a city then the chances are that you don't want the people who furnish each flat in it to have to worry about how the plumbing is done. You want them to be able to concentrate on just their bit, and let the infrastructure work around them,
And that's when these frameworks come in handy - when the people churning out CRUD code to process data don't have to worry about what the message queuing system is, or how their code is instantiated, or where it's going to be used - they just have to wire up a couple of standard interfaces, and make their specific code work.
Someone else will have set up the configuration for them (whose job it is to do just that), and they can get on with their speciality, rather than trying to fashion their own hammers out of rocks, logs and twine.
Which change constantly over time. I started playing with Rails in 2006 and refuse to touch it ever again. Oh god the tragedy when rails upgrades and now I have to figure out why the code no longer works. Perl CGI was never, ever, even in the bad old days, nearly as bad as that.
Rails is awesome for development. The rest of the software lifecycle, well... Lets just say it is never allowed to leave development. You're one apt-get intended to patch a security hole, away from a significant rewrite project. I hate it.
Someday, when its totally obsolete, it'll finally be stable enough to be "enterprise grade". Till then I've had enough.
I'm sure you should have probably understood why your code 'no longer works', perhaps some bad Ruby/Rails programming practices?
Its marketing doesn't match its design. Its a tool for experienced experts to work slightly faster using the One-True-Workflow which they already know. On the other hand, most books, online tutorials, etc, show it as a noobs playground. Its like taking the kids to a neighborhood park that turns out to resemble an Indiana Jones movie set.
I had zero ruby experience when I started fooling with RoR in 05, 06. All rails did was get in the way of developing those language skills. Training wheels on a Harley Davidson, something like that.
Write once, upgrade never because it'll stop working and as a noob shielded from the cold hard world by the framework, you won't have the experience to be able to figure out why. What a pain. The whole experience, just suffering.
Off the top of my head, around 05/06 going in as a complete ruby and rails noob, there was no noob-obvious handholding way to handle many-many CRUD. Things have in fact probably improved quite a bit since then. The problem is with a one-true-path culture, everything has to be rewritten to fit the enforced style of the day. And frankly for some meaningless intranet "CRUD plus a little more" app thats now become somewhat biz critical, I don't want a life of permanent rewriting.
Ah, whatever, just ignore my ranting. My experience has been horrific and it'll color my judgment. I'm sure for everyone else its all candy corn and unicorns and balloons all day long, and will continue to be so. I'll just use something else.
I realized the other day that Rails is designed for Internet time: ship as fast as possible, see if it sticks. If it does, then needing to re-write every few years is assumed to be no big deal, as, presumably, it is succeeding.
I view rewrites as a fundamental failure of design. I should be able to evolve the domain model independently of the UI. Only when there are massive, breaking changes in the scope of the application ("we're going to sell video games instead of show classifieds!") is a rewrite truly necessary.
But, IMO, industry hates design because it alludes to the fact that programmers are not easily replaceable. So, it pushes a new framework or language every 2 years to keep people hopping around, solving the same problem over and over. Meanwhile, it fails to train those people in the (mostly timeless) ways of solving problems reliably. And devs lap it up, secretly hoping it will fix all those icky maintenance problems they're starting to run into.
If you mean something that is easy to get started, deals with the most annoying stuff, and gives you the fundamentals to implement an application, then I think there are some good options.
Of the Java frameworks we've tested [1], if you are ruling out Play-Java (because of a real or imaginary Scala design preference; I'm not judging that), I personally enjoy the coding style of Rest-Express and DropWizard. Check out the Rest-Express [2] and DropWizard [3] multi-query test implementations for a quick insight into their coding style. (Note the Rest-Express test was contributed by that framework's author.)
I'm not sure if this really answers your question, but I think it does speak to my earlier point in this thread that modern frameworks solve the problems I most care about and also (happily) tend to do so more efficiently--with respect to server resources--than the frameworks of a few years ago.
[1] http://www.techempower.com/benchmarks/#section=data-r6&hw=i7...
[2] https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...
[3] https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...
Nothing against scala specifically, just using Play-Java (which we are) means you are bound to using sbt and when debugging into play internals you are looking at scala instead of java.
DropWizard is fantastic, will check out rest-express. I think the thing I miss from both that you do get in play (and rails) is the front end templating, assets pipeline, and useful assorted bits tailored to quickly building a html/js/css/api web app.
It's certainly not anything like rails, but if I'm forced to work in Java I'm quite fond of SpringMVC, especially for building restful services that need to support a bunch of different serialization formats. Once you get over the fact that Spring-done-right is a bit XML-heavy, it's quite good. Also since most of the heavy-lifting is front-loaded into the the context initialization it can be very performant.
Otherwise for more simple stuff I just drop down to straight-up servlets and JSP.
If you can relax your requirement to just the JVM there are tons and tons of options...
There are loads of bad frameworks that want to be too smart and too clean. I mean, there is nothing wrong with writing HTML. But I've seen stuff like:
$output .= $framework->dom->returnInputElement('text', 'name', $initValue, $options);
That's nice and all but when it just returns the element without any extra functionality I think its just a waste of code and resources.I hope it at least protect from XSS attacks.
But for consumer facing stuff, you should probably abstract to something that templates (HAML, mustache, etc).
i can relate, writing apps in rails, django, etc is much better than what was available back in the day (8 years ago!) for java side, spring was just starting to emerge around that time if not later which gives you a pretty comparable experience to rails.
edit to add some anecdotes: scalac and javac are written by the same person. The founder of Relevance, the company that funds Clojure development, wrote a book in 2006 about spring and hibernate.