EJB vs. Web Services

By 01

Sunday, October 05, 2008
Introduction

On numerous occasions, recently, the subject of back end architecture has come up in my day-to-day wanderings.  In particular, the debate of EJBs vs. Web Services.  EJBs are ten years old now.  Web Services came onto the scene earlier this decade.  By historical standards, both are young technologies.  But, EJBs do have a couple of years and legacy versions on Web Services.  No one technology is the end-all-be-all of every situation.  Both technologies have their uses, strengths, and weaknesses.  But, which one should be used?  And, when?

Web Services still have the new-and-cool, buzzword-compliance auroa.  That wore off EJBs a couple of years ago; although, the EJB v3.0 spec's JPA(standardized, Hibernate ORM technology) that replaces Entity Beans, use of Java 1.5 Annotations in place of XML configuration documents, and simplification of the programming paradigm has breathed new life into the technology.  I've read articles and books that suggest these much-needed features came too-little, too-late--it has been suggested that the EJB culture is dying.  Although, I would suggest that it is more accurately stated that the Entity-Bean culture is dying.  Albeit, the EJB 2.x deployment descriptors are not a major selling point of the technology these days.

Likewise, this article focuses on JAX-RPC Web Services that are implemented as SOAP over HTTP calls.  Although, some of the discussion is relevant outside of this context.  I believe this is the most common implementation of Web Services at this time.  Although, there are plenty of alternatives.  You could use SOAP over JMS.  Or, you could be using REST Web Services(see [15], [17], & [18] for more information).  You could also be using JAX-WS to be making Web Service calls.  I'm not sure how much that changes the arguments I make here--that is outside the scope of this conversation.

EJBs and Web Services are both client-server technologies.  Throughout this article, I will use "the server-side" to represent an an abstract, business-logic or data-access tier that hosts EJBs or Web Services.  Likewise, I will use "the client-side" to refer to any tier that hosts Web Services clients or EJB clients.  A client in this case is anything that calls business or data access logic on the server-side.

Decision Points

So, which technology should be used?  And, when?  Before answering that question, let us review the decision points.  Whenever I discuss this subject, I find myself bringing up the same points:

This is by no means an exhaustive list.  But, it is a list of my favorite points.

I must stress that I do not consider "because it is cool" as a reason to use any new technology.  I don't believe a technology should be pursued for its own sake--the technology must solve a problem that either doesn't currently have a solution or that has a lesser solution.  Ordinarily, the business world is solving the same problem over-and-over again.  Every now and then, a better solution comes along.  Civilization marches bravely forward--in some cultures this is called progress.  I have my doubts, but that is well outside the scope of this discussion.

Is Everything Java Based?

If both the client and server are Java-based, the decision to use EJBs should be straightforward.  Why take the overhead of a Web Service, if you don't need too?  Again, "because it is cool" is not a defensible position for any technology.

If the client (or server for that matter) are not written in Java, it will be difficult to use EJBs.  In this case, a Web Service is the best option in my opinion.  Of course, it is possible to convert the EJB interfaces to IDL using java2idl and from there generate CORBA bindings for whatever language your client is implemented in.  But, this will become very complex, quickly; depending on the language, there could be additional required steps.

Please note, this is an article (and a website) about Java & J2EE Middleware;  so, we tend to focus on that segment of the industry.

Is a J2EE Container present on the Server Tier?

Likewise, if you don't have a J2EE container, it will be difficult to use EJBs.  Although, JBoss does offer a fully-functional, Open Source J2EE container.  But, that may not be an option in some shops.  In these cases, Web Services would be the only viable option.

Again, we are focus on Java and J2EE Middleware here.  So, will remain focused on those topics.

Internal Clients vs. External Clients:

Inside-the-firewall or outside-the-firewall?  In other words, is the client on your corporate network?  Or, is it on the Internet?  Put another way, is the architecture of the client and server something that you control?  Are they the same platforms?  Or, is one .Net and the other J2EE? 

If both the client and server tiers exist within your sphere of influence (a place that you control), then using EJB is probably a viable option.  In this case, Web Services are probably an over kill.  So far, in my experience, Web Services are a solution for use with remote clients that exist outside your sphere of control.  Web Services are a ubiquitous standard on the Internet for exchanging complex data and calling business and data access logic. 

