What's wrong with EJB is that it's being marketed as a technology that "reduces time to market for mission-critical applications, effortless scalability and portability, reduced reliance on hard to find developer skill sets, and an overall increase in developer productivity.", but is in fact all lies. The message is coming with a book-thick specification that is so complex that it must
lead to buggy code. -- LozPit?
Sounds like there's a bit of touchiness there... :) Anyway, I have to agree with you in principle. The technology solves some real problems, but it's not "so easy a child could do it". EJB's are starting to suffer from AllPanaceasBecomePoison.
- This page is in SeriousNeedOfRefactoring. I have avoided using the Ref**torMe badge because it seems to be pretty noisy. Also, I would do the refactoring, but being from Microsoft, I am probably not the best choice for editor of this page. People would suspect me of an unfair bias. -- DinoChiesa, December 2004
has been asking me why I am only lukewarm on the EJB specification.
My reason is that it depends too much on MagicCoincidentalReflection
, instead of language features.
Firstly, the create(args)
methods that are defined in the EjbHome
These are mapped to the ejbCreate(args)
methods in the EjbBean
I presume the way this works is that the EjbBean
is instantiated using a default constructor, and then exactly one of the ejbCreate
methods is invoked, i.e. that whose args
matches those given to the create
Using standard language features, there's no guarantee you (the developer) will get the implementation of this right.
I know because you are a smart programmer you will, but what about other people?
Alternative ways to design this would have been for the EjbHome
to delegate those calls to an EjbBeanFactory
, which implements the same create methods.
Then the EjbHome
and the EjbBeanFactory
could implement a common interface, constraining them to be the same at compile-time.
It would also have been better (I believe) to map the create
functions to constructors.
(If you map create to constructors, you wouldn't be able to pool and reuse instances of EJB. Also, the meaning of create is different for Sessions and Entity beans -- RafaelAlvarez
The second complaint is also about objects coincidentally implementing the same methods. The EjbRemoteInterface?
and adds additional methods. The EjbBean
implementation implements SessionBean
, and also those additional methods. Obviously the functionality that really matters to the developer is the additional methods. The developer probably has a very good understanding of those methods, and may even have them defined in an interface. He probably should
have them defined in an interface, and no doubt thinks of them that way. However, EJB doesn't refer to the business interface implemented by the bean at all, except as additional methods luckily implemented by the remote interface and the EjbBean
If this interface were explicitly named (e.g. in the descriptor), we could be more sure that the EjbBean
implements the remote interface. The EjbContainer
could also automatically delegate invocations on the bean to an implementation of that interface which knows nothing whatsoever about EJB.
These are fairly minor complaints compared to the value of a standardized component infrastructure. But I just wish it was a bit nicer.
The EJB specification does not forbid the EjbBean
from explicitly implementing its remote interface, but strongly discourages it, presumably because one usually do not want to leak the EjbBean
reference outside the container. This does make the programming model somewhat strange, like passing the remote reference instead of this
is explicitly named in the DeploymentDescriptor?
. At container generation time, the EjbBean
is indeed checked to implicitly implement that interface.
The biggest complaint I have against the EJB specification is its rather heavy weight programming model, which makes it difficult to decide on the granularity of the beans.
Another reason why you wouldn't want your bean to implement your Remote Interface is that the remote interface extends EJBObject.
This means that you would have to implement all of the methods in the EJBObject interface! You don't want to be doing that in the bean.
A simple design pattern gets around this problem:
- Business Interface - defines JUST the business methods you want to have
- Remote Interface - one line. extends business interface AND EJBObject
- Bean - implements the business interface
So now you have compile time checking. You can also go further and have an object that implements the business interface and have your bean extend it. This allows you to "strap on" the EJB infrastructure.
It is always difficult to find the right granularity in an OO-design, especially in distributed applications. In CORBA the objects delivering services are usually kept as coarse as possible and I think this also applies to EJB. It's not wise to have lots of fine-grained objects floating around in your distributed space.
So yes, the EJB programming model is quite heavy, but considering that Beans are usually very coarse, that doesn't have to be a problem.
Using constructors to implement ejbCreate() with different signatures is not a good idea, based on the fact that it is very expensive to construct new objects. The EjbModel?
allows the EjbServer
to pool instances of Ejbs for reuse whenever needed.
I'd be surprised if that was true. On a modern VM, allocating an object takes a few instructions; initializing it takes more, but that's all being done in ejbCreate anyway; collecting it after it dies costs more again, but the overall cost is still really quite low. It's certainly less than the database hit that accompanies every ejbCreate, and so it wouldn't really add much to the total cost. Someone correct me if i'm wrong about this.
You are correct that the cost of object allocation/deallocation is mostly irrelevant, despite persistent superstitions in the Java programmer community. That's not the benefit of Pooling EJB instances. A session bean (for example) will almost always require resources to do anything useful. Since you'll likely do something like look up a DataSource? or another EJB upon "creation" that's where the pooling payoff comes. Most JNDI implementations are mysteriously and inexcusably slow even within the VM, so we can't afford the lookups upon every remote interface method call.
EJB's biggest problem, for me, is that it uses the CORBA/RMI style of forcing
your code to catch and handle loads of exceptions (actually, javax.rmi.RemoteException
). If you're doing things right, you can easily end up with a whole try/catch mess for every
remote method invocation. This is also, and originally, WhatsWrongWithCorba
avaSoft just ripped it off for RMI, and didn't sort out the mess when they did EJB either.
The result is, frankly, messy code. It's very
hard to make your code clear, simple and easy to understand when the few lines that actually do something are smothered in many more lines of hideous nested exception-handling.
I think in Smalltalk this would be much cleaner (I think
- my Smalltalk knowledge is very limited) because the exception handling is so much cleaner and less invasive.
is the only CORBA ORB / EjbServer
that I've seen that gets it right: it bends CORBA and EJB so that you can
catch all these exceptions if you wish, but you don't have
to. In other words, they've actually delivered on the "transparent distribution" idea that CORBA etc didn't quite manage. The result is that you can actually write clean, simple code that other people can understand.
The RMI philosophy is that forcing try-catches of remote failures is a feature that is necessary for robust distributed computing. JimWaldo?
, the chief architect of RMI, has long been an advocate of explicit distributed computing. The philosophy is that local-remote transparency is a myth, so don't try and pretend the network doesn't exist in your software design. It may look like 'cleaner' code when you write it, but it will run cleaner code at runtime if you actually deal with the issue of distribution properly and explicitly.
I find it kind of interesting that this page doesn't mention a major failing of EJB compared to explicit transaction control. Generic EJB is always going to be slower. This is okay if you want to do financial transactions, but lousy if you want to use it for web applications (which many people do). Many people want EJB, only to find out after they have it that they really didn't want it in the first place.
What do you find slow about it, per se? Is it the spec itself, or a particular app server? If people use EJB as a crutch for justifying poor design, then yes, I could see it as slow. However, since you mention explicit transaction control as faster, I'm curious: assume you have someone who isn't just arbitrarily demarcating all of his/her business methods with TX_REQURES, or is using RMI calls fine-grained methods. Why would it be slow then? Using client-demarcated transactions is a big trade-off with more dimensions than just performance.
EJB does not encourage good design - that might be its biggest failing. Then again, neither does COM+. They are not substitutes for expertise.
Stu, you're right in that someone who knows the model well and knows the trade-offs will have equivalent performance. However, EJB is marketed as a solution which "takes all the complexity" away. Knowing EJB well and knowing when NOT to use it is more complex than learning EJB itself. Until proven wrong, most people will go for the least complexity possible and then wonder why their application is syncing to the database on every assignment.
I suppose what I object to over EJBs themselves is that they are marketed as a silver bullet instead of a tool.
I still maintain that WhatsWrongWithEjb
is it's design-by-committee complexity. This is most apparent in it's transactions which are way too complex and offer too many models and types. The ComPlus
model is simple and cleaner. Also, because of it's design-by-committee approach we have the same situation as Corba with different vendors implementing different services and vendors unable to speak to other vendor's implementations. If you use one Application Server today to serve up your EJBs it won't run on another without changes.
I think we'll have to agree to disagree on this. I find EJB tremendously simpler than COM+. And CORBA. Though CORBA is a different sheep, since it tries to do *everything*, including curing world hunger (I think there's a CORBAfacility for that around the corner...)
COM has a lot of history behind it - as a technical trainer, I find that while COM's philosophy is easy to explain, actually explaining how to use it requires a lot of arbitrary tidbits of knowledge related to its evolution. Contrasted to EJB, I can rationally see and explain a lot of the reasons behind why they did things the way they did.
- [Does this mean IfItsNewItMustBeBetter? Wait a few years and EJB will accumulate some cruft just like COM did.]
- Another person. Has it not already? I thought it has inherited the InternetInterOrbProtocol stuff, without which the various Ejb implementations cannot communicate with each other. -- dl
In terms of transactions, I don't really see any complexity beyond what COM+ offers, since their declarative transaction models are very similar. Allowing client-demarcated transactions is definitely a necessary evil if you want to do heavyweight distributed transactions among legacy TP monitors/mainframes...
Furthermore, most of EJB wasn't necessarily design-by-committee... it was driven heavily by 2 architects within Sun, with input from several Java licences. The Java community process is quite lightweight to the Object Management Group that controls CORBA.
Also note that J2EE is intended to help this portability problem, and so far it actually seems to be working.. EJB 2.0 also includes a pluggable persistence manager to actually allow realistic (and potentially portable) container managed persistence.
I'm not a huge fan of EJB - there still aren't enough tools to really take advantage of off-the-shelf business components, it doesn't give you enough exposure to the underlying server (if you want it), and it leads lazy people to believe that they don't have to put *thought* into their designs...
On the bright side, it has really done wonders to the competitive landscape... the number of choices available is great!
Here's what I have been trying to warn people about is a huge flaw in EJB:
- Osborn: So you won't insist on there being a "pure C#" or a "pure .NET" implementation?
- Hejlsberg: What's "pure?" How many "pure" Java applications really exist? I venture to guess very, very few. That's what the numbers I'm seeing suggest. Let's face it, people need to leverage their existing code. It's just not possible to require companies to throw everything away.
- Goodhew: Have you had a chance to talk to Roger Sessions? [Editor's Note: Roger Sessions is president of ObjectWatch? and the author of COM+ and the Battle for the Middle Tier.]
- Osborn: No, I haven't.
- Goodhew: Roger got the relevant section out of the Enterprise JavaBeans [EJB] specification, which talks about permissible vendor extensions. Not surprisingly, the vendor extensions include things like transactions management, which is fairly important in building enterprise systems, as well as security, messaging, and more. In an article, Sessions lists roughly eleven areas of functionality, which are vendor specific implementations that are permitted. So, if you pick IBM Websphere as your EJB implementation, the code that you write for your EJB application will inevitably lock you into Websphere. This notion that Java is 100% pure and gives you 100% portability just isn't true. There's a great interview with James Gosling on IBM's developer works site in which he directly addresses this issue. He said, yeah, the whole right-once-run-anywhere, 100%-pure-thing was a really goofy idea, and was more of a marketing thing. He says, in effect, "We didn't think we'd ever be able to deliver all that, and basically we haven't." Here's the inventor of the language saying that neither purity nor portability exists. FUD Alert! (Again). See CsharpLanguage
Slightly off-topic: Is Goodhew talking about this interview with Gosling?
If yes, where does he say that? If no, which one does he mean? -- HaskoHeinecke
How about this interview with Gosling: http://www-106.ibm.com/developerworks/features/gosling/
(search for the word 'goofy').
Glad you asked. (I think you misunderstood the question. I've rephrased it, so the answer may no longer seem appropriate.)
I had been meaning to come back and clarify that statement. Here's the part I mean and why I think EJB is not a good solution "Roger got the relevant section out of the Enterprise JavaBeans
[EJB] specification, which talks about permissible vendor extensions. Not surprisingly, the vendor extensions include things like transactions management, which is fairly important in building enterprise systems, as well as security, messaging, and more. In an article, Sessions lists roughly eleven areas of functionality, which are vendor specific implementations that are permitted. So, if you pick IBM Websphere as your EJB implementation, the code that you write for your EJB application will inevitably lock you into Websphere."
It's that vendor lock-in that concerns me. It's the exact same problem with the Corba spec. Anytime, you leave things like this unspecified, vendors create islands. In our EJB development at Viridien, we were locked into BEA WebLogic
and it wouldn't work on WebSphere
. In contrast, COM is an exact binary specification and MTS/COM+ are exactly specified. All of this is moot anyway. DCOM, Corba and RMI are going away, thank goodness to be replaced by XML, SOAP and HTTP, as it should be. Internet standards. IBM and MicroSoft
, and many others are behind SOAP. MicrosoftDotNet
is in that direction. The Internet always wins. I'm glad MicroSoft
finally woke up.
So... to avoid nasty vendor lock-in, go with MicroSoft. And to avoid getting rained on, jump in the river. -- GeorgePaci
- My view is that you cannot avoid vendor lock-in, though EJB guys try to convince you that you can. You get lock-in any way you choose - either with MicroSoft or WebSphere or WebLogic. Let's just all admit it. And let's hope you don't get locked-in to one of the other vendors, who all seem to be fading. (PersistenceSoftware, GemStone, BlueStone, all failing to thrive independently. and just today, AllaireCorp? gets bought by MacroMedia?) -- DinoChiesa, January 2001
Of course there's going to be consolidation - there are too many vendors. GemStone
was bought by Brokat and isn't doing too bad. Persistence is still floating solo. BlueStone
was bought by HP. I don't see why this is a bad thing. Furthermore, I teach quite a few classes and work on several projects involving EJB and I've managed to get my peers to port non-trivial beans between GemStone
by only configuring the app-server-specific XML deployment descriptor. EJB is much more vendor-independent than it used to be, and J2EE has a lot to do with that. -- StuCharlton
- Consolidation is not a problem. The point is that vendor lock-in is a reality regardless of the path you take. EJB just plain is not vendor independent. No 3rd party components. No mix-n-match tools. Can't use JBuilder to build optimized beans for WebSphere. Can't use VAJ to do likewise for JBoss or WebLogic. It's tight coupling between tool and runtime, and it's vendor lock-in. Your example is fine, but it is a classroom setting. I don't doubt that you can write portable code. But a complete app with commercial-class performance, security, and scalability? Is the DD portable? The admin interface? The security? All the extra-EJB optimizations (like pass-by-ref or "smart" entities). No no no, and no. Run in fear from Microsoft if you wish, but don't think for a moment that you are avoiding lock-in when you run into the waiting arms of BEA or IBM or Oracle or... . -- DinoChiesa
Look as SQL DBs. Nobody will change from one SQL DB to a different one if not absolutely necessary. The SQL implementations have subtle incompatibilities. Still SQL has benefits. You have to learn it just once and then you can adapt to all the different DBs. I think this is what's going to happen with EJB: There are benefits of the standard but you will not be able to easily migrate from one vendor to another. Another benefit of the EJB standard might be that components can be created that can be used on every EJB server. This might be the technical foundation for a server-side component market place. -- EberhardWolff
- Wishful thinking. EJB has been out for 3 yrs, no 3rd party marketplace. And don't say Diamelle. That is a single vendor, not a viable market.
Actually, we have been able to deploy our applications (logistics software) under just about every ApplicationServer except WebSphere
. So it could
be a case of vendor lock-out instead of VendorLockIn
. -- AalbertTorsius
It's too complex. -- CimarronTaylor
That too. The ComponentObjectModel and MTS are a far more simpler and elegant solution.
That's a matter of subjective opinion. I find MTS and COM to be a horrible morass of hacks turned into something barely understandable. I find recent moves towards .NET to recognize that COM on the server isn't going to take over the world because no one wanted to COM with C++... C# on the other hand...
Some of the more complex parts of EJB, like the division into several types of beans was something that really opened my eyes on how to use MTS. It seems to me like MTS/COM+ is just as complicated as EJB, but it hides the complication. For example, COM replaces RemoteException
by returning error codes that must be handled explicitly, or (more often) just ignored. There is still the issue of lifetime and uniqueness of COMponents, just like session beans vs entity beans, but again, MTS leaves this for the developer to find out and implement. Q.v. CarHoare
on complicated systems. MTS is just as complicated, it just obfuscates that fact better.
("I just don't wanna have to handle memory any more. My head hurts!")
The j2ee and EJB specs are suffering heavily from PatternOverdose
and this results in AccidentalComplexity
that will hurt many systems and developers committing today to j2ee and EJB hypnotized by marketing hypes.
The alternative being ?...
COMplus, MTS, DotNet
COM+ certainly has it's level of AccidentalComplexity
. MTS is COM+. And DotNet
is beta. They're alternatives, but they've got plenty of their own problems.
Other alternatives: AllaireColdFusion
(using pure objects, no ejb), AtgDynamo
see also PatternAbuse
The way I right now are building web applications are by using languages as interfaces. I write my servlet in Java and communicates with the database using SQL (JDBC works fine). From the Internet I receives a bunch of parameter-variable-pairs that I've turned into a sort of language. When building the response page, my servlet generates XML which is processed with an XSL that the design people have written.
Thus I have above used Java, SQL, XML, and XSL, all open standards that cleanly divides the application. What are the benefits of EJB/JSP over this? I've tried understanding J2EE, but maybe I'm to much a language person...
That's OK - a lot of people have problems seeing the value through the hype. Here's at least a partial answer to your questions:
(1) JSP offers a better separation of view (HTML) from controller (Servlets and Beans) than just using Servlets to output HTML. Of course, JSP is not unique in this way - this same idea (code template tags) is the heart of ASP, AllaireColdFusion
, and a number of other technologies as well. As to why it's better than XSL - well, I'm not sure it's better, it's just an alternate way of doing the separation between controller and view.
(2) EJB offers two things (in my mind) that none of the technologies you've mentioned offers; (a) Unified transactions across multiple data sources (Oracle, Sybase, DB2, MQSeries, etc...) and (b) Scaleable object distribution. Sometimes these are very useful things to have. For instance, if I want to build an N-tier system that might have many different client types (Application, Applet, Web, WAP) then having a single point of contact for my domain logic (object distribution) is a good thing. Of course, again EJB is not unique in this space; COM/.NET and CORBA also offer these, to greater or lesser extents. However, it's the best way in Java
to get these benefits.
Regarding MVC separation in HTML-based Web apps, I would argue that JSP (as well as ASP, PHP, ColdFusion
, etc.) lends itself towards greater muddling of view and controller (and often model) given the breadth of the API and how most people utilize that API. Although such separation can be done if your team is disciplined, most real-world JSP apps I have seen tend to have a heavy mix of business logic (and often direct db reads/writes) in what was planned to be used for presentation only. The older and bigger the JSP app is, the more muddled it seems to be (creeping towards Big Ball Of Mud). A cleaner approach to such separation is to use one of the many template engines, such as Velocity, WebMacro
, Freemarker, etc., for the presentation layer of your Web app. These templating systems have very narrow API's geared specifically towards presentation, and thus are better able to keep the app's core rules (and data model manipulation) out of the HTML templates. -- Jeff Lewis
Look at this excellent "EJB from a critical perspective" by Philippe Mougin from TechMetrix?
and the following discussion at http://www.techmetrix.com/trendmarkers/tmk1299/tmk1299-2.php3
"What's wrong with the EJB 2 Specification" by Tyler Jewell from BEA at http://www.onjava.com/pub/a/onjava/2001/02/28/ejb.html
People on TheServerSide
are discussing it at http://theserverside.com/home/thread.jsp?thread_id=4658
Note that this is outdated now that the EJB 2.0 final spec 2 has been released.
JDO seems to be better proposition for object persistence than EJB. there is a "Java Data object vs EJB" discussion at http://theserverside.com/discussion/thread.jsp?thread_id=771
Sorry if this offends, but ADO.NET is looking interesting for persistence. Not burdened by the overspecification problem that affects with EJB EntityBean
s. Includes support for hierarchies, relations, offline (disconnected) manipulation. Developers define Select, Insert, Update, Delete methods on a ADO.NET DataSet
. (Sounds like EJB?) Has anyone else taken a look?
This paper contains a critical discussion about EJB in the context of web services and business objects: http://www.orchestranetworks.com/us/solutions/0105_whitepaper.cfm
Let me assume that people here already know the essentials of EJB and the arguments against it that it isn't OO. I have found EJB makes sense when providing coarse-grained services (Session) and coarse-grained objects with many relationships (Entity). I don't care that the decomposition isn't pure OO - no silver bullets, remember? The fact is that service layers make sense when doing a distributed application. You can't pretend that network latency and load aren't there when you make your model unless you don't mind your application performing abysmally. When developers use these types of methodologies in local apps (as I do) we do it to manage complexity, knowing that there is a run-time cost, but believing that it is minimal compared to the savings in maintainability, extensibility, and so forth. But our network infrastructure is not now in such a state that we can ignore its effects. We are in the AppleII generation of network apps, and it is appropriate that we are still having to take explicit recognition of our infrastrucure in our application design.
As for the whole "EJB is another form of vendor lock-in", well, I have ported j2ee apps from one server to another. Not without some pain, but in a reasonable amount of time. I even once had to port an app that had been written against a home-grown CORBA implementation of most of the EJB spec to EJB, and that was somewhat worse. But it was possible. Tell me where I am going to get almost all or even most of the MTS spec implemented on another platform please. When a client has huge new demands and wants to move to Unix for stability etc., how am I going to port this MTS app without starting over? Now the case for Mono is another thing altogether. Java is by no means without faults, and I hope that six years of market reality and design evolution have produced *something* of an improvement. When these new technologies are mature enough for actual use, say 1 year plus past beta, then maybe it will be worth taking a serious look at them. But anyone who is talking about moving to .NET based on the output we have so far is smoking their stash. You can tell the pioneers by the arrows in their backs.
Here's the problem I have with EJB: It tries to do too many things and fails at them all. First, we have stateful session beans: Nice idea, but in practice, almost nobody can use them. Why? Too slow, and the notion of state is too limited. Ok, how about stateless session beans: Nice idea. But wait, can't I do the exact same thing with RMI if I wanted? The answer is yes. And, without all of the BS overhead that EJB imposes. In fact, RMI can be used to provide both stateful and stateless type objects with minimal overhead. And guess what? Almost all of the application servers on the market scale RMI just as well. In fact, this is a given, because EJBs simply sit atop of RMI.
RMI isn't perfect, but its not bad. It gives a nice, simple, remote interface for Java. I like it. I've used it a lot. What about transactions? Sorry, I do this myself. I very rarely have to synchronize transactions across multiple data sources. And that's a kicker too, ain't it? That's EJB's entire
notion of transaction: Databases. Honestly now: How many of you are doing cross database commits? Probably not many. Thus, almost all databases on the market have the built-in notion of transaction that is needed. (This means that JDBC gives you all of the needed transactionability you'd ever need). If you really need complex transaction management, then use JTA. It's much nicer.
With Java 1.3 and up's ability to Proxy calls I can very easily create my own transaction framework in about an hour that handles tracking changes to any object that's tagged with a designated interface and I have significantly more control.
I hear these things all the time:
- Threading is complicated: Yeah, but it's something that complex systems may use. If you don't understand threading and can't create your own thread pool in about an hour, you should get another job.
- Database connection pooling: Gosh darn I hear this a lot. Guess what, since Java 1.3 I can create a completely transparent database connection pool in about 30 minutes. Easy as cake. Want to know another little secret? My connection pools are orders of magnitude faster than the best application servers. Especially WebLogic
, which is a total piece of crap.
Let's face facts: If a company is going to hire a bunch of CodeMonkeys
then J2EE and EJB seem like a great idea. However, if you've got any talent at all, most of J2EE will make your skin crawl. Stay away if you can. -- JeffPanici
- Programming skill is maybe the most scarce resource in the IT world. If J2EE (incl EJB) actually makes things simpler and easier, it is probably a good idea. But is it really simpler and easier? -- DinoChiesa
What about transactions? Sorry, I do this myself. I very rarely have to synchronize transactions across multiple data sources. And that's a kicker too, ain't it? That's EJB's
entire notion of transaction: Databases.
I've got to take issue with one of Jeff's points. EJB transactions aren't just about databases. They haven't been for a while now. For instance, with WebSphere
I can now have a single transaction cross DB2 or nearly any other popular relational database, MQ Series, CICS and about a half-dozen other EIS systems that have JCA connectors. That
is powerful. Sure, you don't need it a lot, but when you do, it's really
The claim was and remains incorrect. You can do distributed transactions without having to program to the EJB model. The JTS API for distributed transactions is available through independent implementations related to JMS, JDBC, etc. -- CostinCozianu
. Earlier this year, I queried and got response from Kyle (who authors books on WebSphere
and unfortunately is no longer active). He said at the time EJB was the "only way". Now he could have meant "only sensible way" and CC claimed that he is technically incorrect. -- dl
Well spoken, Jeff. There is one element I perceive to be a major part of EJBs that you did not address, however. What about scalability, especially clustering. Would you rather want to do clustering on your own, or would you use WebLogic
if you really needed this?
For another write-up of the same views, see Tim Hyde's post on firstname.lastname@example.org: http://www.mail-archive.com/general%40jakarta.apache.org/msg03376.html
Kyle, I grant your point that if
you need cross data-source (or external system in the case of CICS, etc.) transaction management, EJB gives you a head start. However, I would still have to evaluate EJB as a solution in such a hypothetical situation. Also, not knocking WebSphere
, but implementing a session bean that wraps a CICS transaction in WebLogic
, JBoss, or other application server isn't quite as easy. So, some of your point varies on which application server you happen to use, not what EJB provides out the box, per se. My point here is: How much plumbing does IBM provide on top of
EJB to give you those features? (In fact, doesn't WebSphere
essentially rely on CICS and simply provide EJB compliant interfaces to the user?)
As to the scaling issue, I'd simply say that - if you're using EJB for what I've seen 100% of projects try to use it for - it's overkill and too costly. I'll qualify that some more: Almost every project I've seen, and that's a fair number, that think
they should be using EJB are building CRUD systems for something. That's it. These are replacements for CICS/COBOL systems written on the mainframe (3270) or RPG programs written on the AS/400 (5250). I can scale web applications like this with IP load-balancing, Apache, Tomcat, and JBoss' RMI container. I have one RMI object that implements a drop-in replacement for HttpSession
for centralized state management (if session management must be fail-safe, I will back it with some kind of persistent store, like a database or serialized file, etc. This doesn't happen very often either).
I'd like to point out that I'm not against "application servers", per se. I think having a centralized place for certain kinds of functionality makes a lot of sense. What I am most strongly against is trying to create marketing cruft on top a perfectly good remote standard for Java: RMI. Jini is really what Sun should be pushing, not EJB. But Jini is something that engineers see and say, "Wow, that's really awesome. It solves all of these problems so elegantly!" And managers say, "Gosh, I'm going to need real
engineers to use this Jini thing. They'll actually have to plan the system out and not use code generators...I think I'll take a look at this EJB thing."
Finally, I'd like to say that I really believe that all of this is meaningless anyhow. I've been building several Smalltalk applications over the past few months using GemStone
and I can say: J2EE is like Fred Flinstone's foot-mobile. GemStone
works equally well for Java, as does Poet and a host of other - dare I say it - OODBMS products. I say this because, this is what object developers want. We want our objects to live
on the network and be portable. Scalability here is simple and elegant. J2EE, if it is to survive and truly simplify our development lives (and our client's bottomlines, because this is where it really matters), will have to grow up to this kind of a solution.
EJB is a phase, and the market will outgrow it. We can come back here in two years and see if I'm right. -- JeffPanici
After writing a book on EJB and studying its evolution, I think the market (and Sun for that matter) has lost sight of the original goal: reusable components. The whole hype around server-side business components built around a framework
or a language
seems to have dwindled. The core concept of re-using and composing components out of other components hasn't died however, it's just in the form of WebServices
talking XML to one another, keeping the underlying component as simple as possible.
So assuming that EJB has failed in its mission of providing reusable components to the masses, what does it give us that helps us?
- configurable transactional resource managers: data sources, jms sources, connectors, etc. HTTP urls, and key/value environment settings that can be set by a sys admin
- transparent 2PC when talking to any transactional resource manager. This effectively works wherever you have an RM that talks the CORBA OTS. A big plus for complex systems.
- a single physical deployable construct (the EAR, WAR, or EJB-JAR) that can be dropped in all J2EE compliant servers with no code changes and only sys admin changes. This is in effect the only "reuse" we get from EJB - the ease of physical placement & configuration of a complex application.
- a common programming model that automates: multi-threading, transactions, security checks, virtual memory
So what's the prob?
- External XML sucks as a means to annotate code. Telling which methods require transactions, which need certain security checks, etc., is effectively AspectOrientedProgramming, and .NET's attribute approach or AspectJ's approach keeps those settings NEAR the code as opposed to conceptually and cognitively separate. Declarative security & transactions aren't a bad idea, but both Microsoft with MTS and Sun with EJB wanted them to be sysadmin settings instead of programmer settings. We now know this to be a pipe dream... transaction demarcation and security checks 90% of the time require programmatic knowledge.
- Too much code generation. Related to the above item of how EJB's are configured... There should be a runtime means of handling this stuff, but I'm noticing it's a Java philosophy to avoid reflection & dynamic proxies as much as possible even when they provide the path of least resistance. At least we could emit byte-code dynamically or something, so I the programmer don't have to run a post-processor tool from hell.
- All those damn interfaces. EJBObject vs EJBLocalObject, etc. Great in concept, but now we have 3 to 5 source code constructs for a single EJB. Gak. Again, this goes to Java's philosophy of type safety, but oh how I would love it if I could just attribute my methods with (you're on the local side, you're on the remote side.). This is a nit pick, it's not to big a deal in practice.
- The callbacks aren't used. Does anyone ever use ejbActivate/ejbPassivate?(Try putting a log statement on your callbacks and you'll find how often they're called in a highloaded app -- RafaelAlvarez) What sane designer would keep an open cursor or network connection or ANY scarce resource in between transactions? Does anyone ever use ejbPostCreate? Only for auto-key-generation, I suppose, but not all containers work properly here. Has anyone actually looked at how much pain and suffering is involved with a scalable implementation of ejbLoad/ejbStore in bean managed persistence assuming a reasonably complex object model? (Of course, the EJB spec states that most BMP developers aren't expected to hand write this code... because tool vendors will make up for it. Sorry, this is just a pass-the-buck scenario).
- Naive concurrency, thread models, and locking. Stateless session beans are no-brainers, but YMMV with stateful session beans - they can be great session stores but you better make sure your EJB server can manage its working set efficiently. Gemstone/J was good at this. In terms of locking, Entity beans have traditionally been useless when cached since they're fully synchronized objects, there's no standard fine-grained locking mechanism. EJB 2 allows for fine grained EJBs which sorta fixes this.
Some comments directed to Jeff:
- Jini isn't the ultimate model and neither is RMI, primarily because it's Java to Java only unless you're speaking RMI/IIOP, and even that is painful from the non-Java side. Secondarily, RMI/Jini is a synchronous model. JMS really is a huge deal to EJB's target audience, for good reason.
- If J2EE is to survive, it must grow up to become part of a solution (OODBMS) that virtually no one uses, and almost all vendors are puny? Sorry, this is some odd logic in terms of marketplace adoption. I'm an old Gemstone guy myself, I love the technology and know that you can do tremendous things with it, but I don't think this is the direction the world is ready for yet. Maybe in another 5 years.
Gemstone is too raw for most developers (I had to build my own indices in GS/J, I don't think most would enjoy that), plus its support for ad hoc queries / reporting is definitely lacking (in the tools support especially). GS/S is tremendously better than GS/J or the new GS/Facets, but I'm not counting on a Smalltalk revolution to occur... (would be nice tho).
After using Oracle for a while, I've come to some conclusions: Oracle is excellent. It's fast, it's scalable, and it does a lot for DBAs. It's just a pain to integrate with objects ... O/R mapping tools have been trying with limited success... but it can work, there just needs to be more progress in this area. ADO.NET in particular has some interesting ideas for creating an object graph out of SQL calls. After working with a TOPLink+Oracle project, it's hard to go back to hand-crafting SQL calls.
Your comments on the reusable component aspect is interesting. I've discussed this with many colleagues, and we've all come to the same conclusion: it's a pipe-dream. Here's why: Do you really think that - say - Zurich, IBM, and BankOne? would all use the exact same "Customer" component? If they did, what would that say about their
intellectual property and how its controlled? You see, each business
wants to think their way of handling customers, orders, deliveries, accounts, etc. is different. This is something they use to differentiate themselves in the marketplace, no matter how crazy it may sound to the software engineers of the world. In my opinion the entire component model push came from VisualBasic, which proved that there is a market for certain kinds of developer-centric component reuse. However, the rub here is that the domains one tends to find "componentized" are things like widgets, credit-card processing/bank transfer, etc. Again, companies want to believe that they are
unique with respect to their core domain objects, which negates the possibility of a reusable domain component market.
We're on the same page. Keep in mind that I don't claim RMI or Jini to be
perfect solutions; only better for the types of application that I see people building. And that's part of my gripe with EJB - indeed, the J2EE picture in general - it presupposes that one will use all of the specified technologies; though Servlets with a templating engine (WebMacro), JDBC, and a dabble of RMI, if necessary, is sufficient for most CRUD type web applications. Again, I'm not against frameworks that work and make life easier; something I find EJB failing at. Your point on AspectOrientedProgramming is well taken and I whole heartedly agree. But, again, this is something the market will likely see as
Keep in mind, I don't assume that the market will accept any
current OODBMS system. What I am proposing is that the technological concepts in use here will migrate to some market accepted platform - JDO perhaps (but probably not). Also, I've never used GS/J, but I think GS/S is very flexible and high-level. Sure, its not perfect; nothing ever is. However, I can build applications very fast using Smalltalk and GS/S. As a side note, Poet is a very powerful and high-level Java/C++ OODBMS product. It does support high-level indexes and full SQL and OQL. It's a fantastic product and I highly recommend it.
This brings me to my last point: Why, as
professionals, must we always kowtow to the whims of those who don't know any better? If Smalltalk, Gemstone, Poet, etc. is the answer, we need to
show the market this. Instead, we buckle under and use whatever fad tool comes along. I admit, until very recently, I succumbed to this pressure as well, but I've really been studying my marketing as of late and I feel strongly that there is more than
hope for Smalltalk and products like GemStone. Just like ExtremeProgramming promises a way to better software development, I think we, as the people developing these systems, need to show our preferences. I'm going to better articulate myself on TimeToChange, drop by and see if we can start a revolution. -- JeffPanici
I agree about the reusable business components being a pipe dream. I've always sort of felt this way, though I think intra-organizational reuse was a good possibility, with EJB and J2EE, and probably someone has delivered on this in some small form from time to time.
Regarding J2EE: I don't agree that it presupposes the use of *all* its technologies. The J2EE blueprints talk about lots of different combinations. J2EE doesn't make my skin crawl, - in fact I'm very happy it exists at the very least to provide the standard deployment formats (EAR, WAR). Servlets+JSP with the JakartaStruts
framework is an excellent choice for developing everything from simple CRUD to complex web system. I've used it with great success, and it's *fun*. The general movement towards JSP tag libraries is a positive step, one mirrored by ASP.NET - both standards seem to be approaching the level of innovation that WebObjects
was at back in 1998. <grin>
- Sun requires that any licensee of the J2EE brand provide implementations of everything in the J2EE spec. Even a vendor who only wants to make money selling a JMS provider, needs to also deliver the rest of J2EE.
How true is this? TIBCO sells a JMS implementation, without providing anything else from the J2EE platform. I don't know if it is J2EE certified, but... Anyway, as an ex C developer, C++ developer, CORBA developer, i jumped in the Java space and find J2EE too much heavyweight and verbose. I worked with WebLogic
/Oracle, and the performance were so bad (Sun Enterprise E10000 servers) that we ended up by developing our own database service classes (sort of) with load-balanced RMI support instead of using BMP or even CMP. The reason ? There is more than one way to update/delete/insert into a database, and we got much better performance on relying on database features, rather than making a generic all-purpose class. And i do not see how anything generic can be faster. Also, much more stuff should be declarative within the code or deployment, with no knowledge about the resulting generated code (that should be completely hidden within the application server itself). I am actually trying the .NET stuff which at first sight looks much more clear to me. And i begin to believe that the competition between the J2EE vendors will slow Java progress so much that Microsoft will provide better application server implementation than anyone else (and believe me, i do have no shares in Microsoft corp.). As far as they (or any third-party company) port their CLR to other OS than Windows, they will get more marketshare in the mid-frame segment.
As for "why can't we change", well, I'll leave that to for TimeToChange
, but I think "we" are in the minority. Most people don't agree with our opinions of what is 'better'. I get heckled as alterno-man at work for the simple fact that I even know Smalltalk and Objective-C.
More cynically, I would also suggest that most managers don't want to hire programmers that can write their own thread or db connection pools, they want to hire cheaper programmers because people that can write those things are too expensive. Hence, the paradox of tremendous business interest vs engineering cynicism towards EJB. -- StuCharlton
If EJB strikes you as over-engineered, difficult to design & code for and not very much like Java itself, take a look at EnterpriseObjectBroker
. -- PaulHammant
Just reading all this should tell you what's wrong with EJB. Simplify your lives and use .NET.
This is a false dichotomy.
Jeff - I agree with your critique, if not the details of your solution.
Until recently, I had a strong feeling that EJB existed for purely political reasons - i.e., to give companies like IBM a profitable stake in Java.
What happened recently is that, working on an opensource project with EJB programmers, I got a strong whiff of deja-smell. I was flashing back to years of dealing with mainframers.
EJB is a monolithic welfare state - oh yeah, it'll do a zillion things for you. But the overhead is outrageous.
And the creativity disappears: the beautiful thing about Java (and other OO languages) was that, even without going to eXtremes, the roles of designer and programmer became inseparable. There's no such thing as an "OOP coder" who can ignore the architectural implications. But the division of "roles" in EJB recreates that classic mainframe caste system.
What I loved about the original JavaBeans
was the ideas of mobility - objects could migrate to the most efficient location in a distributed system - and unbundled services orthogonal to each other. With EJB, that's all gone.
And the attitude becomes - if you don't use EJB, you can't have database integrity, or transactions, or threading, or you'll have to reinvent the wheel, etc. Anybody out there who's old enough to remember what it was like to propose distributed computing in a corporation with a mainframe priesthood should be familiar with this mindset. -- TomRossen
Okay - I'm not the first one to see the connection to IBM and mainframes. In EnterpriseJavaBeans
EJBs look like a Microsoft style territory grab by Sun. It will sell big boxes like Windows sells fast PCs (which is why Sun and IBM are in bed).
and somebody else said,
All these issues result from the mistake of doing things in the wrong places. They are then partially solved by building very heavyweight physical and logical infrastructure, which sells huge application servers and huge boxes to run them on, i.e. back to the mainframe model of computation.
I think this is regressive.
(EJB's 101 Damnations)
I'm surprised that no-one has mentioned this problem with EJBs: they require so much boilerplate code. This is extremely inelegant, and basically turns my brain to mush just looking at it. Yes, I know it can be generated, but you've still got to live with it. Thank goodness for XDoclet. But the fact that XDoclet had to be written suggests there's something very smelly in the EJB spec.
Java itself is a stoic and painful language IMO. It would be so easy to create a better syntax with more programmer-friendly features that still compiles to the same .class files
(i.e. the language would be functionally equivalent). The "Nice" (experimental) language does this, AFAIK. JDK 1.5 goes about 20% of the required distance to drag Java into the 21st century, and it's sad that we had to wait this long.
But back to EJBs: the Java language should change to better support what they are trying to do. Imagine that: one group of people putting in that bit of extra effort, to make hundreds of thousands of lives easier. EJBs are ugly, and have other problems described above, but they are useful. -- GavinSinclair
EJB development is difficult, without a doubt, but once beans have been developed, bean clients are the beneficiaries of a clean enterprise object API. The trick is - once a design has been created - to build the beans themselves. There is
a lot of boilerplate/plumbing work to do, just to get an EJB "Hello, world." up and running. A lot of complex coding and configuration conventions must be followed, and many kinds of mistakes can't be discovered until deployment time. Deployment itself can be a burdensome extra step in the frequent edit-run development cycle of an agile process.
But EJB is the way it is mostly because of its proposition: ambitious design goals tempered by implementation constraints. A distributed component infrastructure is inherently complex, no matter the component model, if client transparency is to be provided. Building components made even more difficult when constrained to a general-purpose programming language like Java - witness the greater complexity of CORBA development and its IDL abstraction.
But distributed infrastructure need not be complex. See for example: ErlangLanguage, which is amazingly simple. Unfortunately EJB puts together in one basket distribution, transactions, half-baked object persistence, concurrent execution, and the bundling of all these together breaks SeparationOfConcerns.
The real question of EJB should be: is it more complex than necessary
given its proposition? What is there in EJB that is arbitrarily
problematic, and not explainable as deriving from trying to reach its goals while using the Java language?
Something like EjbQueryLanguage. And the whole CMP specification.
It's not enough to say "this looks a lot harder than what I'm used to" without asking "how would I do this more simply?". For those considering its use, the first question should really be "how does the EJB proposition align with my needs?", followed by "do I really need
a 3-tier deployment architecture?".
A 3-tier architecture does not necessarily need EJBs.
If you do choose EJB, you'd be nuts (or shortly driven so) if you choose to build EJBs by hand. As in any situation where you find yourself writing boilerplate, cookie-cutter code, it's time to use a generative tool. For EJB, such a tool would minimally generate, from a simple specification or model, the home and remote interfaces (and their local counterparts if needed), as well as much of the bean class, of the specified EJB components. For anyone who are repulsed by code generation, recall that this is just the time-honored approach of creating a high-level little language when the usual one is insufficiently expressive. Maybe the EJB spec. should define one, but it's already big enough.
Even with an EJB generator, you may still find yourself writing a lot of boilerplate if you mistakenly ignore EJB Entity CMP and go with BMP (or worse) for persistence of non-legacy enterprise data. But direct database programming, repetitive though it may be, is still a habit that many developers seem wedded to, even though very few of them do it well. But I digress...
In some of the above, "EJB" and "J2EE" have been used as if they were synonyms. They are not; EJB's are just one of many technologies that are gathered together under the J2EE umbrella. Not that J2EE is simply a marketing term: there are real architectural principles that underly all the J2EE technologies.
For example, just because you are using J2EE does not at all mean that you are obliged to use Entity EJB's to do all of your database accesses. JDBC is one of the J2EE technologies, and you can certainly call JDBC directly. (At the most recent BEA user conference, there was a good talk about the different ways to access database systems, comparing and contrasting and illuminating the trade-offs.)
Raw EJB technology is indeed hard to use. To make it work you really need appropriate tools. Just for starters, hand-editing an XML EJB Deployment Descriptor (ejb-jar) with a raw text editor is clearly no good. Real J2EE app servers include interactive tools for building these files (such as BEA's "Builder"). Another (better) approach uses code annotations; see http://www.beust.com/cedric/ejbgen
for example. And then there is the more aggressive approach taken by something like BEA's WebLogic
Workshop, which really takes care of all the boilerplate and lets you focus on the substance. (I'm trying hard not to sound partisan here; I just happen to be familiar with the BEA technology and I'm sure there are other good approaches.)
The substance of it is treated in EjbFlaws. It is unlikely that Cedric's doclets or BEA's wizards can get you through EjbTernaryRelationshipExample. The EJB model has flaws by design and will have to be abandoned sooner or later because of competitive pressure from Microsoft and the alternative Java solutions from the open-source community.
Regarding "vendor lockin", it's not a bright-line binary thing, as if either you are or are not "locked" in. It's a matter of degree. Moving code between J2EE app servers isn't free, and it can't be since J2EE intentionally leaves many decisions out of scope. But it's very much easier than moving between Microsoft's technology and anything else.
The Roger Sessions quote above confuses Java language portability (the claim that a program written in "100% Pure Java" should run on any conforming Java VM (of the same version!) with a strawman claim that any EJB can be transparently and effortlessly moved between two different Java app servers. Of course these are entirely different claims. This is really so simple that one wonders whether Sessions really misunderstands it or not.
By the way, if anyone can track down evidence that James Gosling said that Java's portability goals/claims were "goofy", I'd be curious to see it. The hyperlink above doesn't work, and I can find nothing like that on the IBM DeveloperWorks
site. I wonder if this is apocryphal, and if not whether it is out of context, or whether he was calling "goofy" some other claim, or what.
- @DanWeinreb, the interview was from 1999 and it looks like it was zapped from IBM's site, but archive.org still has it: http://web.archive.org/web/20010627001957/http://www-106.ibm.com/developerworks/features/gosling/. -- DinoChiesa, December 2004
- Totally OT, but revisiting my comments from January 2001 about the EJB/J2EE vendors, BlueStone was discontinued by HP. Stu Charlton ("I don't see why [HP's acquisition of Bluestone"] is a bad thing"), there's your answer. Allaire's server-side stuff (jRun from Live Software) has pretty much withered in the hands of Macromedia. Macromedia still makes its money on tools. What ever happened to Gemstone? ATG pulled out of containers. And BEA, of all companies, had an employee purge in summer 2004, and just reported its 13th (count em) straight quarter of flat-to-declining revenues in software licenses. BEA's quarterly software license revenue has not been this low since July 2000. -- DinoChiesa
Whatever happened to GemStone
is still operating, on a substantial revenue stream from its Smalltalk product line, interestingly enough. They sunsetted their GemStone
/J J2EE application server in about 3Q01, if my memory serves me correctly. However they continue to offer the Facets product for Java, which is basically all the OODBMS stuff minus the J2EE app server stuff, as I understand it. You can call their Java libs to persist your objects, and do so in any app server you want, I presume, as long as you can start the app server by invoking the HotSpot
VM distributed with Facets and making the GemStone
classes available to the relevant classloaders. It's not clear to me without further investigation what integration exists between GemStone
transactional resources (e.g. GemStone
sessions) and the app servers' JTS implementations. You can look at their product offerings at http://www.gemstone.com
. -- RandyStafford
ejb is not a good one,instead of this we can use Spring,it's having inbuild ejb..