9.5 To Use EJB or Not to Use EJB?


Now that we have explored the details of JDO integration with EJB in this chapter, an often-asked question may be on your mind: "Should I use EJB in a given application?" The answer, as happens so often, is "It depends."

Before proceeding, let's quickly recall what has been said in this chapter already. Enterprise JavaBeans come in three flavors: entity, session and message-driven beans. The authors of this book believe that JDO clearly offers a better alternative over EJB entity beans and advocate using JDO as primary persistence API within the service methods of session- and message-driven beans. Alternatively, directly using JDBC or possibly a combination of JDO and JDBC may also be applicable .

However, as we have seen above and as readers familiar with the matter know, EJB-based development even with just two remaining bean types of interest represents a certain inherent complexity. The real question, then, is this: "Should I use EJB session- and message-driven beans at all?"

Session- and message-driven beans are components in the EJB architecture, which essentially provides a distributed component model, plus features such as security, transaction management, and scalability. Another J2EE API provides similar features: the Servlets API. Servlets represent another kind of J2EE component architecture. It is worth comparing the two in more detail with respect to the features of interest to help decide whether EJB is appropriate for a given application:

  • Component distribution: Does your application require fully distributed components that can be invoked from other remote components and dislocated plain old Java objects on other Java virtual machines? Then EJB session beans are probably a good choice. Or does your application mostly use co-located Plain Old Java Objects (POJO) "components" (i.e., well-defined public interfaces with underlying implementation possibly spanning multiple classes that the component consumer should not directly access) with a few coarse-grained services, including human-readable Web pages, offered to the outside world? Then Servlets may be enough. [6]

    [6] A Servlet-only based architecture is still "service-oriented" from an external system's point of view: Servlets offer HTTP-based (only) services, input arguments are the request parameters, and the returned documents contain the service result, either an HTML page if the service-consumer is a human, or as a SOAP-based XML response (or simpler format, e.g., plain text string) if the service-consumer is a machine.

  • Service protocol: If remotely accessible services need to be invoked only via HTTP, then Servlets are sufficient. [7] If RMI and possibly IIOP for CORBA interoperability are a requirement, then EJB session beans are the obvious choice. If cross-firewall support is an issue, Web services often make sense again, though. A similar argument applies if non-Java clients need access to the service, e.g., a .NET application. If performance is a concern, processing time for features such as SOAP marshalling and unmarshalling overhead could be worth a thought. In short, it really depends on the big picture.

    [7] It is worth mentioning briefly that the Servlet API technically provides for non-HTTP Servlets, leaving the door open for support of other request/response style protocols in the future. This option, however, is almost never used in practice, and Servlet support in most application servers today really means HTTP Servlet support only.

  • Security: Security is a broad subject, encompassing authentication, authorization, encryption, and other topics. The relatively simple method-level declarative security model that EJB containers offer requires role-based authorization. Servlets can also be protected with role-based access control in the J2EE standard, albeit at an even cruder class-level only because they do not expose individual business methods by design. However, many real-world applications today require more advanced security authorization anyway. Other security aspects, such as authentication and encryption (SSL, via HTTPS in Web containers), are provided by both Web and EJB containers.

  • Stateful architectures: Both the EJB and Servlet component models offer the possibility for stateful architectures via stateful session beans on one hand and the HTTP session variables on the other hand. However, if you need a stateful distributed component architecture, the EJB model is possibly more appropriate.

  • Message-oriented architectures: If an application is essentially an asynchronous message-processing "sink," then relying on EJB 2.0 message-driven beans probably makes sense. The Servlet component model itself does not offer any comparable message awareness; however, plain vanilla Java classes can act as JMS destinations as well. Further discussion of this topic is outside of the scope of this book.

  • Efficient multi-threading and request dispatching: While an inherent feature of EJB containers, a Web container also provides features such as retrieving a thread from a thread pool, calling the correct method to handle the request, and so on. This is not necessarily an argument in favor of the EJB component model. An in-depth discussion of scalability with clustering follows below.

  • Transaction demarcation : EJB offers declarative transaction demarcation via CMT, for which there is no standard alternative in the Servlet component model. Servlets can, however, use explicit demarcation via JTA, a standard J2EE API that EJB also uses when operating in BMT mode. As we have seen earlier, JDO fully integrates with JTA and offers strong support for ACID transactions on persistent data, even when used outside of EJBs. (In a Web-based architecture, including Web services, transaction demarcation can often be centralized in relatively few classes, e.g., in Servlets, a Servlet filter, MVC-type controller Action classes, or similar piece of code.)

  • Transaction context propagation: If your service is invoked remotely as part of a larger "value chain," i.e., in an Enterprise application integration (EAI) scenario, then EJB definitely makes sense because the transaction context with the currently active transaction can be propagated across service method invocations of yours and other services, and all related work can take place within one transaction. The Servlet API and Web service's standard do not (yet) offer any such possibility. EAI-type applications also frequently interact with existing EJB-based services, i.e., other session beans or possibly directly with entity beans, and using fully EJB here definitely makes sense.

Concluding briefly, the first (distributed components) and the last (transaction context propagation) issues are often the decisive ones in favor of EJB if an application requires such.

For most other systems, most notably the common enterprise information systems (EIS) and productivity applications with mainly a Web-centric presentation tier and straightforward transactional requirements, a Servlet-only based architecture is generally simpler and makes more sense. [8]

[8] The presentation and backend/business logic tiers can and should still be clearly separated in the class design when the business service using JDO is co-located in the same VM as the Servlet tier, instead of in a remote EJB tier. Such an approach is shown, e.g., by the Sun Java Blue Prints Adventure Builder 1.0 (Early Access Release at the time of writing), albeit with direct JDBC instead of JDO, but the principle is the same.