EJBs in theory could be used over the Internet; however, you would be tying all remote clients (that you don't control over) to Java and J2EE technology--that will probably be too restrictive to some of your clients. 

Likewise, providing redundancy on the EJB server-tier will be tricky in this case.  Using a hardware load balancer with EJB calls (RMI over IIOP) is tricky--probably counter productive, if you could even get it to work.  Although, not required by the spec, most J2EE EJB containers (and associated client implementations) provide basic redundancy within a cluster concept by having client stubs (Home Objects) reference a primary container and a secondary.  If a load balancer is sitting between these its possible the system could become confused.  Likewise, you could be maintaining persistent connections through a network device that is tuned for short-lived connections--this adds overhead to the device and will lead to socket errors in your application.  Furthermore, there is no guarantee that your InitialContext (through the load balancer) and the connection your EJB method calls make will go to the same server--this hurts the primary/secondary server concept most EJB containers implement.  It also introduces the possibility that your EJB call could end up on an EJB server that knows nothing about your EJB or your session with the container(s).  Thus, you are limited to exposing each individual host:port for your ORB Listener to the outside world.

In my experience, using a client-side Service Locator pattern in conjunction with Home Object caching is the most effective solution.  This pattern hides the details of finding the remote server-tier, provides access to the same service on multiple host:port endpoints, caches connections (via Home Objects), and is a standard J2EE approach.  This comment applies to EJB v2.x; however, object caching on the client side would still provide for persistent connections, low-overhead in reusing connections, and a good way to manage the connections to the server tier.   That being the case, a client-side, software-based, load balancing solution is my recommended approach to redundancy for EJBs--hardware load balancers are best avoided in this situation.

Configuring RMI over IIOP for use through a firewall can also be difficult, but not impossible.  Running RMI/IIOP through a firewall has two basic challenges[1]:


So, EJBs weren't really designed to work between a client and server belonging to different groups.  It also looks all clients into Java--this is probably not a viable, real-world constraint.  Conversely, Web Services were designed for exactly this kind of thing.  So, if your business and data-access tier's clients can exist outside your sphere of control, Web Services are probably the best option.

By "sphere of control", I generally refer to remote clients coming into your application from over the Internet.  But, it could also be a leased line.  There are probably many other crazy situations that I haven't considered.  But, the common theme will be no control over the client tier.

Passing Through Firewalls

I brought this topic up in the last section.  But, I explicitly mention it here to contrast SOAP over HTTP and RMI over IIOP.  A SOAP request being made over an HTTP request is running over a stateless protocol.  This means a socket connection is established, a request is made, a response is given, the connection is closed.  It's possible the socket would be kept open (keep-alives) and reused for performance reasons, but each individual request-response is performed in isolation from previous communication between the client and server.  So, Web Services, SOAP over HTTP, are fairly easy to use with a firewall configuration.

In contrast, EJBs, RMI over IIOP, has multiple host:port combinations that the firewall would need to allow: JNDI port, ORB listener port, and ports involved in CSIv2.  Worst, some of these ports are dynamically assigned at run-time.  However, most vendors do provide a mechanism to statically assign these ports.

So, it would be easier to configure a firewall for use with Web Services communication than for EJB communication.  But, it is possible to do the latter--it's just a little more complicated.

Baggage

An EJB client requires generated/compiled stubs to be distributed to all clients.  Web Services do not require such mechanisms; WSDLs can be used to describe the Web Service's format and location.  Although, many Web Services implementations will use a similar client stub under the covers for a performance improvement; this stub would be generated by the development tools based upon the WSDL (IBM RAD does this, for example).

In their purest implementation, Web Services are easier to use and manage from a client standpoint because there are no client stubs used.

Hardware Load Balancers

I previously brought up this topic as well.  Using the same argument outlined in the last section, Web Services are a better fit for load balancers than EJBs.  In fact, I would recommend not attempting to use a load balancer with EJBs.

Serializing Java Objects Versus XML Document Parsing

Data marshalling is an extremely expensive task.  Any type of network-based communication between two systems (especially disparate systems) will involve some type of data marshalling.  This is unavoidable.  In a Web Service call, data marshalling is represented as the construction of an XML request document on the client side, parsing the XML request document on the server-side, constructing an XML response document on the server side, and parsing an XML response document on the client side.  For an EJB call, data marshalling will involve serializing the Java object(s) that are passed to the method call as arguments on the client side, deserializing those Java objects on the server side, serializing a response object on the server side, and deserializing a response object on the client side.

Regardless of the technology, there is much happening.  In generally, (de)serializing Java objects is much more efficient than building and parsing XML documents.  I've seen this not just in EJBs and Web Services, but in custom built systems were Servlets could build dynamic images based upon information passed in via a servlet call that accepted XML documents or serialized Java objects as input parameters.  In generally, the serialized object calls were more efficient.

It would be irresponsible to recommend a technology based upon performance alone.  But, my experience has shown there to be a fair amount of overhead in parsing XML documents (in comparison to serializing Java objects).  But, as we saw in the last section, if the clients will be external, Web Services are the better choice--regardless of any performance hit.

JTA Transaction Manager Versus WS-Transaction

Any non-trivial application will eventually have to account for updating multiple databases or accessing multiple database connections in the same unit of work.  This is where the XA protocol comes into play.  The XA Protocol specification was written by the X/Open group (presently called The Open Group). 

Distributed Transactions is a complex subject.  Attempting to do the topic justice here is well outside the scope of this discussion.  I want to introduce the major concepts that provide for Distributed Transactions in both EJBs and Web Services.  My goal is to introduce enough information to make an informed decision.

The JTS Transaction Manager (or JTA Transaction Manager as I have been referring to it) is a Java implementation of the XA Protocol's Transaction Manager.  The JTS Specification defines the "implementation of a transaction manager that supports the Java Transaction API (JTA) specification (see JSR 907) at the high level and implements the Java mapping of the OMG Object Transaction Service (OTS) specification at the low level"[5].  The OMG "is an international, open membership, not-for-profit computer industry consortium. OMG Task Forces develop enterprise integration standards for a wide range of technologies, and an even wider range of industries."[6]  The Open Management Group defines the specifications underlying CORBA technology.  The definition just given for JTS demonstrates that under the covers, an EJB container is a CORBA ORB.  The JTA Specification defines "standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system: the resource manager, the application server, and the transactional applications."[5]  It handles all the machinery implementing XA two-phase-commit, distributed transaction in a J2EE application.

In an EJB-based application, using container-managed transactions (i.e., declaratively-defined transactions at the bean or method level, which are handled behind the scenes by the EJB container) is probably the most straightforward way of providing XA transactions to an application.

"WS-Transaction defines coordination types, such as Atomic Transaction, which use the WS-Coordination framework to define rules which both the Coordinator and participants must adhere to during their communications."[21]  The WS-Coordination framework "describes an extensible framework for providing protocols that coordinate the actions of distributed applications."[20]  In other words, the WS-Coordination framework defines how Web Services (running in different containers) should coordinate activities (such as transactions).  It provides for the low-level communication facilities that would be needed.  For Web Services running in the same container, if the Web Services are defined as EJBs in a J2EE Container, then the JTA Transaction Manager can be used to coordinate distributed transaction between Web Services within that same container.

WS-Transaction also defines how distributed transactions initiated from within Web Services would interact with the JTA Transaction Manager.  WS-Transaction could also coordinate distributed transactions with .Net and any other transaction service, which support WS-AtomicTransaction.

The WS-Transaction spec sounds promising, but it is complex and young.  I have not seen WS-Transaction being used in a production environment yet.  But, that doesn't mean it won't be a viable offering in the future.

In the meantime, the declarative transaction inside an EJB Container described above are probably the best option in my opinion.

WS-Security Versus J2EE Security & CSIv2

Like Distributed Transactions, Security is a big subject that goes well beyond the scope of this article.  But, again, my goal is to paint a coherent, high-level picture that can be used to make decision regarding which technology to use.

The topic of Security for Web Services is defined by the WS-Security specification.  The WS-Security specification is published by the OASIS standards body--as are all Web Services specifications.  WS-Security provides three high-level concepts for securing Web Services:


These three concepts provide for end-user identity, message signing, and field encryption, respectively.  There are other concepts introduced in the specification, but these are the important ones.  For example, timestamps to prevent replay attacks are also defined.  Of course, this concept suffers from a dependancy on NTP (as do all security timestamps)--that inevitably leads to problems regardless of the technology.  I haven't seen a truly robust NTP setup yet.  But, it may be out there somewhere.

Security Tokens pass the identity of a calling appliation or end-user to the server-tier.  There are a couple of tokens that are defined by the spec; each vendor can also implement their own proprietary security tokens--doing so ties you to a particular vendor's implementation.  The Security Token is injected into the SOAP headers of the message.  Ordinarily, a Security Token would only be a part of an request message.  It doesn't buy much to send a Security Token from a server to the client in a response document.  I like to call Security Tokens WS-Security Identity, but that isn't its real name.

Integrity provides message signing.  This is a glorified, trusted checksum of the XML document.  This provides a mechanism that offers a guarantee that the message that was received is the unaltered message that sent by the sender.

Confidentiality provides field encryption for potentially every field in an XML document.  This allows a Web Service request and response to travel over an unencrypted HTTP connection, but still allow the information to be passed with assurance that no unauthorized parties read the message in transit.

EJB Security is provided by J2EE Security --a part of the J2EE Specification.  There isn't a 1-2 mapping between what WS-Security provides and what J2EE Security provides.  J2EE Security addresses authentication and authorization of Web Resources and EJBs. 

J2EE Security at the Web-tier is beyond the scope of this discussion.  J2EE Security at the EJB-tier protects EJBs by declaring method permissions and mapping Users and Groups to J2EE Security Roles[12].  This provides basic authorization to EJBs.  

To handle security between an EJB client and the EJB container (assuming these are separate containers) it is necessary to provide security token, integrity, and confidentiality just as WS-Security provides.  Common Secure Interoperability version 2 (CSIv2), a CORBA/IIOP-based standard interoperability protocol, addresses this situation by providing authentication, protection of integrity and confidentiality, and principal propagation for invocations on enterprise beans, where the invocations take place over an enterprise's intranet.[12]  The most straight forward way of accomplishing the integrity and confidentiality pieces are to use SSL.  Straight SSL (non MASSL handles the confidentiality part; a trusted client certificate required in a MASSL connection would provide for the integrity piece.  I'm sure there are plenty in the security community who would argue otherwise.  I believe this is how Websphere v6.1 addresses these requirements.

Passing a security token(i.e., user credentials) from a client to a server and having the server tier trust those credentials places the onus of authenticating the user on the client-tier.  This situation is present with EJBs or Web Services; so, this doesn't help us with the EJB or Web Services decision.

In my opinion, J2EE containers have better out-of-the-box support for EJB security--through J2EE Security and CSIv2--than they do for Web Services Security--through WS-Security.  In most containers, enabling a few parameters would allow you to use CSIv2.  In contrast, WS-Security is a complex specification whose implementations are difficult to configure and troubleshoot.  All things being equal, securing EJBs would probably be easier than securing Web Services primarily because currently J2EE containers has better out-of-the-box support for J2EE Security & CSIv2.  However, if security between the client and server tiers is not a concern, then this part probably won't weigh on the decision.

My own experiences with WS-Security would suggest that there is a happy, middle ground that levels the playing field.  If WS-Security Security Tokens are used with Web Services provided over a MASSL transport layer, you have provided a basic level of user identity propagatio, message integrity, and confidentiality.  This approach also entails encrypting every byte of the message at the transport layer instead of encrypting each message field.  Which one is more effecient?  I do not have any concrete data.  But, the latter seems like a lot of work for the container to be doing.  Of course, the SOA crowd is a big fan of their approach.

J2EE Container Features/Support

Anyone who has worked with a J2EE Container (Web or EJB Container) knows there are many configuration options available.  Some are defined within the spec.  Others, are common problems the spec doesn't address to which each vendor gives a unique solution.  Although, most of those solution tend to look very similar.  There is a great deal of cross-pollination between Websphere, WebSEAL, and JBoss, but the details do tend to differ greatly.

These configuration and tuning features allow Middleware Administrators to fine-tune J2EE applications.  They also require mastery of a  significant body of knowledge to be effective.  But, that is the mark of a good Middleware Administrator.

In contrast, Web Services are a feature that was built on top of the Web & EJB containers(in the Java/J2EE universe)--whether through spec-defined mechanisms or proprietary implementations.  As a result, there aren't nearly as many tuning or configuration options for Web Services in Websphere,Weblogic, or JBoss.  This may change in the future; it probably will.  But, in the mean time, a Middleware Administrator doesn't have much direct control over the Web Services subsystem of the J2EE Container.  Although, there is indirect control through what is offered up by the Web and EJB containers.

I don't know that this weighs in favor of EJB or Web Services like the other points do, but it is interesting to consider the maturity of EJB implementations versus Web Services when measured from this standpoint.  Maybe I am incorrect when I suggest this is a Web Services maturity gauge.  Perhaps, that body of tunable parameters will never materialize?  I'd be scared if that were the case.

Architecture

This entire discussion has focused around Web Services or EJBs.

The Web Services specification family doesn't go into much detail about how Web Services should be implemented.  In this discussion we've even been focusing on JAX-RPC Web Services with SOAP over HTTP and EJB v3.0.  The EJB/J2EE spec defines many internal details of an EJB engine (namely CORBA).  Likewise, EJB exists entirely within the Java universe.  Web Services are agnostic to the underlying platform and language.  Furthermore, with Web Services, the specs do not lay out nearly as many details from what I have seen.

As I eluded to in the "J2EE Container Features/Support" section, this creates a situation where, the implementation of a Web Services runtime environment can vary dramatically from one implementation to the next.  This statement doesn't even take into comparison all the alternatives to SOAP over HTTP.  So, an architectural compromise may be to write all business and data access logic using EJB v3.0 (in conjunction with Hibernate or JPA ) and per the J2EE Spec wrap the EJBs as Web Services.  This solves many of the problems, but not all.

For example, this would still leave you with the need for WS-Security (as described earlier) instead of CSIv2 and J2EE Security for client-server communication security.

From a strictly architectural perspective, I think an EJB container provides a more robust environment.  This opinion is an amalgamation of all the previous points that have been made.

Conclusions


Several discussion points have been presented to help determine whether EJBs or Web Services should be used.  The conclusion of each point is summarized below:

Discussion Point
Conclusion
Inside-the-firewall vs. outside-the-firewall
If inside-the-firewall, use EJBs.  If outside-the-firewall, use Web Services.
Is Java available?
If Yes, EJB.  If No, Web Services.
Is a J2EE container available on the server tier?
If Yes, EJB.  If No, Web Services.
Passing through firewalls. Web Services are easier.  EJBs are more difficult.
Baggage(client-side stubs)
Web Services
Use of hardware load balancer technologies Work great with Web Services.  Not recommended with EJBs
Serializing Java objects vs. XML document parsing. EJB
JTA Transaction Manager vs. WS-Transaction EJB
WS-Security vs. J2EE Security & CSIv2 EJB
J2EE Container features/support EJB
Web Services Architecture (EJBs under the covers) Neutral

If your client and server tiers are inside the firewall, Java is being used on both tiers, and a J2EE container is available on the server tier, EJBs are probably the best approach.  If you are outside the firewall, don't have a J2EE container, or there are non-Java clients, Web Services should be used.

There are almost certainly other criteria for making this decision.  What do your developers have experience with, for example?  Every situation is unique.  Every project has its own requirements.  A complete understanding of a project's requirements is the most important piece of making any technology decision.  Hopefully, this article can help in the process of translating project requirements into a technology decision.

References

[1]Firewall Security for Corba and J2EE/EJB with the IIOP Domain Boundary Controller
[2]http://www.opengroup.org/bookstore/catalog/c193.htm
[3]http://www.opengroup.org
[4]http://java.sun.com/javaee/technologies/jts/index.jsp
[5]http://java.sun.com/javaee/technologies/jta/index.jsp
[6]http://www.omg.org
[7]http://www.omg.org/cgi-bin/doc?formal/2003-09-02
[8]http://www.oasis-open.org
[9]http://www.oasis-open.org/specs/index.php#wssv1.1
[10]http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Security.html
[11]http://java.sun.com/j2ee/j2ee-1_4-fr-spec.pdf
[12]http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Security8.html
[13]https://juxtaposition.axley.net/2006/11/on-the-performa-1.html
[14]http://soa.sys-con.com/node/204424
[15]http://en.wikipedia.org/wiki/Representational_State_Transfer
[16]http://www.xfront.com/REST-Web-Services.html
[17]http://www.petefreitag.com/item/431.cfm
[18]http://home.ccil.org/~cowan/restws.pdf
[19]http://www.jboss.org
[20]http://en.wikipedia.org/wiki/WS-Coordination
[21]https://www.ibm.com/developerworks/webservices/library/ws-transjta/
[22]http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ws-tx#technical
[23]http://www.hibernate.org
[24]http://en.wikipedia.org/wiki/Object-relational_mapping
[25]http://java.sun.com/products/jndi/1.2/javadoc/javax/naming/InitialContext.html
[26]http://www.java-tips.org/java-ee-tips/enterprise-java-beans/persisting-a-home-object-reference.html
[27]http://en.wikipedia.org/wiki/Web_service
[28]http://java.sun.com/webservices/jaxrpc/overview.html
[29]http://en.wikipedia.org/wiki/JAX-WS

 

©2008 www.thinkmiddleware.com

All copyrights & trademarks belong to their respective owners.

The comments and opinions herein are that of the author.

Please direct all comments to 01.

While the information presented on this web site is believed to be correct, the author is not responsible for any damage, loss of data, or other issues that may arise from using the information posted here.

Made with CityDesk
Last Modified: Sunday, 09-Nov-2008 10:48:35 MST