I want to state that I am a „Certified Springsource Professional“ (whatever that means anyway) and that, after doing some CORBA, EJB and lots of Spring in my carreer I am really biased. Totally.
I am glad Eberhard Wolff poured his thoughts about Java EE and Spring and why he doesn‘t care. It is long time since I wrote my last more then a tweet long posting, and since I do care, it made me sit down and write again.
I do care about Java EE and Spring, and I think that you might too.
Last, I would like to apologize for the title, it is misleading. While I truly do believe in Java EE and Spring, this post is clearly should be titled
„EJB, Spring, FUD and why you definitely should care“.
Java EE and EJB are different things. Believe me on this one for now.
Let me take Eberhards lead – I would like start with the current state. It is true, I hear and read people asking the same question „EJB has catched up, so why use Spring. Where is the added value?“.
While it is true that a side by side comparison would not make a lot of sense and surely would be boring, I would like to refocus on the question for the moment.
EJB did not catch up. Just because we don‘t need abstract classes anymore and we somehow managed to hide our dependency lookups into fancy modern Annotations does not mean we got any close to where the Spring Framework is today or even was in the past. It takes more than Generics and Annotations to modernize a framework that has its roots in CORBA-Architectures.
Frankly, it takes some time to learn EJB and surely not less time to understand what the Spring framework is all about. Let us just do some respect to those behind both frameworks by just stop comparing Annotations and counting JARs.
I agree with Eberhard when he writes that this is „asking the wrong question“. Time to grow up here.
Reducing both frameworks to a dozen bullet points in a Powerpoint (Keynote in my case) presentation makes them replaceable. It does not matter which one to use, and this leads us to the holy cow of standards. Since EJB apparently catched up, why risk not being standard?
Java EE matters. EJB does not.
It is amusing. Ever noticed that, because of EJB 3 you don‘t need Spring anymore, but if you use Spring people warn you not to drop Java EE entirely?
Let us focus on Java EE for a moment. The next picture was taken from the actual Java EE specs. Do you recognize the Java EE Architecture Diagram? If not, it is a good time to remember you to take a look at the Java EE Specification PDFs in the near future.
If it is new to you, how long did it take you to find EJB there? And, if you are a Java EE expert, think about how much are you giving away by not using EJBs?
Look at the picture. Java EE and EJB are different things.
Why do we need something like EJB in first place?
Sometimes, especially true for software development, we don‘t like to reinvent the wheel. We call it reusable software design and we use components, modularization and loose coupling to archive that kind of „hey listen, this is a wheel, we have done it before“.
To help us with all the wheels we have at our disposal, we created architecture blueprints. There we named the pieces and explained how to put the jigsaw together. This is why you will find DAOs in integration layers, services and managers and somehow always find yourself around in a Java EE application. Patterns, naming conventions, all true, all valid, independently of EJB and Spring.
Generic frameworks are created to help us not to reinvent the wheels. And they are, by design, generic. So you end up creating a short layer on top of them („my foobar application framework“). This is your job, my job. We are nowhere close to get rid of this.
EJB is one of those wheels we really don‘t want to reinvent. There is lot of know-how required to define (and later build) such a generic framework. EJB is a nice framework if you play by the rules (sometimes we call it „design by restrictions“) and if the rules do not hurt in your domain.
Here we come to the point where your application stops being Java EE conform, your „my foobar application framework“ is an ugly piece of closed source software. You have more than one problem now: you created your own little framework that you have to extend, document, maintain and bug fix. And you will be doing all this playing by the restrictive rules of EJB.
If your software does not need any layer of abstraction on top of EJB, go away, stop reading. You will be happy with the way things work for you right now.
JPA and EJB are different things. Surprised?
In the past, enterprise persistence as a higher lever service was truly part of the EJB. Persistence was named Entity beans and it was ugly. The first and second implementation of entity beans differed completely from each other, we had to migrate. People started using hibernate or other ORM solutions, EJBs Entity Beans had a very bad reputation. We had a lot of try and error with persistence in the early specs, ended up cloning Hibernate and called it the new shiny Java Persistence API, JPA in short.
It would be wrong to think of JPA as part of EJB. EJB uses JPA, not more, not less. There are lots of projects that are described as being EJB 3 projects just because they are using hibernate hidden behind JPA Annotations.
So, the current state is: by not using EJB, you still have JPA and JTA to play with. They are standalone specifications not bound to the EJB specification.
To be or not to be: the state question
There is something that EJB does have what the Spring Framework does not (technically spoken): Stateful Session Beans. Those are the „heavyweight“ components in the EJB stack, and the ones that are closely tied to the number of client sessions you will be running on your system. They introduce state, state passivation and all the lifecycle required to manage the bean across the different transactional states. It might be that, with EJB3 implementing stateful session beans got easier, but the inherent complexity of such beans cannot be reduced. Know your vendor, know you framework. This is no piece of cake here.
In a time not too long ago the main discussion concerning Java EE Architectures where those concerning state, discussing if the backend should have state or not. Software architects argued if and why not one should design a stateful server. Scalability, clustering and session passivation and synchronization where hot topics.
It is long time since I met someone defending state on the server.
EJBs without Stateful Session Beans and Persistence
So what is left? Good question. Stateless Session Beans. Those pooled beans with that simple lifecycle. And there are those message driven beans, but hey, technically speaking, those are stateless session beans listening to a JMS destination, no nothing really new here.
So, if we want to reduce the EJB versus Spring topic to a real minimalistic question, it would be: thread safety or not. EJB is the only framework in the whole Java EE specification that cares for thread safety for you. The servlet API deprecated the thread safe servlets a long time ago because of performance and „well, it was not really thread safe“ issues.
Nailing it down, Spring will give you singletons and EJB will give you pooled, threat safe beans.
Having singletons in a Java EE environment is some real added value, hence we had no way to implement singletons before Spring. No managed bean context in Java EE backend provided such simple construct as the singleton pattern. In Java EE with EJB you end up hooking up some instances in the naming context, but this time unmanaged, not thread safe and you have to manage the lifecycle of those instances for yourself. I met very few people who have chosen this path, and there are too many people asking how to implement/ setup a singleton EJB.
EJB 3.1 introduced singletons.
“By default, all Singleton methods are made thread-safe and transactional. This means that all multithreaded access to the bean is serialized and all methods are assumed to have a REQUIRED transaction attribute.” (source)
Further reading here.
Think of it: a singleton EJB! Multithreaded access is serialized. Wow.
And, finally, if you do not have real singletons, kiss JMX goodbye. Start creating your own (proprietary, closed source) management and monitoring layer into your application, because this time you are not allowed to use the standard.
FUD. Fear, Uncertainty, Doubt
„Spring is a proprietary thing, Java EE is standard and you will end up in a one vendor lock and without support.“
Anyone that is using either EJB or Spring in any runtime is in a vendor lock. Ask Atlassian (Jira, Confluence, …) how hard it is to provide products that are meant to run different vendor application servers.
Support is a hard topic, this is where vendors patronize customers. A vendor can start finger pointing and refuse support when it sees non Java EE frameworks. How good such support is in first place I cannot tell, but it does not feel like support, it just feels like „who to blame and make responsible for“. Java EE has been „on production“ for some years now. We don‘t really expect to be running into mythical support issues with the major runtime environments anymore. If something goes wrong, than it is your proprietary closed source own code that is the culprit, it won‘t be the framework. Vendor support won‘t help you here, as the fingers pointed will be directed to you at the end.
And yes, it is proprietary. There is only one server-side component model in the Java EE specification, so everything else is proprietary. If you need runtime modularization, go for OSGi. You might be surprised to hear that the Spring component model is the OSGi standard component model. In this parallel universe, EJB is proprietary and worst – it won‘t even run there.
Did I mention that Java and Java EE still lack a modularization specification?
„Spring gives you more flexibility by the price of increased configuration complexity“
This is, as for today, a lie. Sorry folks, but comparing EJB 3 to the configuration common to Spring 2.0 is dumb and unfair. As dumb and unfair as showing a resource configuration xml file used in Websphere deployments.
I would not do that.
Sorry. Had to show you. Magical. Truly amazing. And don‘t tell me it is ok just because we have tools. It is not.
The point is: there is no EJB without product specific configuration. Huge config files are a nightmare when it comes to automation, bug fixing, version upgrade. Sure you have expensive tooling with wizards and editors, but you would not need them in first place. And the fancy tooling does not help you find diffs in configs.
Complexity and tooling
Java EE huge configuration files and cumbersome packaging is a real show stopper when it comes to development efficiency. We started solving those problems by creating and using even more complex tools, the development is nothing close to agility.
The packaging of enterprise applications consists of archives (ZIP files) and meta data descriptors. This EAR (Enterprise ARchive) must be packaged and (re)-deployed after each change that the developer wants to check in the runtime environment. If you are lucky you get away with a few hot deployment cycles before you have to do a full restart of the application server. And this is no ones but Java memory management fault, you will always end up into permgen memory issues. Regardlessly of vendor, this holds true for Tomcat and for Websphere.
After all, tooling is the wrong answer to the EJB complexity issues. We started using complex tools to hide away the complexity of the underlying enterprise development and deployment lifecycle. The tooling does not help, it makes it worse. And all this goes with the price of efficiency, as development deployment turn-over is measured in minutes and not in seconds. It is not modern, it is not agile. It is frustrating.
Java EE leads to Vendor and Version lock-in. Be warned.
It is all about standards. Yes, it is. Even the vendor and version lock-in is standardized. No kidding.
Java EE is the umbrella specification that should provide us two things: give us an architectural blueprint and shield us from specification version jungle. As software architect all I have to do is follow the blueprint and trust the versions. The actual Java EE Version 6 was finalized december 2009 and lists 28 technologies with corresponding versions that as „Full Java EE Product Requirements“, among them:
- EJB 3.1
- Java Persistence 2.0
- JSF 2.0
There is a good reason why JPA 2.0 was released, and there is no good reason why I should start a project today not using JPA 2.0. Same applies to JSF, another standard that did vastly improve with version 2.0.
And if you would like to use JPA 2.0 today, you are better of with Spring, since – as far as I know – there are few to none Java EE application servers providing JPA 2.0 support. But this will change in the future: then you would like to use JPA 3.0, but there will be few to none Java EE application servers providing the newest API.
By the way, do you know what I mean what by „newest API“? The first early draft of JPA 2.0 was published in May 2008. The proposed final draft was published in March 2009. The final release is dated 10 December 2009. It is not new stuff. It has been around for at least two years now, and all major Java EE vendors are in the expert group.
Am I to naïve to expect releases from the major vendors a few days after the specification gets finalized? Naïve or not, using the actual versions of selected APIs can be hard to archive on an full stack application server even today, 10 months after specification release.
Standards should protect my investment
But they do not. The EJB specification did not hesitate in breaking with contracts and programming models in the past. The future does not look good either, as technologies bekome required elements in a full stack application server. Keeping backward compatibility has become a problem and nobody takes it for granted that my Java EE application will run on the next version of the application server. You might get along without making any changes, but you won‘t know it until you fully test it. So what is this EJB standard good for anyway? All we have today are very cheap copy clones from Hibernate and Spring in Java EE. There has not been innovation from within Java EE for years now. The vendor lock-in is getting worse, the tooling more heavyweight and complex.
So actually, if want to use hassle free deployment, stay away from full stack Java EE application servers. Or, you will probably end up in a vendor and version lock-in (it feels a little like Internet Explorer 6 all-in-one-vendor-plus-version-lock-in).
Take a look at JSF. JSF is obligatory part of a full stack application server, but JSF gives you nothing. Again, you have a component model, and each vendor will provide the required runtime API. But you won‘t be happy with that, you will need a JSF library like RichFaces, ICEFaces, PrimeFaces, MyFaces, etc.
Take a good look at those. You will realize that, once you start using JSF, you are not standard anymore, you are bound to the JSF library vendor. The programming models for the components are different, the tags have different names. Switching or mixing JSF library ranges from very hard to impossible. So what good is the JSF standard for? Why is RichFaces for JSF 2.0 taking so long and how many people are developing it? Will it be there tomorrow? Will it be continued? JSF surely, but RichFaces, ICEFaces? Who can assure that?
Historically seen, the best way to protect you investment in the past would have been using the Spring Framework. All major releases where drop-in replacements, new features pouring in without compromising the existing programming model or the living code. Glimpsing at the feature we are seeing answers to modularization, cloud computing, massive data storage, full text search,complex event processing coming from the community, not in the Java EE. For some time now, innovation has found its home in VMWare/ SpringSource and Google labs.
… one more thing
If you are looking for a god excuse to pick EJB instead of Spring pick the thread safety one, as this is, IMHO, the least embarrassing one. You will only have to explain why you have thread safety concerns in a stateless server that you cannot handle for yourself.
To wrap things up, let us never forget that, while EJB is really nothing more than than server side component model reduced to stateless session beans from the practical Java EE point of view. It is nothing, it is meaningless.
EJBs are more like an appendix, a useless remainder from the Java EE grandfather CORBA, useless today, but still there.