If, while going through the above bullet points, you conclude "mixed" results for your application, a "mixed" approach may well be what you need: EJB session beans for remote invocation via RMI, plus a few thin and simple Servlets for HTTP-based access. In this scenario, the Servlets may use the EJB 2.0 local interfaces to forward requests to co-located session beans, or both session beans and Servlets could possibly access Plain Old Java components.

Last but not least, a point must be made that this discussion centered specifically around the usage of the EJB session and message-driven beans and their APIs, and not J2EE application servers in general. Indeed, the J2EE universe and a compliant application server offers many other APIs such as JMS, Servlets, JSP, JCA, JDBC, JNDI, JavaMail, JTA with a JTS-compliant transaction manager for possibly distributed transactions, JMX, and so on. Modern J2EE application servers often also provide other services such as connection pooling and monitoring, hot deployment, clustering, cluster-related distribution and update features, security and user administration, generic monitoring, and management features. All of these other APIs and features are also available to and integrate with JDO-based enterprise applications on a server that chooses not to use the EJB component model.

9.5.1 Scalable JDO-based applications with clustering

If scalability requirements are the only reason to develop an application based on the EJB component model, then a second look at alternatives is time well spent. Figure 9-4 is an illustration of a typical non-clustered scenario, which will be extended next .

Figure 9-4. Simple system architecture with one server and no clustering.

graphics/09fig04.jpg

Scalability in this context usually refers to clustering mechanisms where requests can be redirected by software (or a hardware load-balancer) to different physical Java virtual machines, often on physically different hardware boxes, depending on load and availability of servers. A clustered-system architecture is a goal generally for one or both of the following reasons:

  • High availability, a way to ensure " fail-over " to a standby server.

  • Load-balancing, distributing incoming requests for improved scalability.

Such features are often provided by J2EE application servers and are thus far unrelated to JDO. Enter JDO into the picture, and with the extensive caching that JDO implementations usually perform, a minor problem for clustering architectures appears: If nodes in a cluster are not aware of each other, and if each keeps an in-memory cache of persistent data, write access to a persistent object on one node quickly renders cached instances on other nodes out of date and thus invalid. Furthermore, concurrent modification of identical instances on different nodes arise as a related issue.

Two basic approaches exist to counter the issue and make clustering possible:

  • Turn off caching altogether, and rely on datastore transactions only, with no JDO optimistic or locally optimized transactions. This resolves the problem, but implies a performance penalty that would largely outweigh the basic advantage that clustering tried to achieve in the first place. This configuration would, in a way, use only the underlying native datastore as cache instead of JDO.

  • Use a JDO implementation that provides a distributed PersistenceManagerFactory -level cache synchronization feature.

Implementations of such cache synchronization features vary widely between JDO implementations, for those that offer such a feature at all, and include anything from simple broadcast UDP messages, to IP multicast-based solution, to a JMS-based one, or an HTTP-based one, possibly using SOAP or even RMI.

This feature is not standardized in the JDO 1.0 specification, but is available from several JDO implementations. This type of feature is generally regarded as an implementation differentiator between vendors , and may not need standardization under the specification. Relevant implementations naturally do not interoperate . Configuration of a particular feature is highly dependent on the respective JDO implementation.

However, such a clustered deployment configuration should be completely transparent to application logic, and using an implementation-specific cache synchronization feature may not be a major portability issue, because changing to another JDO implementation ( ideally ) only changes the runtime deployment configuration, but no code.

In fact, the architecture used here is one of application-level clustering, as opposed to individual object-level clustering: The objects representing business entities, the business logic, caches, and the container are all co-located within one VM. Each node in such a cluster persists data directly to the underlying datastore. The nodes then use some sort of distributed caching coherency strategy akin to classical data replication among themselves . This architecture can perform particularly well for read-often, change-rarely data scenarios.

Note that clustering using this approach can be applied both when using JDO from within EJB and when using JDO directly from, for example, the Web tier. Figure 9-5 visualizes such an architecture.

Figure 9-5. Cluster with two server nodes running JDO implementations with cache synchronization on one database server. Note how the JDO implementations on both servers directly access the datastore.

graphics/09fig05.jpg

9.5.2 Round-tripping approaches

A slightly different approach to the one above is what is often known as "round-tripping" in its various forms. The basic idea is to provide a more or less lightweight client-side JDO PersistenceManager without access to the underlying datastore.

Such a local PM can transparently request copies of objects from a master server, e.g., via a generic service with getAllObjects(Query q, String[] fields) and updateObjects(Object[] changedObjects) sort of methods, but provided by the JDO implementation and transparent to the application.

Issues such as object graph diffing and instance reconciliation, relationship graph management, and instance insertion ordering have to be addressed by such implementations.

In a less transparent and more explicit variation, an EJB session bean could send objects and partial object graphs that are copied to the remote machine, manipulated there, and then sent back for resynchronization with the original persistent objects. Such features are not standardized in the JDO specification, but are available in different shapes in some JDO implementations. Figure 9-6 visualizes such an architecture.

Figure 9-6. Architecture of "Distributed JDO" with a round-tripping approach. Note how clients interact only with a server that accesses the datastore.

graphics/09fig06.jpg

The architecture of such round-tripping approaches (sometimes referred to as "Distributed JDO") is generally more in line with optimistic/long-running transactions. It could typically be well suited for Swing-based fat GUI clients, for example, if security and code distributions implications are not a concern. Such approaches are not service-oriented in the traditional sense. Scalability of architectures based on such features should be evaluated in more detail before embarking fully on them.



Core Java Data Objects
Core Java Data Objects
ISBN: 0131407317
EAN: 2147483647
Year: 2003
Pages: 146

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net