J2EE Design Considerations for WebLogic Server Version 2.0 Prepared from material generated from the Ambassadors of Enterprise Architectures
March, 2001
J2EE Design Considerations for WebLogic Server ___________________________________________________________
Table of Contents 1.0 INTRODUCTION.......................................................................................................7 2.0 J2EE DESIGN CONSIDERATIONS........................................................................8 2.1 SERVLET / JSP..........................................................................................................................................9 2.1.1 Multiple Content Types (HTML/WML/XML/…) ...........................................................................9 2.1.2 HttpSession..................................................................................................................................12 2.1.3 Transactions.................................................................................................................................13 2.1.4 Servlet Chaining..........................................................................................................................13 2.1.5 JSP Tag Library...........................................................................................................................13 2.1.6 JavaBeans....................................................................................................................................13 2.1.7 Session State Management for Rich Client types........................................................................14 2.1.8 Deployment..................................................................................................................................14 2.1.8.1 Web Application & WAR..................................................................................................... ...............14 2.1.8.2 HttpSession........................................................................................................................... ..............15
2.1.9 In-Memory State Replication with a Proxy Server......................................................................15 2.1.10 JDBC Session Persistence.........................................................................................................16 2.1.11 Cookies.......................................................................................................................................16 2.1.12 Different Java Virtual Machines (JVM).....................................................................................16 2.2 EJB.......................................................................................................................................................17 2.2.1 General........................................................................................................................................17 2.2.2 Remote.........................................................................................................................................17 2.2.3 Inheritance...................................................................................................................................17 2.2.4 References....................................................................................................................................18 2.2.5 Life Cycle.....................................................................................................................................18 2.2.6 Transactions.................................................................................................................................19 2.2.7 Persistence...................................................................................................................................20 2.2.8 Resources.....................................................................................................................................21 2.2.9 EJB QL........................................................................................................................................21 2.2.10 Container-Managed Persistence...............................................................................................21 2.2.11 Message-Driven Beans..............................................................................................................22 2.2.12 Session Beans.............................................................................................................................22 2.2.13 Entity Beans...............................................................................................................................25 2.2.14 Client-Server Interface..............................................................................................................29 2.2.14.1 Access to EJB Services............................................................................................... ......................29 2.2.14.2 Granularity of Entity EJB Services.................................................................................................... 29
2.2.15 Modeling Relationships.............................................................................................................30 2.2.15.1 Types of Relationships................................................................................................... ...................31 2.2.15.2 Modeling Relationships with EJBs................................................................................................. ...32
2.2.16 Inter-Bean Communication........................................................................................................32 2.2.16.1 Entity to Entity........................................................................................................................ ..........32 2.2.16.2 Session to Session.............................................................................................................. ...............32 2.2.16.3 Entity to Session............................................................................................................................... .33 2.2.16.4 Session to Entity............................................................................................................................... .33
2.2.17 Deployment................................................................................................................................33 2.2.17.1 Overview........................................................................................................................................ ...33 2.2.17.2 Performance......................................................................................................................... .............33 2.2.17.3 Availability............................................................................................................................... .........34
2.3 JMS......................................................................................................................................................36 2.3.1 Transactions.................................................................................................................................36 2.3.1.1 Transacted JMS sessions ..................................................................................................... ...............36 2.3.1.2 JTS UserTransactions ................................................................................................................... ......36
Page 2
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.3.1.3 JTA Transactions Between WLS JMS and MQSeries JMS - A First Look..................... .....................36 2.3.1.3.1 Using JTA and the XAResource Interface.......................................................................... .........36
2.3.2 Security........................................................................................................................................37 2.3.3 Deployment..................................................................................................................................37 2.3.4 Performance................................................................................................................................38 2.3.4.1 Concurrency................................................................................................................................. .......38 2.3.4.2 Session Pool.............................................................................................................................. ..........38
2.3.5 Issues............................................................................................................................................39 2.4 JNDI.....................................................................................................................................................40 2.4.1 How do you get an InitialContext................................................................................................40 2.4.2 Delegated Name Space................................................................................................................40 2.5 JTA / JTS..............................................................................................................................................41 2.5.1 Overview......................................................................................................................................41 2.5.2 Working with Oracle in Transactions..........................................................................................45 2.5.2.1 Lock Duration....................................................................................................................... ..............45 2.5.2.2 Row-Level Locks....................................................................................................................... .........45 2.5.2.3 Read Operations (SELECT)...................................................................................................... ..........45 2.5.2.4 Data Manipulation Operations ( UPDATE, INSERT, DELETE)............................................. ............45 2.5.2.5 Summary...................................................................................................................................... .......46 2.5.2.6 Oracle’s Transaction Isolation Levels.............................................................................................. ....46 2.5.2.6.1 Read-Committed............................................................................................................... ..........46 2.5.2.7 Serializable........................................................................................................................................ ..47 2.5.2.8 Comparison................................................................................................................................ .........47
2.5.3 EJB Transactions Management...................................................................................................48 2.5.3.1 General approach............................................................................................................. ...................48 2.5.3.2 Transaction Control..................................................................................................................... ........48 2.5.3.3 Number of involved beans............................................................................................. .....................48 2.5.3.4 Duration................................................................................................................................ ..............49 2.5.3.5 Should an EJB Service be Transactional?.......................................................................................... ..49 2.5.3.6 Atomicity Requirements.................................................................................................................. ....49 2.5.3.7 Isolation Requirements..................................................................................................................... ...49 2.5.3.8 Transactional Isolation for EJB Services................................................................................. ............50
2.5.4 Default Transactions Setting........................................................................................................50 2.5.4.1 Retrieve Operations.......................................................................................................................... ...50 2.5.4.2 Fine grained updates..................................................................................................... ......................51 2.5.4.3 Batch updates........................................................................................................................... ...........51 2.5.4.4 Summary...................................................................................................................................... .......51
2.5.5 Deadlocks....................................................................................................................................51 2.6 SECURITY................................................................................................................................................53 2.6.1 Overview......................................................................................................................................53 2.6.2 Authentication..............................................................................................................................54 2.6.2.1 WebLogic Realms............................................................................................................... ................54 2.6.2.2 Context Propagation...................................................................................................................... ......54 2.6.2.3 Single Sign-on................................................................................................................................. ....54
2.6.3 Authorization...............................................................................................................................55 2.6.4 Encryption....................................................................................................................................55 2.6.4.1 40 and 128 bit encryption............................................................................................................. .......55
2.6.5 JAAS.............................................................................................................................................55 2.6.6 Balancing Security & Performance.............................................................................................55 2.7 JDBC....................................................................................................................................................56 2.7.1 Overview......................................................................................................................................56 2.7.2 DataSource..................................................................................................................................56 2.7.3 Connection Pooling.....................................................................................................................56 2.7.3.1 Connection Pooling Design Recommendations............................................................................... ....58
2.7.4 BLOB / CLOB..............................................................................................................................58 2.7.5 Batch updates...............................................................................................................................59 2.7.6 Scrollable ResultSets ...................................................................................................................59
Page 3
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.7.7 RowSet.........................................................................................................................................59 2.7.8 XA Transactions...........................................................................................................................59 2.7.9 Transactions.................................................................................................................................60 2.7.10 Other JDBC Design Recommendations.....................................................................................60 2.8 JAVA MAIL API - ASYNCHRONOUS PROCESSING AND RESULTS NOTIFICATION...................................................62 2.8.1 JavaMail API: The "Aretha Franklin" of Asynchronous Messaging...........................................62 2.8.1.1 R-E-S-P-E-C-T (circa 1967)............................................................................................................... .62 2.8.1.2 Rock Steady (circa 1969)..................................................................................................... ...............63 2.8.1.3 Freeway of Love (circa 1986).......................................................................................... ...................64 2.8.1.4 Fade to Black.................................................................................................................... ..................67
2.9 PERIPHERAL TOPICS..................................................................................................................................69 2.9.1 Smart Proxy.................................................................................................................................69 2.9.2 Firewall / DMZ............................................................................................................................70 2.9.2.1 HTTP Tunneling................................................................................................................................. .71
2.9.3 LAN / WAN Considerations.........................................................................................................72 2.9.4 Execute Thread Count.................................................................................................................72 2.9.5 Data Caching...............................................................................................................................74 2.9.5.1 Cache Types........................................................................................................................... .............74 2.9.5.1.1 Client-Specific Memory......................................................................................................... .....74 2.9.5.1.2 Server-Side Cache.................................................................................................................. .....74 2.9.5.2 Caching Principals.......................................................................................................... ....................75 2.9.5.3 Caching Criteria..................................................................................................................... .............75 2.9.5.4 Caching Limitations................................................................................................................. ...........76 2.9.5.5 Cached attributes........................................................................................................................... ......78 2.9.5.6 Preferred Caching Approaches................................................................................................ ............78
3.0 APPENDIX A – USING JMS WITH MQ SERIES - SAMPLE CODE...............80
Page 4
J2EE Design Considerations for WebLogic Server ___________________________________________________________
Credits Many thanks to Mark Ortega who created the original draft of this document. Thanks also to the many Ambassadors of Enterprise Architecture who submitted much of the remaining material.
Technical Field Readiness
Page 5
J2EE Design Considerations for WebLogic Server ___________________________________________________________
Revision History The table below lists the major revisions of this document. Date
Release
Author(s)
Description
11/01/00 11/21/00
Draft Version 1.0
3/29/01
Version 2.0
Mark Ortega Draft of content & format Ambassadors of Enterprise First release Architecture/JP Gordon AEA/JPG Created separate Intro to J2EE for WLS and updated design considerations, adding new material and removing non-J2EE related information.
Page 6
J2EE Design Considerations for WebLogic Server ___________________________________________________________
1.0 Introduction This document is a living reference document for anyone involved in the design and architecture of J2EE-based applications in WebLogic Server (WLS). The original goal for this document was to provide a design guide and best practices for J2EE applications on WLS. At this stage of its evolution, since best practices for WLS 6.0 are still being acquired, this document is not yet a formal design guide, but it does provide a foundation and includes a number of best practices involving the primary J2EE APIs. It also includes a peripheral section that includes some non-J2EE oriented tips and tricks for working with WLS. Thus, this document is not a: •
J2EE Design Guide (yet) – Sun Microsystems has an excellent one already written.
•
WebLogic Development Guide – BEA has an excellent set of documentation already written
•
WebLogic Administration Guide – This is already available as part of the WebLogic documentation
•
Tutorial on Java and J2EE APIs. It is assumed that the reader already has a foundational knowledge on these topics. However the list of J2EE services is discussed in the ~Introduction to J2EE Architecture document.
Section 2presents a number of guidelines and best practices for designing and deploying a J2EE application. . These are the practices that affect performance and availability throughout an application whether just using Servlets, EJB or other APIs. In addition to taking a system level approach, section 2 also discusses some common issues in the physical environment. Please note that this is a living document – the intent is to keep it updated with additional design recommendations and relevant best practices over time. Given the new features emerging from WebLogic 6.0, and as people’s savvy for this release improves, this document will be a useful and necessary mechanism for capturing recommendations and practices relevant to that release and others into the future. In keeping with that spirit, we encourage you (OK, plead with you!) to send your comments, suggestions, corrections and/or other relevant pearls of wisdom to
[email protected] to ensure that your valuable knowledge is available to everyone.
Page 7
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.0 J2EE Design Considerations Before diving into the design considerations, there are a few documents you should know about that are quite relevant to the topic. There are several documents on J2EE design. The most comprehensive is the J2EE Blueprints Final Release. There is a summary of this document, here: J2EE Blueprints Digest. The WebLogic Server 6.0 Documentation Center, especially the Developer Guides are another excellent resource of related information. For information related to WLS 5.1, check out the WebLogic Server 5.1 Documentation Center. Also, the Sun Java Center has recently released a set of J2EE patterns. This collection of J2EE-based solutions to common problems, reflect the collective expertise and experience of Java technology architects in the Sun Java Center over the past three years. The J2EE Patterns presented here extract these "best practices" approaches and let you apply the patterns to your own particular application and accommodate your own needs. The J2EE Patterns express proven techniques clearly and simply, and make it easier for you to reuse successful designs and architectures. Simply put, use the J2EE Patterns so that you design your J2EE system correctly, successfully, and quickly. The remainder of this section provides various descriptions of J2EE-based services and design suggestions for using them. Since much of this material was submitted by a number of individuals, the flow is not optimal, but the advice certainly is.
Page 8
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.1 Servlet / JSP 2.1.1 Multiple Content Types (HTML/WML/XML/…) With WebLogic’s implementation of the Servlet / JSP specification, developers are not limited to HTML content. There is documentation on how to use WML, Using WAP with WebLogic Server, and XML: Programming WebLogic XML. For a FAQ on XML in WLS 6.0, check out http://e-docs.bea.com/wls/docs60//////faq/xml.html#737730 . Of course it is easy to imagine that whenever a new markup language appears, you would be able to use the same methodology to provide content. The challenge is to create one Servlet / JSP which could serve the same content to different devices (browser, phone, PDA, etc.) according to an input parameter. Because WAP decks are very limited (one “page” can contain 1400 compiled bytes or about 2000 bytes of source code), so to generate WAP pages automatically from HTML pages is not easy. It is almost impossible to make general rules about which parts of the HTML content should be omitted and how to translate forms. So the main problem is how to build an architecture that supports multiple devices. There are two approaches: 1. A solution with a Servlet, which forwards a request to different JSP pages with different templates (see figure 2-1). •
A Client requests the Servlet with a parameter in the query string (CONTENT={HTML | WML | XML}).
•
The Servlet calls other objects, invokes EJBs, queries the database, etc. and then sets the data into the Session object
•
The Servlet forwards to the proper Servlet/JSP depending on value of the content parameter.
•
The Servlet/JSP fills the template with data from the Session object and responds to the client.
Page 9
J2EE Design Considerations for WebLogic Server ___________________________________________________________
Page 10
J2EE Design Considerations for WebLogic Server ___________________________________________________________
HTML client
(4) JSP with HTML template (1)
(3)
EJB
Servlet - Session object (2) (3)
(1)
WAP client
DBMS JSP with WML template (4)
HTML specific / WAP specific / Common Figure 2-1 2. A solution with Servlets which generate an XML stream and forward it to another Servlet which parses the stream to the proper type of document (see Figure 2-2) •
A Client requests the Servlet with a parameter in the query string (CONTENT={HTML | WML | XML}).
•
The Servlet calls other objects, invokes EJBs, queries the database, etc. and then generates the XML document.
•
The Servlet forwards to the proper XML parser depending on value of the content parameter.
Page 11
J2EE Design Considerations for WebLogic Server ___________________________________________________________ The parser generates the proper type of document. In production, memory is fast and I/O is slow (relatively). Therefore a goal during development is to maximize requests and invocations in memory and minimize invocations and transactions across the network. With WebLogic Servlet / JSP, there are three primary techniques to do this:
HTML client
(4) Universal HTML parser (1) EJB (3) Servlet –XML doc
(2)
(1) (3)
DBMS
Universal WML parser
WAP client (4)
Figure 2-2 HTML specific / WAP specific / Common
1. minimize the calls to setAttribute() 2. have the Servlets and EJBs in the same JVM (in-process communication). 3. minimize the lifetime of the transaction. In choosing whether to use a servlet or a JSP page, keep in mind that servlets are a programmatic tool best suited for low-level application functions that do not require frequent modifications. JSP pages are a presentation-centric, declarative way to bind dynamic content and logic. 2.1.2 HttpSession It’s a good design practice to store an EJB Primary Key or Handle in the Session object rather than the EJB itself.
Page 12
J2EE Design Considerations for WebLogic Server ___________________________________________________________ In a stateful Servlet, the Session object is very important to optimize for quantity and quality. For instance, it may take several times longer to set 10 variables than 1 object which contains the 10 variables with getAttribute()and setAttribute(). If replication is true, this factor may even be greater. Also a 1 MB object uses more resources than a 1 KB object. 2.1.3 Transactions Whether the Servlet invokes an EJB, sends a JMS message or queries a JDBC database, the action should be short with respect to time. This minimizes contention for an instantiated object and locking for a row in the database. Note that JSP pages and servlets are not designed to be transactional and should usually delegate transactional work to an enterprise bean. However, if transactional work is necessary in a JSP page or servlet, it should be very limited. For those situations where it is necessary, the JSP or servlet can demarcate transactions using the javax.transaction.UserTransaction interface. 2.1.4 Servlet Chaining Servlet chaining is not supported in WebLogic and for good reasons since they degrade performance. Instead through the RequestDispatcher interface, the forward and include methods perform the same function while not decreasing performance and state management. 2.1.5 JSP Tag Library A tag library is a way to represent objects as a set of tags. An HTML author to get and set properties may then use those tags. A tag library helps separate the role of HTML author from Java programmer. This may increase productivity during the planning, development and deployment stage of an application. Similar to proper EJB design, the tag library should represent course-grain objects or objects that will be called by the presentation layer. For instance if a Person object is not exposed to the presentation layer but rather a Customer object is, then tags should be created for the Customer not the Person. 2.1.6 JavaBeans <jsp:useBean> is an excellent method to expose current JavaBeans or Java classes to HTML authors. It helps decrease development time because it is not necessary to create a tag library for the component. On the other hand, if the business logic is written as EJB components, then there is an extra step to create JavaBeans that represent the EJBs instead of just generating a tag library.
Page 13
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Another positive and negative is reusability. Although the JavaBean is more reusable than a generic Java class, it does not provide the abstraction of a tag library. So for JavaBeans the <jsp:useBean> tag is beneficial but for EJBs it is easier and more reusable to create a tag library. 2.1.7 Session State Management for Rich Client types Session state management is the ability of the server to store client data across client invocations. When using Servlet or JSP based clients, the HttpSession Object supports this requirement. Both WLS 5.1 and 6.0 extend this capability to a cluster by replicating the HttpSession object to a primary and secondary location within the cluster. In the case of Rich (RMI Clients) clients, these facilities are not inherently available. Following are suggestions for single server and cluster aware solutions. WLS 5.1 Workspaces can be used to provide server-side storage. This solution is only available prior to WLS 6.0 and is limited to a single server deployment. Workspaces are not replicated. The JNDI tree can be used as a distributed store, but has numerous limitations. Only references to objects are stored in the JNDI tree and replicated across the cluster. JNDI references would also need to be unbound at the end of a users session. Entity Beans are a viable option for both single server and clustered solutions. Disadvantages of entity beans for maintaining Session State are the performance overhead of persisting session data, and the requirement to remove bean data at the end of a session. Stateful Session beans can be used in a single server deployment using WLS 5.1 or a cluster using WLS 6.0. Stateful Session beans are an excellent choice since they are inherently designed to provide session-scoped data 2.1.8 Deployment 2.1.8.1 Web Application & WAR The specification defines how to package these resources into a portable Web Application Archive so that they can be deployed on an application server (such as WebLogic Server) that supports J2EE Web Applications. A Web Application operates within a Servlet context that defines an environment that is separate from other Web Applications running on the same server. Several Web Applications may run in a single instance of WebLogic.
Page 14
J2EE Design Considerations for WebLogic Server ___________________________________________________________ A deployment descriptor that ties its resources together and describes how the resources are deployed on an application server accompanies each Web Application. 2.1.8.2 HttpSession Within WebLogic, you have properties to setup and configure Session tracking that greatly affect performance and availability. These properties primarily focus around the cache, replication and cookies. If sessions are enabled, weblogic.httpd.session.enable=true, review the following properties. The cache is the memory location of the sessions. The lifetime of the session is controlled by a timeout parameter, weblogic.httpd.session.timeoutSecs=integer. Although a session may have timed out, it is not garbage collected until the session is invalidated, weblogic.httpd.session.invalidationIntervalSecs=integer. In an ideal world, the customer knows the expected size of each session. In reality, it is rare. In either case, you should estimate the total amount of memory required for the Session objects by multiplying the maximum number of sessions, weblogic.httpd.session.cacheEntries=integer, by the average size of a session (application specific). If the figure is too high, redesign the session or decrease the number of sessions in the cache. To increase availability but decrease performance, a session may be replicated. Although, WebLogic supports many ways to persist the session (file, database or replication), memory replication is recommended because it provides an increase in availability with the least decrease in performance. 2.1.9 In-Memory State Replication with a Proxy Server When using in-memory state replication, the WebLogic Cluster must live behind one or more proxy servers. The proxy servers are smart enough to send requests, belonging to the same HTTP session, back to the same server in the cluster that holds the session data. This eliminates the need to write the session data to a shared database. You may use the Netscape Server, IIS, Apache or the WebLogic Server as a proxy server. Replicating each session on a secondary node in the cluster provides Failover. If the primary node fails, the secondary node takes over, becoming the new primary node for the session data. Another node is selected as the secondary node, and a backup of the session is made. If WebLogic Server is used as the proxy server, fail-over will occur up until the results are sent to the browser. However, if Netscape Server, Apache or IIS is used as the proxy server, fail-over will occur at the request level. To setup memory replication, configure the following properties in the weblogic.properties file.
Page 15
J2EE Design Considerations for WebLogic Server ___________________________________________________________ weblogic.httpd.clustering.enable=true weblogic.httpd.session.persistence=true weblogic.httpd.session.persistentStoreType=replicated 2.1.10 JDBC Session Persistence Each cluster node may access the Servlet’s session via a shared database through JDBC. For details on setting up persistent storage for Servlet sessions, see the Administrators Guide on Setting up Session Management. Each time you add or change data in the HttpSession the change is written immediately to the persistent store database, allowing any other servers access to the updated data. This method provides good failover, but each change to the session involves a write to the database, which can be a substantial performance reduction compared to using no persistence. Also, there is the possibility of greater contention during locking of a row in the database. 2.1.11 Cookies Cookies may not be a performance issue but often are a security issue. If cookies are enabled, make sure they do not store private or sensitive information in the cookie. Also expire the cookie according to the customer’s security policy. That is: weblogic.httpd.session.cookie.maxAgeSecs=integer 2.1.12 Different Java Virtual Machines (JVM) One issue that should be of concern to the developer is the various JVMs that exist. It may cause problems to develop your JSP pages using one JVM version, and execute the pages on another. If you plan to run your Servlets on jRocket or HotSpot, be certain to test them in that environment. Try to develop your Servlets using the same JVM as the running environment.
Page 16
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.2 EJB 2.2.1 General When you write J2EE applications that manage a specific business function such as tracking employee data or performing complex financial calculations, put the business logic for these tasks in enterprise beans that run in the application server tier. This way you can focus your code on solving the business problem at hand and leverage the enterprise bean container for supporting low-level services such as state management, transaction management, thread management, remote access to data, and security. Separating business logic from low-level system logic means the container can create and manage the enterprise bean at runtime. Any enterprise bean coded to specification, can be configured for transaction management or security attributes according to how it will be used in a given J2EE application, and deployed to any specification-compliant container. Reusable components make this all possible without changing and recompiling the enterprise bean's code. 2.2.2 Remote In designing distributed enterprise applications, you must consider the effects of transmitting data across a network between remote objects and their clients. Due to network overhead, it is more efficient to access beans from a local client (Servlet, EJB or another object) - than to do so from a remote client where data must be serialized, transmitted over the network (sometimes with inefficient protocols: SSL, HTTP, HTTPS), and then unmarshalled. Maximize the number of object invocations within the same JVM. If it is required to invoke remote objects, minimize the number of calls and the amount of data. Because enterprise beans use significant system resources and bandwidth, you might want to model some business objects as data access or value objects instead. Data access objects do such things as access the database on behalf of the client. Value objects represent a structure to hold data fields and provide simple get and set methods to access the data. Additionally, you can structure your application to use an enterprise bean to mediate communication between the client and the rest of the EJB tier. 2.2.3 Inheritance Using inheritance may be appropriate when building groups of related beans that share common code. However, you should be aware of several inheritance restrictions that apply to EJB implementations.
Page 17
J2EE Design Considerations for WebLogic Server ___________________________________________________________ For bean-managed EJBs, the ejbCreate() method must return a primary key. Any class that inherits from the bean-managed EJB class cannot have an ejbCreate() method that returns a different primary key class. This restriction applies even if the new class is derived from the base EJB's primary key class. The restriction also applies to the bean's ejbFind() method. Because AHome.create() and BHome.create() return different remote interfaces, you cannot have the BHome interface inherit from the AHome interface. You can still use inheritance to have methods in the beans that are unique to a particular class, that inherit from a superclass or that are overridden in the subclass. 2.2.4 References Once a client has obtained the EJBHome object for an EJB instance, it can create a reference to the home by calling getHomeHandle(). getHomeHandle() returns a HomeHandle object, which can be used to obtain the home interface to the same EJB instance at a later time. A client can pass the HomeHandle object as arguments to another client, and the receiving client can use handle to obtain a reference to the same EJBHome object. Clients can also serialize the HomeHandle and store it in a file for later use. By default WebLogic Server stores its IP address in the HomeHandle object for EJBs. This can cause problems with certain firewall systems. If you are unable to locate EJBHome objects using home handles passed across a firewall, set the following property in your weblogic.properties file: weblogic.system.enableReverseDNSLookups=true
When you enable reverse DNS lookups, WebLogic Server stores the DNS name of the server, rather than the IP address, in EJB home handles. 2.2.5 Life Cycle Entity EJBs can be accessed by multiple clients, but only in a serial fashion. If two clients attempt to access the same entity EJB instance (an instance having the same primary key), the second client blocks until the EJB is available. An instance of a stateful session EJB can be accessed from only one client virtual machine at a time. Multiple client threads from the same virtual machine can access the same instance of a stateful session EJB, but they must do so in a serial fashion;
Page 18
J2EE Design Considerations for WebLogic Server ___________________________________________________________ simultaneous access to a stateful session EJB results in a RemoteException, as required by the EJB 1.1 specification. This restriction for stateful session EJBs applies whether the EJB client is remote or internal to WebLogic Server. If multiple Servlet classes access a session EJB, each Servlet thread (rather than each instance of the Servlet class) must have its own session EJB instance. To avoid RemoteException errors in such a scenario, each Servlet should store a reference to a particular EJB instance in a local variable of the Servlet’s service() method. 2.2.6 Transactions Database transactions are typically one of the most valuable resources in an online system. When using EJBs with WebLogic Server, transaction resources are even more valuable due to their relationship with database connections. WebLogic Server can use a single connection pool to service multiple, simultaneous database requests. The number and length of database transactions that use the pool largely determine the efficiency of the connection pool. For non-transactional database requests, WebLogic Server can allocate and reallocate a connection very quickly, so that another client can use the same connection. However, for transactional requests, a connection becomes "reserved" by the client for the duration of the transaction. To optimize transaction use on your system, always follow an "inside-out" approach to transaction demarcation - transactions should begin and end at the "inside" of the system (the database) where possible, and move "outside" (toward the client application) only as necessary. The following sections describe this rule in more detail. Allow the data store to manage transactions Many RDBMS systems provide high-performance locking systems for OLTP transactions. With the help of Transaction Processing (TP) monitors such as Tuxedo, RDBMS systems can also manage complex decision support queries across multiple data stores. If your underlying data store has such capabilities, use them where possible. You should never prevent the RDBMS from automatically delimiting transactions. Use container-managed transactions over bean-managed transactions Your system should rarely rely on bean-managed transaction demarcation. Use WebLogic Server container-managed transaction demarcation unless you have a specific need for bean-managed transactions. Possible scenarios where you may need bean-managed transactions are:
Page 19
J2EE Design Considerations for WebLogic Server ___________________________________________________________ You must define multiple transactions from within a single method call. WebLogic Server demarcates transactions only on a per-method basis; if you require multiple transactions in a single method call, you must use bean-managed transactions. Note: If your EJBs use multiple transactions in a single method call, it is still better to break the transactions out across multiple methods and use container-managed transactions on the revised bean. A single transaction must "span" multiple EJB method calls. For example, one method begins a transaction, and another method commits or rolls back the transaction. In general, this practice should be avoided where possible since it requires detail information about the workings of the EJB object. If it is required, you must use beanmanaged transaction coordination, and you must coordinate client calls to the respective methods. Never demarcate transactions from a client application In general, client applications are not guaranteed to stay active over long periods of time. If a client begins a transaction and then exits before committing, it wastes valuable transaction and connection resources in WebLogic Server. Moreover, even if the client does not exit during a transaction, the transaction duration may be unacceptable if it relies on user activity to commit or rollback data. Always demarcate transactions at the WebLogic Server or RDBMS level where possible. Use declarative transactions Declarative transactions can be realized by specifying the transaction type needed with deployment of the EJB (e.g. TX_REQUIRED, TX_REQUIRES_NEW, etc.). By doing this the responsibility for the transaction handling is given to the EJB container. With programmatic transactions the responsibility is given to the bean and hence the programmer of the bean. This is much more tedious than using declarative transactions. 2.2.7 Persistence The EJB 1.1 container in WebLogic Server Version 5.1 uses a pessimistic locking mechanism for entity EJB instances. As clients enlist an EJB or EJB method in a transaction, WebLogic Server places an exclusive lock on the EJB instance or method for the duration of the transaction. Other clients requesting the same EJB or method block until the current transaction completes. With the database locking mechanism of the EJB 2.0 container, WebLogic Server continues to cache instances of entity EJB classes. However, the container does not cache the intermediate state of the EJB instance between transactions. Instead, WebLogic Server calls ejbLoad() for each instance at the beginning of a transaction to obtain the latest EJB data. The request to commit data is subsequently passed along to the database.
Page 20
J2EE Design Considerations for WebLogic Server ___________________________________________________________ The database, therefore, handles all lock management and deadlock detection for the EJB's data. Deferring locks to the underlying database provides an easy way to improve throughput for concurrent access to entity EJB data, while also providing deadlock detection. However, using database locking requires more detailed knowledge of the underlying data store's lock policies, which can reduce the EJB's portability among different systems. 2.2.8 Resources Separate bean-specific and bean-independent resources It is important to make a distinction between bean-specific and bean-independent resources when programming EJBs. Why? Because allocation of resources is expensive and should be minimized as far as possible. This should however not be done at any price and this is where the distinction between bean-specific and bean-independent resources may help. Example: can all EJBs of this type share this socket or is it specific for a particular instance of an EJB? Distribute only the necessary files to clients and servers It is recommended to distribute the relevant class files on a “need to know” basis, i.e. only those files that are needed for a particular environment. For clients only the class files for the home and remote interfaces should be distributed. For servers only the files for the bean classes should be distributed. 2.2.9
EJB QL
This release of WLS supports the Enterprise JavaBeans Query Language (EJB QL). EJB QL is syntax for the definition of finder methods or queries for entity beans with container-managed persistence. This syntax allows the Persistence Manager to provide for the implementation of the finder methods. EJB QL defines finder methods so that they are portable across containers and persistence managers. EJB QL is a declarative, SQLlike language that is meant to be compiled to the target language of the persistent data store used by a Persistence Manager. For more information on EJB QL, see Using EJB QL. 2.2.10 Container-Managed Persistence WLS 6 provides added support for container-managed relationships among entity beans. This container-managed persistence model is an improvement over the limitations of the field-based approach to container-managed persistence in earlier versions.
Page 21
J2EE Design Considerations for WebLogic Server ___________________________________________________________ With container-managed persistence, database access calls are not written in the entity bean. Instead, persistence is handled by the EJB container that is available at run time. The persistent fields and relationships for which the container must generate data access calls are specified in the deployment descriptors. When the entity bean is deployed, the container is used to generate the necessary database access calls. For more information on container-managed persistence, see EJB 2.0 Persistence Features and Changes. 2.2.11 Message-Driven Beans EJBs are integrated with the Java Message Service (JMS) to provide the ability for a message-driven bean to act as a standard JMS message consumer. The message-driven bean is a stateless component that is invoked by the EJB container as a result of receiving messages from a JMS Queue or Topic. The message-driven bean then performs business logic based on the message contents. Using the message-driven bean model allows EJB developers to work with a familiar framework and set of tools and also provides access to the additional support provided by the container. Message-driven beans have no home or remote interface, and therefore cannot be directly accessed by internal or external clients. Clients interact with message-driven beans only indirectly, by sending a message to a JMS Queue or Topic. WLS automatically creates and removes message-driven bean instances as needed to process incoming messages. Only the WLS container directly interacts with a message-driven bean by creating bean instances and passing JMS messages to those instances as necessary. The goal of the message-driven bean model is to assure that developing an EJB that is asynchronously invoked to handle the processing of incoming JMS messages, is as easy as developing the same functionality in any other JMS MessageListener. For more information on message-driven beans, see Developing Message-Driven Beans. 2.2.12 Session Beans The decision about whether to use stateless versus stateful session beans is a fairly easy and intuitive decision. Even though session beans are temporary in nature, there are still cases in which it is necessary to remember some client data from one method call to the next in its short life. In this case you would use stateful beans. When it is a one-time shot, that is, you use the logic only once and then you're done with it, then you should use a stateless bean. The bottom line is that session beans are the foundation of the application’s business logic. Stateless Session EJBs provide coarse-grained access to system’s data, as well as computational services. This type of bean utilizes system memory in a transient manner, since it doesn’t hold any data in memory. Stateless session EJBs support full-load balancing and will provide automatic fail-over support when services are idempotent. Stateless Session EJBs are relatively light-weight components. Since they don’t hold any state, the container dynamically assigns beans to client requests on a per-method call
Page 22
J2EE Design Considerations for WebLogic Server ___________________________________________________________ level. This means, that a small number of stateless sessions can serve many transactions before the container will need to increase the pool size. That is in stark contrast to entity beans, where every bean instance serves a single client. If the client code needs to invoke a task that spans interactions with more than one entity bean, this functionality should be modeled as a method in a session bean. Session beans will provide a coarse-grained interface with the business data, to provide application’s workflow (business process definition). Special care should be given to memory intensive operations as “listing”, batch-retrieves, batch-updates and previews. It is highly recommended to model such operations using session beans, without interaction with entity-beans. In the case of interaction with a single business unit, modeled as an entity EJB, client code should interact through a session bean. Session beans publish interfaces to handle interactions with more than one entity bean (workflow), and to handle with batch operations. Client code will interact with session EJBs for these purposes. To trigger workflow and batch operations, client should interact with Session EJBs. In general, a good design will emphasize the use of coarse-grained session-beans as workflow, and limit fine-grained direct entity access. Batch operations should be modeled as methods of session beans. Batch operations mentioned in the last paragraph can be mostly done using single database access (insert or update SQL statement). There are, however, batch operations that require multiple SQL statements to execute. These are mostly operations that create multiple entries in a table (repetitive inserts). These operations should be serviced from a stateless session EJB, but for optimal performance should be implemented using database stored-procedures. To minimize performance hit, strive to push implementation of operations, which uses multiple insert statements, to the database level. Algorithms that perform calculations based on input (parameters) without need to access persistent data are also best modeled using stateless sessions. Calculations that are input based should be modeled as session-bean methods.
Page 23
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Session beans will most likely be required to provide a mixture of all the above services together. This will result in session beans providing services that (for instance) uses batch retrieve, manipulate in memory data, perform logic, branching and finally perform batch update. You should tie together such functionality under a single method (service), only if there is a need for transactional atomicity for all these operations, or it is required by business logic that is provided by the service. Otherwise, distribute functionality among several methods. Session EJB provide mixed services under one method, only when transactional constraints or internal service logic prevent breaking the service to smaller services. A good practice is to create a mixed service by wrapping up several methods as a single workflow operation served by another method. For mixed services, also review transaction management guidelines. Keep business logic in session beans and data in entity beans Session beans should contain business logic, relying on entity beans for the storage and persistence of their data. This is similar to the façade design pattern. It is recommended to have only a limited amount of business logic in the entity beans in order to improve their reuse (in general entity beans can be more easily reused than session beans). Ensure cluster is homogenous when replicating stateful session beans To replicate the state of a stateful session EJB in a WebLogic Server cluster, you must ensure that the cluster is homogeneous for the EJB class. In other words, you must deploy the same EJB class to every WebLogic Server instance in the cluster, using the same deployment properties. In-memory replication is not supported for heterogeneous clusters. By default, WebLogic Server does not replicate the state of stateful session EJB instances in a cluster. This models the behavior released with WebLogic Server Version 5.1. To enable replication, set the replication-type deployment parameter to InMemory in the weblogic-ejb-jar.xml deployment file. For example:
InMemory
Page 24
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Write smart stateful session beans When stateful session beans die, their state will be lost. It is recommended to write stateful session beans in such a way that they are able to restore their conversational state to that just before they died. In many cases this will prove to be impossible, but there may be some situations where the state can be restored, e.g. based on environmental or session information. Consider using the javax.ejb.SessionSynchronization interface When using stateful session beans with declarative transactions the javax.ejb.SessionSynchronization interface offers a couple of methods that can help restoring status after a rollback of a transaction: afterBegin(), beforeCompletion() and afterCompletion(). The EJB container will automatically call the methods of this interface at the appropriate times. 2.2.13 Entity Beans Read/Write Entity beans models fine-grained data manipulations and access. They act as intermediateors to underlying persistent store, while caching information in the application server’s memory. They provide client-specific object view for relational representation of data. RW entity EJBs are relatively heavy-weight components, and can service a single client per instance. Do not use read-write entity beans if the functionality you want to model absolutely needs automatic fail-over or load-balancing support in EJBObject level. Generally speaking, an entity bean should represent an independent business object that has an independent identity and life cycle, and is referenced by multiple enterprise beans and/or clients. In contrast, a dependent object represents data which is related and bound to the life-cycle of another business-entity. A dependent object is better implemented as a Java class (or several classes) and included as part of the entity bean on which it depends. For example, in a system that manages users, every user is associated with contact information. Not only does a contact belong to a user, it does not even exist without a user. Therefore, the contacts database table should be represented with a helper class and not with an entity bean. This helper class is called “dependent class”. An entity bean has an independent life cycle that is not bound within or managed by the life cycle of another object.
Page 25
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Read Only Entity beans are an excellent choice when there is a need to model data, which is relatively static. They provide automatic fail-over and full load-balanced operation in a clustered environment. Use RO entity EJBs to access data, which applies to one of the following criteria:
• It is ensured to be static by business rules • It is updated by a non-EJB source on a low-frequency basis • Updates to data done by EJB sources need-not be reflected immediately to users (clients can tolerate temporary non-synchronized data). As with RW entity EJBs, do not use RO entity EJBs unless you need to cache some information (for caching criteria see separate section). Use Read Only Entity EJBs only when you need to cache static information.
Database information that can only be generated after other data is inserted, and should be removed when the other data is deleted, should be modeled as a helper, dependent Java class, and manipulated by other beans.
Object to Relational schema should aggregate few logically-related database tables into single entity bean. The entity bean will manage life cycle of a single business concept, including all it’s related data. Since an entity bean is supposed to provide a unified, aggregated remote interface to a set of dependent persistent objects, the services it publishes need to provide some business logic. Data manipulations done through entity beans need to encapsulate some business logic. If your entity bean appears to be a collection of simple set and get methods, it is a good sign that something is wrong. Although it is a good idea to aggregate few logically-related tables under one RW entity bean, care must be taken not to make the component too coarse. After certain threshold, performance will suffer, since access to small-grained, dependent objects will require more database operations. Also, if the bean caches information, there will be unnecessary big memory foot-print for maipulating encapsulated dependent objects.
Page 26
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Don’t excessively aggregate functionality. Too coarse entities become difficult to use, and couple unrelated functionality. As a rule of thumb don’t aggreagate relationships more than one level deep. There is no point to use an entity bean if you do not need to cache some of the data it represents (for caching criteria see separate section). This will unneccesarily consume application server resources. Model data access and manipulations in a RW entity EJB, only if part of the data, or all of it, needs to be cached. Entity beans provide unfied access and manipulation for a single business concept. You should not access data modeled by entity bean X from entity bean Y. You should strive to minimize inter-entity beans calls as much as possible. Good modeling can prevent such calls completely. The scope of data manipulation provided by an entity bean should be focused to a single instance of the business concept (reperesented by a bean and it’s dependent objects). Do not use entity beans operations to affect the data of more than one instance: Entity beans should be course grained You should not attempt to model every object in your system as an entity EJB. In particular, small subsets of data consisting of only a few bytes should not exist as Entity beans - the trade-off in network resources is unacceptable. For example, line items in an invoice or cells in a spreadsheet are too fine-grained and should not be accessed frequently over a network. In contrast, logical groupings of an invoice's entries, or a subset of cells in a spreadsheet may be modeled as an entity EJB, if additional business logic is required for the data. Entity beans should validate and format data Even coarse-grained objects may be inappropriate for modeling as an entity EJB if the data requires no additional business logic. For example, if the methods in your entity EJB work only to set or retrieve data values, it is more appropriate use JDBC calls in an RDBMS client or session EJB. Entity EJBs should encapsulate additional business logic for the modeled data. For example, a banking application that uses different business rules for "Platinum" and "Gold" customers might model all customer accounts as entity EJBs; the EJB methods
Page 27
J2EE Design Considerations for WebLogic Server ___________________________________________________________ can then apply the appropriate business logic when setting or retrieving data fields for a particular customer type. Optimize entity EJB data access Entity EJBs ultimately model fields that exist in a data store. You should optimize entity EJB wherever possible to simplify and minimize database access. In particular: •
Limit the complexity of joins against EJB data
•
Avoid long-running operations that require disk access in the data store
•
Ensure that EJB methods return as much data as possible, so as to minimize round-trips between the client and the data store. For example, if your EJB client must retrieve data fields, use bulk get/setAttributes() methods to minimize network traffic
Use isModified() where appropriate EJBs must set the isModified() flag to true in every place where the state may change. Methods such as ejbRemove(), ejbActivate(), and ejbPassivate() must also set this flag, because the bean may be reused. If the EJB uses container-managed persistence, you must set the flag to false in ejbLoad() and ejbStore(), if you want the container to take advantage of this optimization. Although ejbStore() is called before the EJB is actually written to the database, in the event that an exception is raised while writing to the database, WebLogic Server assumes that the EJB has been modified, regardless of the setting of the flag. Reduce network roundtrips by using lazy loading of beans Normally the ejbLoad() method of a bean will load all the referenced subbeans. This may be a waste of resources if the client never calls a method of the subbeans. A better approach is to load the subbeans at the time they are needed. This can be achieved by adding a proxy layer of indirection between the bean and its subbeans. Packages to do this already exist, e.g. SmartProxies by Rickard Oberg. Note however that lazy loading beans have a performance trade off due to the delayed loading of the beans. There is a very interesting article on Designing Entity Beans for Improved Performance, by Beth Stearns.
Page 28
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.2.14 Client-Server Interface This section will provide basic guidelines for how to rout calls between client code (mostly servlets, JSPs and request handlers) and the EJB services layer. It will also touch the granularity of the client server interface, taking into account clustering considerations and performance optimization. The assumption here is that client code interacts with the EJB tier using JNDI lookups and RMI invocations. 2.2.14.1Access to EJB Services If client code needs to interact with a specific (single) entity, it is recommended that client code communicate with it through a stateless session bean. Effectively, session beans will wrap operations served by entity beans, thus creating a façade for them. Although this may look wasteful (additional lookup), it provides more flexibility about the way functionality is implemented (it makes it easier to change modeling from entity bean to stateless session, if required). 2.2.14.2Granularity of Entity EJB Services The basic question here is what is the service granularity an entity bean should expose for manipulating data through it’s interfaces: will every attribute have a set method of it’s own? Fine-grained, per-attribute set methods are known for creating performance problems. These problems arise from the fact that many times client code needs to manipulate few attributes of a business entity at once. When client code retrieves data from a specific business entity, many times it is interested in a complete set, or known sub-sets, of the attributes held by the entity. Thus, fine-grained set and get methods will result in performance degradation, which will originate from the following reasons: In a clustered environment, db-is-shared property has to be true. That means that data retrieval services provided by RW entity beans has to be transactional. Default container behavior will kick in, and synchronize the database with object state for every read operation. That means that fine-grained get methods will result in multiple loading of attributes from the database. This will result in significant performance degradation, if data-sets requested by the client include many attributes. •
In a two tiered cluster, RMI invocations of client code will serialize parameters and send them over the wire to the EJB cluster. Using fine grained services will lead to many network operations.
•
Some operations needs to be performed for every EJB service call. For instance: security authorization. Fine-grained set and get methods will result in excessive execution of auxilary operations.
Page 29
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Excessive use of the fine-grained operations (such as setDocumentName ) will lead to the usual performance problems associated with fine-grained remote communication, and is considered a bad practice. This discussion leads to the conclusion, that it is required to define "bulk" accessing methods that take or return portions of the entity bean’s object graph or a collection of data. The granularity of services provided by entity EJBs should exactly match the granularity needed by the client code. For example, a Requirement entity EJB should provide an overloaded setRequirementData() method. The different versions of this method will get various data object parameters. Thus, the set of attributes of a specific data objects will define the granularity of a specific service. These data objects should be serializable, and can be returned by bulk get methods, and reused later on the presentation tier, by JSP java code. Define bulk accessors, that package access to several persistent fields in a single method call. A bulk setter method should get a serializable data-object as parameter, which holds all the data to set. A bulk getter should return a serializable data-object, which holds all data requested by the client. In order to optimize data access, data objects should not have setters or getters. They consist of a constructor and a list of public attributes. They merely represent a data structure with no behavior. The fact that data objects do not have set methods defines them as semantically immutable, and this should instruct clients not to modify their attribute’s values. When these object are passed from a servlet / request handler, the EJB tier should not modify data-object’s attributes. Data objects represent data-structures with no behavior. A consumer of data-object should not modify it’s attributes. Presentation tier and EJB tier should reuse data objects as much as possible. 2.2.15 Modeling Relationships Most enterprise applications define relationships between business entities. These relations are modeled in the database level as inter-table relationships. This section will describe how to translate database relations into an EJB object view.
Page 30
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.2.15.1Types of Relationships
• One to One In a one-to-one relationship, each row in a table is related to a single row in another table. For example, a user record has a reference to a single contact information record, and vice-versa. In the data model, such a relationship usually means that one table has a foreign key, which is mapped to the primary key of another table. The table with the foreign key is called the “child” table, and the referred table is called the “parent” table.
• One to Many If the primary key in a parent table matches multiple foreign keys in a child table, then the relationship is one-to-many. This relationship is common in database applications. For example, an order may contain many line items. The order is stored in the orders table, where line items are stored in lineitems table. Each line item has a foreign key of the order to which it belongs.
• Many to Many In a many-to-many relationship, each entity may be related to multiple occurrences of the other entity. For example, a college course has many students and each student may take several courses. In a database, a cross-reference table containing the foreign keys should represent this relationship. When modeling relationships, it is important to differentiate between two types: 1. External Relationship This type of relationship is common when two entities are completely independent, and the relationship between them does not affect their internal behavior When modeling external relationship between two business entities, strive to decouple the relationship management from the entitie’s data management. 2. Inherent (Structural) Relation When the relationship to other objects is inherent in the nature of the object, it means that part of the behavior of the object is to define a structue. This type of relationship is typical in composite structues When modeling structural relationship, manage the relationship from within one of the objects. The object which other entities “belongs” to should manage the relationship. Do not manage the relationship from both sides. Note: if in order to maintain a relationship, an operation needs to access more than one bean, than it should be modeled in a session-bean, as a workflow operation.
Page 31
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.2.15.2Modeling Relationships with EJBs When the relationship between two business entities is external, model it outside entities code. When modeling external relationships, use stateless session beans. This will de-couple operations that add or delete relationship from the entities’ code. When the relationship between two business entities is structural, model it inside entity bean code. When modeling structural relationships, place the code that manages the relationship inside one of the beans. You may consider caching relationship attributes if performance is important. 2.2.16 Inter-Bean Communication There is a need to define the possibility of one EJB service to invoke another EJB services. This section present guidelines for this issue. Following these guidelines presented here together with other guidelines presented in this document will minimize the possibility for deadlocks. 2.2.16.1Entity to Entity Since entity beans present fine-grained, data-oriented service, which is focused around specific business concept, a good design will prevent inter-entity beans calls. There are few good reasons for that: Inter-entity beans call actually structure a workflow oriented operation. Thus, it is best modeled by a stateless session EJB. Inter-entity beans call makes it very possible for an application to create dealocks in beans level (this is due to the fact that EJB is a single threaded framework). A database deadlock or rollback is also possible, since inter-bean calls enable table data manipulations by two different beans, so transactional race condition may be possible. Avoid inter-entity-beans invocations.
2.2.16.2Session to Session Although possible, inter-session bean calls are not the optimal way of chaining stateless services. This is due to the lookup overhead of invocations, and the possibility that the
Page 32
J2EE Design Considerations for WebLogic Server ___________________________________________________________ target session bean will not reside on the same machine as the calling session. A better design will externalize shared functionality to a utility class, and reuse this class from all sessions. Inter-Session beans are permitted. However, if you need to reuse a stateless service by calling another session, a better approach would be to externalize the service to an additional Java class, which will be used by both session beans.
2.2.16.3Entity to Session According to these guidelines, good modeling will prevent the need for such calls, since entity beans should provide fine-grained services, and session beans provides coarsegrained or workflow oriented services. Avoid entity bean to session bean calls.
2.2.16.4Session to Entity Since session beans provide workflow operations, this type of call is possible. Note, that since batch operations should be performed by direct database access, the possibility for beans or database deadlocks will be reduced dramatically. Use calls from session beans to entity beans when you model fine-grained workflow operations, which encapsulate interactions with few business entities. 2.2.17 Deployment 2.2.17.1Overview The WebLogic Server EJB Container is required reading. It clearly explains the lifecycle and caching of an EJB including the properties to set to alter the default behavior. 2.2.17.2Performance A stateless session bean utilizes a free pool for its cache. When WebLogic starts, you may create a number of instances (initial-beans-in-free-pool). As with the other types, you may cap the number of instances in memory (max-beans-in-free-pool). When a client creates an instance, it receives a reference to a bean in the pool. When the response is received, the bean is returned to the pool. Unlike stateful session or entity beans, each method call may reference a different instance in memory.
Page 33
J2EE Design Considerations for WebLogic Server ___________________________________________________________ No stateful EJB instances exist in WebLogic Server at startup time. As clients look up and obtain references to individual beans, WebLogic Server initializes new instances of the EJB class and stores them in the cache. If max-beans-in-cache is reached and there are EJBs in cache that are not being used, WebLogic Server passivates some of those beans. This occurs even if the unused beans have not reached their idletimeout-seconds limit (described below). If max-beans-in-cache is reached and all EJBs in the cache are being used by clients, WebLogic Server throws a CacheFullException. Entity bean performs an ejbLoad() and ejbStore() for each method call. This may be extreme depending on the bean. To optimize reads and writes from the database, several properties may be set. db-is-shared, is-modified-method-name (not required in EJB 2.0), delay-updates-until-end-of-tx, readonly (read-timeout-seconds), concurrency-strategy (more information). 2.2.17.3Availability In a WebLogic Server cluster, the server-side representation of the home object can be replaced by a cluster-aware "stub". The cluster-aware home stub has knowledge of EJBHome objects on all WebLogic Servers in the cluster. The clustered home stub provides load balancing by distributing EJB lookup requests to available servers. It can also support failover support for lookup requests, since it routes those requests to available servers when other servers have failed. All EJB types - stateless session, stateful session, and entity EJBs - can have clusteraware home stubs. Whether or not a cluster-aware home is created is determined by the home-is-clusterable deployment property in weblogic-ejb-jar.xml. If this property is set to "true" (the default), ejbc calls the rmic compiler with the appropriate options to generate a cluster-aware home stub for the EJB. Stateless Session Bean Stateless session EJBs can have both a cluster-aware home stub and a replica-aware EJBObject stub. By default, WebLogic Server provides failover services for EJB method calls, but only if a failure occurs between method calls. For example, failover is automatically supported if there is a failure after a method completes, or if the method fails to connect to a server. When failures occur while an EJB method is in progress, WebLogic Server does not automatically failover from one server to another. If methods are written in such a way that repeated calls to the same method do not cause duplicate updates, the method is said to be "idempotent." For idempotent methods, WebLogic Server provides the stateless-bean-methods-are-idempotent deployment property. If you set this property to "true" in weblogic-ejb-jar.xml, WebLogic Server assumes that the method is idempotent and will provide failover services for the EJB method, even if a failure occurs during a method call.
Page 34
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Stateful Session Bean To replicate the state of a stateful session EJB in a WebLogic Server cluster, you must ensure that the cluster is homogeneous for the EJB class. In other words, you must deploy the same EJB class to every WebLogic Server instance in the cluster, using the same deployment properties. In-memory replication is not supported for heterogeneous clusters. By default, WebLogic Server does not replicate the state of stateful session EJB instances in a cluster. This models the behavior released with WebLogic Server Version 5.1. To enable replication, set the replication-type deployment parameter to InMemory in the weblogic-ejb-jar.xml deployment file. For example: InMemory
Page 35
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.3 JMS 2.3.1 Transactions To support transactions, JMS uses the Java Transaction Service (JTS), which is implemented in the WebLogic Server. There are two ways to use transactions with JMS. If you are using only JMS in your transactions, you can create a transacted JMS session. If you are mixing other operations, such as EJB, with JMS operations, you should use a JTS UserTransaction in a non-transacted JMS session. 2.3.1.1 Transacted JMS sessions Transactions in JMS transacted sessions are chained -- whenever you commit or roll back a transaction, another transaction automatically begins. The JMS Connection has a TransactionTimeout=seconds value that specifies the number of seconds a transaction can run before it is timed out. When a transaction times out, it is rolled back. The default TransactionTimeout is 3600 seconds (one hour). If you have longrunning transactions you might need to increase this value to allow your transactions to complete. 2.3.1.2 JTS UserTransactions If you are using JMS and EJBs, or have already started a user transaction, WebLogic JMS respects the existing UserTransaction. If you create a JMS transacted session when you already have a UserTransaction, an exception is thrown when you call any transaction method on the JMS Session object. To combine JMS and EJB operations in a transaction, you can start a transaction from an EJB or by getting a javax.jts.UserTransaction with a JNDI lookup. 2.3.1.3 JTA Transactions Between WLS JMS and MQSeries JMS - A First Look This section describes some explorations in using JTA transactions to envelop WLS JMS and MQSeries JMS messaging.
2.3.1.3.1 Using JTA and the XAResource Interface
• XAResource interfaces must be registered for WLS (with the exception of XAcompliant JDBC interfaces). This registration can only be done on the server side. To get the XAResource from MQSeries, a session is needed. It is necessary to create the session on the server so that the registration can be done. Therefore, all JTA work between WLS and MQSeries must be done on the server side, not in the client.
Page 36
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • WLS JMS does not implement the XA* methods. There are several reasons for this. One is that the methods are optional and the WLS JMS interface can be an XAResource without them. Second, there are some problems with the interface as defined in the JMS 1.0.2 specification that make it impossible for a distributed product like WLS to implement the interface correctly. For example, WLS can have multiple XAResources available to a session but this is not handled by the session.getXAResource() method. However, MQSeries JMS uses the XA* methods to access the XAResource. In summary, the application code must use different objects and method calls for connection factories, connections, and sessions between the two JMS implementations.
• Finally, if you don't set things up correctly, you will get a one-phase commit with just WLS JMS and no warning that MQSeries JMS is not participating in a two-phase commit. This seems to be the way that the JTA specification is written. The only way to really know if it's working correctly is to turn on WLS JTA debugging. Starting with the sample that was posted in the BEA WLS newsgroup earlier (editor thinks this is a posting entitled “Weblogic 6.0 - MQSeries - JMS “ dated 09-March-01) regarding support for foreign JMS providers, the sample was modified to run on the server side. There are many ways that the code could have been modified. For instance, a startup class with all of the code, a servlet, multiple RMI objects with more functional methods, an EJB, etc. The sample listed in Appendix A – Using JMS with MQ Series Sample Code chose to simply put the code in a startup class (with more ambitious changes left as an exercise for the reader). 2.3.2 Security If an ACL is not set up for a JMS queue or topic, all permissions for that queue or topic are by default granted to everyone. The developer must set the permissions "receive" and "send" for a JMS queue or topic by entering a property in the weblogic.properties file. 2.3.3 Deployment A ConnectionFactory, Topic and Queue may be configured in the weblogic.properties file, the WebLogic Console or programmatically through the JMS API. A Connection, Session and Message may be configured programmatically through the JMS API.
Page 37
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.3.4 Performance 2.3.4.1 Concurrency JMS Connections, ConnectionFactories, Topics, and Queues support concurrent use. Other JMS objects -- including QueueSenders and QueueReceivers, TopicPublishers and TopicSubscribers, and Sessions -- can be accessed by only one thread at a time. Internally, WebLogic JMS uses JMSMessageQueue tables to store the state of durable subscribers. By default, WebLogic JMS uses one table for all active durable subscribers. If the DBMS used as the backing store for JMS does not support row-level locking, this can lead to deadlocks in the system. MSSQL Server and Cloudscape do not support rowlevel locking. To avoid deadlocks, you can configure WebLogic JMS to use a separate JMSMessageQueue table for the transacted operations of each active durable subscriber. Within the weblogic.properties file, you must define the maximum number of active, transacted, durable subscribers with the weblogic.jms.maxTransactedDurableSubscribers property. This value should be equal to the number of JMSMessageQueue tables created. For example, if you have created three tables, the following line must be added to the weblogic.properties file: weblogic.jms.maxTransactedDurableSubscribers=3 The default value for this property is zero, which indicates that all transactions will be done against a single JMSMessageQueue table. Again, this default behavior is fine for DBMSs that support row-level locking. 2.3.4.2 Session Pool WebLogic JMS implements an optional JMS facility for defining a server-managed pool of message consumers -- a ServerSessionPool. The ServerSessionPool receives messages from a Topic and passes them to a server-side MessageListener implementation that you provide to process the messages. Your class provides an onMessage() method that processes a message. The ServerSessionPool manages a pool of JMS Sessions, each executing your singlethreaded onMessage() method, so that messages are processed in parallel. Overall placing producers and consumers on the same server may enhance reliability. This means that if the server goes down then all messages are lost, and everyone starts over.
Page 38
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.3.5 Issues JMS is good for non-persistent publish/subscribe. Persistent publish/subscribe has too many failure points. There are many scenarios where receive queues are lost or send queues are lost and there is no recovery. The developer should take care to perform error checking when using a durable subscriber in JMS. When a large number of JMS topic subscribers are involved, sometimes the send and receive queues can become congested. This causes loss of data or unreliable messaging. There is no complete workaround for this issue at this time. Some server-side programs calling JMS on another member of a cluster incurs a bug with JMS ObjectMessage.getObject() returning null. Extra error checking is needed. There is a problem with a JMS race condition in a 2-server cluster. We think this is a solved issue in WLS 5.1. The patch could not be rolled back to WLS 4.51. Specifically, the race condition is solved in SP3 (service pack 3) for WLS 5.1. Only when JMS is clusterable will this really be solved. This feature will make JMS much more stable and will improve performance as well. In some cases there is a problem with persistent messages not being persisted. This happens when setJMSDeliveryMode is set to persistent. JMS must be restarted when this happens. Extra error checking is required for even simple message passing. In a message receiver, it is good practice to check that the received message is of the type the message handler method expects.
Page 39
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.4 JNDI 2.4.1 How do you get an InitialContext In order to perform work that requires authentication or access control, you must associate a principal, or user, with the thread that will perform the work. To do so, create a context with the appropriate principal and credential property values as described in the sections above. To disassociate a principal with the thread, close the context. When a thread is associated with a principal, that principal becomes the default for the thread. If any contexts are subsequently created without principal or credential properties, the principal associated with the thread will remain unchanged. The WebLogic documentation on JNDI provides more information. 2.4.2 Delegated Name Space Using WebLogic to support your calls to a delegate service provider provides several advantages: •
The client doesn't need to install the delegate service provider.
•
The client doesn't need access to the delegate service provider.
To use another JNDI provider, you must provide a third property that specifies the property list to be used for connecting to the provider from the WebLogic Server.
Page 40
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.5 JTA / JTS 2.5.1 Overview Transactions provide developers with a common framework for process synchronization and errors-management. Using transactions, the operation performed by your execution thread is guaranteed to have support for the ACID properties. Proper transaction handling is essential to maintain data integrity in an enterprise system. Transaction optimization is vital for system performance, and may also minimize the possibility for deadlocks. Some transaction best practices are explained in the other sections such as EJB, JMS, JDBC. Below is a just a list of best practices that are a rule of thumb and not absolute. As mentioned previously, I/O is slow and transacted I/O is slower. But because most business applications require a guarantee, transactions are required. Therefore, use them wisely. Always design a transaction to be short-lived. For instance a client (including server side objects) should begin a transaction and wait for input from other sources. In contention with a short-lived transaction is the notion that the number of transaction should be minimized. The fewer transactions to the database, typically the faster the application. Be Performance-Conscious Transactions are very hard on performance. Be mindful of keeping transactions as short as possible in order to minimize database locking. Use Container-Managed Demarcation When possible, always use container managed transaction demarcation. This greatly simplifies a developer’s responsibilities and tasks, especially for transactions in distributed environments. Don’t Assume Client-Side Supports Transactions When designing application components, keep in mind that while enterprise beans have a mechanism for multiple-step transactions to be started automatically by their containers, applet and application client containers might or might not support this. However, applet and application client containers can always invoke an enterprise bean that does. No Client Demarcated Transactions A transaction should not begin on a remote client with a UserTransaction. Although legal, the network may cause performance and availability issues.
Page 41
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Allow WebLogic to Manage the Transaction Whenever possible, you should allow WebLogic to manage the transaction. If you declare EJB, JMS, or JDBC pools transactional through properties, you are allowing WebLogic to manage it. No Nested Transactions Nested transactions are not supported by WebLogic. Combine Operations in a Statement Whenever possible, collect a set of data operations and submit an update transaction in one statement in the form: BEGIN TRANSACTION UPDATE TABLE1... INSERT INTO TABLE2 DELETE TABLE3 COMMIT
This approach results in better performance than using separate statements and commits. Even with conditional logic and temporary tables in the batch, it is preferable because the DBMS will obtain all the locks necessary on the various rows and tables, and will use them and release them in one step. Using separate statements and commits results in many more client-to-DBMS transmissions and holds the locks in the DBMS for much longer. These locks will block out other clients from accessing this data, and, depending on whether different updates can alter tables in different orders, may cause deadlocks. Warning: If any individual statement in the above transaction might fail, due, for instance, to violating a unique key constraint, you should put in conditional SQL logic to detect any statement failure and rollback the transaction rather than commit. If, in the above example, the insert failed, most DBMSes will send back an error message about the failed insert, but will behave as if you got the message between the second and third statement, and decided to commit anyway! MS SQLServer has a nice connection option enabled by executing the SQL set xact_abort on, which will automatically roll back the transaction if any statement fails. Don’t Take User Input During Transaction – Minimize Locks
Page 42
J2EE Design Considerations for WebLogic Server ___________________________________________________________ If an application sends a 'BEGIN TRAN' and some SQL which locks rows or tables for an update, do not write your application so that it must wait on the user to press a key before committing the transaction. That user may go to lunch first and lock up a whole DBMS table until he comes back. If user input is needed to form or complete a transaction, use optimistic locking. Briefly, optimistic locking employs timestamps and triggers (some DBMSes will generate these automatically with tables set up for it) in queries and updates. Queries select data with timestamp values and prepare a transaction based on that data, without locking the data in a transaction. When an update transaction is finally defined by the user input, it is sent as a single submission that includes time-stamped safeguards to make sure the data is the same as originally fetched. A successful transaction will automatically update the relevant timestamps for changed data. If any interceding update from another client has altered any of the data on which the current transaction is based, the timestamps will have changed, and the current transaction will be rejected. Most of the time, no relevant data has been changed so transactions usually succeed. When one a transaction fails, the application can re-fetch the updated data to present to the user to reform the transaction if desired. Consider Transactional Isolation Transaction isolation allows you to define how transactions interact between themselves, by controlling the level of access a bean has to shared data. The disadvantage of sharing data is the increased prevalence of dirty, non-repeatable, and phantom reads. •
A dirty read can happen when a transaction modifies a row in a database table but has not yet committed it. If another transaction reads it, and then the first transaction does a rollback (because of some error), the changes to the row are eliminated. The second transaction has data that is inconsistent.
•
A non-repeatable read can happen when a transaction reads a row, then a second transaction modifies that row. If the first transaction reads that row again, it gets different values.
•
Suppose that a transaction selects a set of rows that match a query, then a second transaction inserts new rows that also match the query of the first transaction. When the first transaction executes the same query again it will get those additional rows. This is called a phantom read.
Page 43
J2EE Design Considerations for WebLogic Server ___________________________________________________________ To minimize these consequences, isolation levels can be set for the methods of the bean. Even though these can be defined in the deployment descriptor of the bean, the functionality is really provided by the database. The isolation levels defined are:
Transaction Isolation Level
Description
TRANSACTION_READ_UNCOMMITTED
Transactions can read uncommited changes to data Dirty reads, non-repeatable reads and phantom reads can occur.
TRANSACTION_READ_COMMITTED
Transactions can read committed changes to data, but not uncommitted data. Data reads are prevented, non-repeatable and phantom reads are possible.
TRANSACTION_REPEATABLE_READ
Transactions can’t change data what is being read by other transactions. Dirty and non-repeatable reads are prevented; Phantom reads are possible.
TRANSACTION_SERIALIZABLE
Transaction operate serially on data. The strictest isolation level; all of the above problems are avoided.
In the majority of cases, your beans will use TRANSACTION_SERIALIZABLE as the isolation level. Once the application has been in production for a while and there is a need for serious fine-tuning for performance, this is one of the parameters that should be considered. Of course, your application determines how far you can go in setting isolation levels. Read-only transactions that publish information can be interleaved, while transactions that update data need more thought Keep in mind that not all databases support all isolation levels, even though they might appear to be accepted by the JDBC driver of choice.
Page 44
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.5.2 Working with Oracle in Transactions Oracle automatically uses different types of locks to control concurrent access to data. It automatically locks a resource on behalf of a transaction to prevent other transactions from doing something - requiring exclusive access to the same resource. Oracle's default locking mechanisms lock data at the lowest level of restriction to guarantee data integrity while allowing the highest degree of data access concurrency. 2.5.2.1 Lock Duration All locks acquired by statements within a transaction are held for the duration of the transaction, preventing destructive interference from concurrent transactions. All locks obtained by SQL statements in a transaction are released, as soon as the transaction is committed or rolled-back. 2.5.2.2 Row-Level Locks The only data-lock obtained automatically by Oracle is Row-Level lock. This means that operations lock only rows of data that they manipulate, and do not globally lock tables. 2.5.2.3 Read Operations (SELECT) SQL Select statements do not acquire data locks at all. Therefore, other transactions can query and update a table beeing queried, including specific rows being queried. Since Select statements do not block any other transaction, this is refered to as nonblocking query. A Select operation is also not blocked by any other transaction. If a select operation accesses locked rows, it will never wait. (unless a SELECT FOR UPDATE query is issued). In Oracle, select operation does not block and are never blocked. 2.5.2.4 Data Manipulation Operations ( UPDATE, INSERT, DELETE) A transaction acquires an exclusive data lock for each individual row modified by one of the following statements: INSERT, UPDATE, DELETE, and SELECT with the FOR UPDATE clause. That means that any other transaction will not be able to update these rows, and will block until the first transaction commits or performs a rollback. As specified in the previous section, read operations done by other transactions will not be blocked. Transactions with UPDATE, INSERT, DELETE and SELECT…FOR UPDATE operations will block any other transactional UPDATE operation refering to it’s affected rows.
Page 45
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.5.2.5 Summary The following table summarizes the above discussion. All operations are assumed to be transactional. Scenario
Possible
Reader blocks Readers
No
Reader blocks Writers
No
Writer blocks Readers
No
Writer blocks Writers for other rows
No
Writer blocks Writers for same rows
Yes
2.5.2.6 Oracle’s Transaction Isolation Levels Oracle supports two SQL92 isolation levels: Read-Commited (the default) and Serializable. A Serializable transaction offers better data isolation than a Read-Commited one, but this does not come for free: a Serializable transaction reduces data-access concurrency level, and therefore may significantly degrade performance if overused. After one determines that a specific operation needs isolation from other operations, it is necessary to state which isolation level the operation will use. It is important to note here, that transactions of both isolation levels share the same locking strategy (perform locking identically).
2.5.2.6.1 Read-Committed This is the default transaction isolation level. Each query executed by a Read-Committed transaction sees only data that was committed before the query (not the transaction) began. In other words, in a Read-Committed transaction, Oracle will create a different snapshot of committed data before every query in the transaction. Thus, the Oracle query will never read dirty (uncommitted) data. A “query” here means either explicit (such as SELECT) or implicit (such ones carried out by UPDATE…WHERE, DELETE…WHERE and INSERT with sub-query). However, because every query is performed with its own snapshot of data, and because Oracle does not prevent other transactions from modifying the data read by a query (see locking), that data may be changed by other transactions between two queries in the transaction. Thus, under this isolation level, a transaction that executes a given query twice, or two consecutive queries referring the same data, may experience both nonrepeatable and phantom reads. If a Read-Committed transaction T1 blocks another Read-Committed transaction T2 (T2 tries to write to a row locked by T1), then when T1 is either committed or rolled-back, T2
Page 46
J2EE Design Considerations for WebLogic Server ___________________________________________________________ will override changes done by T1. The database will allow such overriding without any notification. This allows better transactional throughput (no work needs to be rolled back and redone if such conflict occur), but may compromise data consistency. Read-Committed isolation level should be the default transactional setting for environments where few transactions are likely to conflict. 2.5.2.7 Serializable Serializable isolation permits concurrent transactions to make only those database changes they could have made if the transactions had been scheduled to execute one after another. Specifically, Oracle permits a serializable transaction to modify a data row, only if it can determine that prior changes to that row, which were made by other transactions, were committed when the serializable transaction began. For clarity, let’s consider the following example: A serializable transaction T1 is blocked by another transaction T2 (either serializable or read-committed) for a specific row. If T2 rolls back, T1 will update the locked row and proceed. However, if T2 successfully commits, T1 will get the following exception: “Cannot serialize access for this transaction”. When such an exception is caught, the transaction should be rolled back, in order not to leave the database in an inconsistent state. This may cause considerable loss of work, and thus significantly reduce transactional throughput. Serialized transactions detect possible serialization conflicts, and notify client code about such conditions. This makes it possible for an application to monitor and rollback the conflicting operation. Another difference between serializable transactions and read-committed transactions, is that all queries in the transaction share the same consistent data snapshot, taken before the transaction began. This means that queries done in a serilizable transaction will not be exposed to nonrepeatable and phantom reads. If you explicitly or implicitly query the same data multiple times in the same transaction, and have to get complete consistency between queries, you should use Serialized isolation. Serializable mode is probably not the best choice for relatively long transactions that must update the same rows accessed by a high volume of short update transactions. Because a longer running transaction is unlikely to be the first to modify a given row, it will repeatedly need to roll back, wasting work. 2.5.2.8 Comparison The following table compares the important factors of the two isolation levels.
Page 47
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Factor
Read-Committed
Serializable
Locking Strategy
Only same-row writers block
Only same-row writers block
Dirty Reads
Not Possible
Not Possible
Dirty Writes
Not Possible
Not Possible
Non-Repeatable reads
Possible
Not Possible
Phantom reads
Possible
Not Possible
Snapshot time
Before each query in the tx begins
Before the tx begins
Exception after blocking tx commit
No
Yes
Exception after blocking tx rolls-back
No
No
2.5.3 EJB Transactions Management The following sections provide general design guidelines for transaction demarcation in the EJB framework. 2.5.3.1 General approach The preferred method of transaction demarcation is to use the service provided by the container. Consider programmatic transaction demarcation only in cases where you absolutely have to do so. These cases will be detailed below. Use Container Managed Transactions as a preferred demarcation technique. Remember that in any case entity beans cannot demarcate transactions programmatically. 2.5.3.2 Transaction Control Client code may not start transactions. This may significantly complicate development if Web tier will be separated from EJB tier. Transactions will be started, committed or rolled-back at EJB service layer. 2.5.3.3 Number of involved beans Try not to enroll many beans in a single transaction scope. Since WebLogic employs pessimistic object locking this may result in performance bottlenecks and possible deadlocks. Increased memory consumption is also possible, since all entity beans enrolled in a transaction will reside in the cache.
Page 48
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Try to minimize number of beans that participate in a single transaction scope. Wrap access to several entities in a single transactional workflow operation, only if operation’s atomicity is important. 2.5.3.4 Duration Try to keep transactions as short as possible. The reason is that as long as a transaction is active, server resources cannot be used to serve other clients. 2.5.3.5 Should an EJB Service be Transactional? There are two basic questions that we need to ask before we can dictate whether a service, published by an EJB component, needs to be transactional: • •
Does the service have atomicity requirements? Should data manipulations done by the service be isolated?
If the answer for either question (or both) is yes, the service needs to be transactional. Isolation level of the transaction will be determined by other considerations. 2.5.3.6 Atomicity Requirements A service needs atomicity support if it contains multiple data manipulation queries (UPDATE, INSERT or DELETE ). If an error occurs in the middle of the transaction, when only part of the manipulations were performed, we would like to reverse the effect created by these manipulations, effectively keeping the database in a consistent state. It is important to note that services that issue only SELECT queries impose no atomicity requirements. This is true also for services that perform a single data manipulation. Atomicity is required only by EJB services that issue multiple data manipulation queries. These services need to be transactional. 2.5.3.7 Isolation Requirements The first thing to do when investigating isolation requirements for an EJB service, is to analyze the acess to the data manipulated by the service. If there is no other source that may access that data, no isolation is required. If other sources may access the data, but only read it, no isolation is required. The only interesting concurency ( when Oracle is the database ) is if at least two different sources may try to maipulate the same data at once. An EJB services which manipulates (writes) data, which is also manipulated by another service, needs to be transactional.
Page 49
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.5.3.8 Transactional Isolation for EJB Services Once it is determined that a service needs to be transactional, it is required to determine it’s isolation level. You should follow these guidelines:
• Short, fine-grained updates are operations that update a specific (single) business entity. This update may be done by issuing one or several UPDATE statements. These transactions are relatively frequent, and are short in duration. Another observation is that such operations will rarely block eachother. Such operations will default to Serializable isolation.
• Long, batch updates are operations that update several business entities. These transactions are non-frequent, and are long in duration. There is a probability that such operations will collide with fine-grained updates. It is unlikely that a batch update will block a fine-grained update. It is more likely that a fine-grained update will block a batch update. Such operations will default to Read-Committed isolation. When batch update are blocked by a fine-grained update, the batch transaction will not roll back even if the short transaction commits. In this manner, we increase the transactions throughput, since we don’t need to rollback a lengthy operation. On the other hand, if a short update is blocked by a batch update, the short update will be rolled back if the batch update commits. The user should be notified about operation failure. 2.5.4 Default Transactions Setting This section will dictate the default transactions setting for various operations in WLS applications. Use these settings as a baseline for determination of transactional settings for various operation types. Deviations from these rules should be explained on a percase basis. 2.5.4.1 Retrieve Operations These operations include fine-grained and batch retrieves. They may issue any number of SELECT queries to any table in the database. These operations do not require atomicity (since no update is issued), and, in most cases, need no isolation from other operations. Thus, in the vast majority of cases, these operations need not be transactional at all. Default setting for any retrieve operation is: TX_NOT_SUPPORTED. An exception to this rule is when there is a possibility that another transaction may update the data when read, and the data is mission critical (means that it should be always presented in it’s most accurate state) . In this case, you would probably want to make the read operation transactional.
Page 50
J2EE Design Considerations for WebLogic Server ___________________________________________________________ If mission critical data might be changed when read, use the following transactional settings: TX_REQUIRED with READ_COMMITTED isolation. 2.5.4.2 Fine grained updates These operation update specific (single) business entity. This update may be done by issuing one or several UPDATE statements, and one or more SELECT statements. By default fine grained updates should use the following transactional settings: TX_REQUIRED with SERIALIZABLE isolation. 2.5.4.3 Batch updates These operations update several business entities. They may issue any combination of SQL statements. They include all long, complex, workflow operations. By default batch updates and workflow operations should use the following transactional settings: TX_REQUIRED with READ_COMMITTED isolation. 2.5.4.4 Summary The following table summarizes default transactions settings: Operation Type
Transactional
Isolation Level
Fine-Grained retrieve operation
No
NA
Batch retrieve operation
No
NA
Mission-critical data retrieve operation with possible concurent writer
Yes
READ_COMMITED
Fine-grained update operation
Yes
SERIALIZABLE
Batch updates and workflow operations
Yes
READ_COMMITED
2.5.5 Deadlocks Deadlock situation may arise when two or more transactions are waiting for data locked by each other. Oracle automatically detects deadlocks situations, and resolves them by rolling-back one of the statements involved in the deadlock, such that a set of conflicting row-locks is released. In general, deadlocks occur infrequently in Oracle. Most deadlocks will occur as a result of transactions explicitly overriding default locking of Oracle. To minimize the chance for a deadlock, all operations need to manipulate data in the same order. If two
Page 51
J2EE Design Considerations for WebLogic Server ___________________________________________________________ transactions update data in Table A and in Table B, it will be good if both of them will issue their updates in the same order (i.e., first Table A, then Table B).
Page 52
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.6 Security 2.6.1 Overview There are several basic concepts associated with securing distributed systems. Each of these has a role in systems design and architecture, although they are not broadly applicable to every application. It is the designer’s role to determine the relevance of each of these topics to the specific application. The intention of this section is not to be a thorough discourse on the various security issues but rather introduce the topics in the context of their relation to WebLogic Server. In addition, there is some additional information on security in other sections: EJB, JMS, etc. For more detail, an excellent review of general security and Java can be found at http://www.javaworld.com/javaworld/jw-04-2000/jw-0428-security_p.html •
Authentication – Verifying the identity of clients, servers, or system components. Authentication is addressed in WebLogic Server via the WebLogic Realm, including authentication by the weblogic.properties file, LDAP, RDBMS, Unix, Windows NT Registry, and an open API for custom realms.
•
Authorization – Controlling the access to system resources. Authorization is typically represented as an Access Control List (ACL), detailing the services or objects a particular user or group of user can access. ACLs can be placed on various distributed services or components, including EJBs, RMI objects, methods within these objects, URLs or URIs, etc. In the current release of WebLogic Server, authorization is defined in the weblogic.properties file.
•
Auditing - Collecting, storing, and distributing the record of successful or failed operation requests.
•
Confidentiality - Preventing the disclosure of information to unauthorized parties. Some form of encryption provides confidentiality to the application information and data exchanged between application components in a distributed system. WebLogic Server relies on Secure Sockets Layer (SSL) for confidentiality.
•
Integrity - Preventing the accidental or malicious data corruption, or the tampering with system’s configuration or operation.
•
Non-repudiation - Binding the originator’s identity to specific operation request, with later verification proof by third party. Non-repudiation implies that transactions are authenticated users, are authorized to access these services,
Page 53
J2EE Design Considerations for WebLogic Server ___________________________________________________________ the transactions are actually completed, and can be verified by a third party (e.g. for legally binding contracts or transactions). 2.6.2 Authentication 2.6.2.1 WebLogic Realms Typically customers want to store security information in something other than the weblogic.properties file so that they have a reasonably manageable solution. WebLogic provides a number of "realms" to allow different types of security datastore. In selecting a realm the main consideration is whether one wants to store access-control as well as authentication information. Only the RDBMS realm - apart from weblogic.properties - supports both of these and this generally means that many customers choose this. The other alternative is for customers to develop their own custom realm to access some non-standard security datastore. Whatever is chosen it is important to use the realm mechanism so that security vulnerabilities are not introduced via custom security solutions. 2.6.2.2 Context Propagation Many customers would like users to authenticate themselves once and for that information to be propagated to components within the system - for instance from Servlets to EJBs. In order for this to work correctly it is important that developers use the security support built into WebLogic Server. In particular J2EE Web Applications provide good facilities for a user to authenticate themselves once with the WebLogic environment and for their identity to be propagated to other WebLogic components. 2.6.2.3 Single Sign-on Single sign-on allows a user to satisfy a single authentication challenge – e.g. provide a password – and have that validation be shared by all applications accessed by the user. The user authenticates once, even if the underlying applications use disparate security components, systems, or databases. Single sign-on can be implemented using 3rd party security solutions, enforcing a common security architecture across all applications and components, and through custom-coded solutions. The realm capability in WebLogic Server enables J2EE and EJB applications to integrate with a designated single sign-on service but does not provide that service and does not enforce single sign-on across disparate applications. The WebLogic realm defers authentication of WLS-based objects, components and objects to an external security service; in the case of single sign-on, the external service is the common security
Page 54
J2EE Design Considerations for WebLogic Server ___________________________________________________________ architecture or 3rd party solution. The application designer must enforce a common authentication service on all applications under the single sign-on umbrella. 2.6.3 Authorization WebLogic Server only supports access-control based authorization, it does not support policy-based authorization. Customers requiring this sort of sophistication in their security solution should look to 3rd-parties with these sort of features. 2.6.4 Encryption 2.6.4.1 40 and 128 bit encryption WebLogic Server supports both 40 and 128 bit encryption for SSL. Customers that require higher levels of encryption than that provided by 40 bit should investigate 128 bit options. 2.6.5 JAAS The Java Authentication and Authorization Service (JAAS) framework supplements the Java 2 platform with user-based authentication and access control capabilities. JAAS is a standard extension to the Java 2 Software Development Kit, v 1.3. WebLogic Server incorporates portions of the JAAS specification in the WLS 6.0 release. 2.6.6 Balancing Security & Performance No system is completely secure. As companies, data, and applications become more distributed there is greater risk to exposure and application compromise. Business goals to extend services and products to customers, especially over the Internet, must be weighed against the exposure to an organization of easing access to valuable information and corporate data. The challenge becomes to balance protection of corporate assets with the business requirements. To authenticate, authorize or encrypt uses processing time. As with everything in life, there is trade-off. With the security realms, WebLogic has tried to optimize the trade-off between security and performance. Authentication should occur once per user. Therefore it is acceptable to call a remote process to authenticate. However, authorization may occur for each and every object invocation (Servlet, EJB, JMS, JTS, JDBC, etc…). Therefore, authorization should not require a remote call – this is WebLogic’s default behavior.
Page 55
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.7 JDBC 2.7.1 Overview Since database drivers are in a transition between JDBC 1.2 and 2.0, this section focuses on explaining the functionality and the specification and WebLogic’s support. The JDBC 1.2 API is expressed as a series of abstract Java interfaces that allow an application developer to open connections to particular databases, execute SQL statements, and process the results. The most common classes are: Connection, Statement, ResultSet. Stored procedures are also supported. The JDBC 2.0 API supports more advanced features typical of an application server: DataSource, Connection Pooling, Advanced Data Types (BLOB, CLOB), Batch, Scrollable ResultSet, RowSet and XA transactions. With WebLogic 5.1, all JDBC drivers support the JDBC 1.2 API. Also the DataSource and Connection Pooling is supported for all drivers. Only the jDriver for Oracle supports BLOB, CLOB, Character Streams and Batch. Scrollable ResultSet, RowSet and XA transactions are not supported in the current release. 2.7.2 DataSource A DataSource object provides a new way for JDBC clients to obtain a DBMS connection. To create a DataSource object you define it with an entry in the weblogic.properties file. This DataSource entry then points to a connection pool that is also defined in the weblogic.properties file. DataSource objects can be defined with or without Java Transaction Services (JTS) enabled. Creating a DataSource object with JTS enabled causes the connection to behave like a JTS connection, with support for transactions. 2.7.3 Connection Pooling A set of resources has one common characteristic: there's a limited supply. Usually the supply limitation isn't related to the scarcity of the resource, but to the difficulty of obtaining it. For example, it's possible to open a database connection for each query, but it's a time-consuming operation. It's assumed that these resources (e.g. database connections, threads, EJB instances) will be needed by different parts of an application that will "compete" for them according to some application logic. Each individual resource can be used an unlimited number of times. In the context of WebLogic, this translates into infrastructure that:
Page 56
J2EE Design Considerations for WebLogic Server •
___________________________________________________________ Contains a pool of resources to be managed
•
Supplies the needed resource on demand
•
Denies the resource if none are available
•
Exercise some policy on resource availability including queuing, waiting, and so on
WebLogic’s threading model lends itself nicely to shared access to resources.1 While it is possible for the developer to create and manage pools directly – this is not advisable since the container already takes care of much of this functionality. Besides, a developer would have to take care of a lot of implementation details (careful synchronization is one example) to produce a resource pool for production-level heavy lifting Resource pooling is most frequently used for database connections. For the purposes of this discussion, the database connections are JDBC connections established in the JDBC Connection Pool. Establishing a connection to a database is an expensive operation – especially so, at runtime, since each connection can take up to a second to set up. Because of this, the traditional way of handling database connections from a client is to establish a connection between the client and the database when the client application starts – and maintain the connection till the client ends. This is a costly architecture because you need as many connections as active clients, and worse still, the connection is not being used efficiently, since the interaction with the database is intermittent and the connection is almost always idle. A more efficient alternative is to use connection pools. The idea is that a predefined number of database connections are established and then made available to the clients when needed. As the connection has already been established, a connection is immediately available when the client requests one. When the client is done with the connection, it is not dropped but returned to the pool to make it available to other clients. A connection pool has many performance and availability advantages. Reusing a connection from a pool is far more efficient than creating a new connection for each client each time. You do not hard-code details such as the DBMS instance, table, user, password, etc., in your application rather it is declared in a set of properties. You can limit the number of connections to your DBMS. This can be useful for managing licensing restrictions on the number of connections to your DBMS. A connection pool is dynamic. It can be created at server startup via property files entries, dynamically from within the WebLogic console or dynamically from an application. You can find more information on connection pooling in the WebLogic Documentation section on pooling. 1
. In this context we assume that resources are shared among concurrent threads, not among the operating system's processes.
Page 57
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.7.3.1 Connection Pooling Design Recommendations •
When using connection pools the correct way for the client to interact with the database is to obtain a connection from the pool every time a query or set of queries will be done and then return the connection to the pool when the set of queries is completed.
•
An important aspect of using pools is that a resource obtained from a pool must be returned after the application is done using it. Obviously, if anything prevents the return of the resource, it creates a resource leak that will eventually deplete the pool.
•
Ensure that pool size calculations take the thread execution count into consideration. For instance it typically doesn’t make much sense to maximize your thread count with a small pool.
•
With respect to JDBC connection pool size, it is always best to start low and avoid increasing the count unless you need both a high and low range.
•
WebLogic allows shrinking the size of the pool after it has been increased to meet demand. With the allowShrinking property in the WebLogic Properties file, this feature is enabled and it can be used in conjunction with the shrinkPeriodMins property to specify how many minutes it has to wait before shrinking the size of the pool.
•
It is safe to have the number of Database connections equal the executeThread count. Additionally, it might be worthwhile to have the executeThread count equal to Database connections be one or two more than the number of execute threads. This way the remaining threads can do work while the others are blocked waiting for the database.
•
Since connections in the pool are allocated on a one per transaction basis, it is possible that long-lived transactions could block the pool for a long time, meaning that you will need to increase your pool size. This has nothing to do with the number of execute thread count but must be taken into consideration. When the native performance packs are not being used, you should also take into consideration the number of threads dedicated to reading from the sockets.
2.7.4 BLOB / CLOB BLOBs or CLOBs in Oracle behave differently than other data types in regards to transactional boundaries (statements issued before a SQL commit or rollback statement) in that a BLOB or CLOB will become inactive as soon as a transaction is committed. If AutoCommit is set to TRUE, the transaction will be automatically committed after each
Page 58
J2EE Design Considerations for WebLogic Server ___________________________________________________________ command issued on the connection, including SELECT statements. For this reason you will need to set AutoCommit to false if you need to have a BLOB or CLOB available across multiple SQL statements. You will then need to manually commit (or rollback) the transactions at the appropriate time. 2.7.5 Batch updates The batch update feature allows an application to submit multiple update statements (insert/update/delete) in a single request to the database. This can provide a dramatic increase in performance when a large number of update statements need to be executed. The Batch update feature is available in the Statement interface and requires the use of SQL statements that return an update count and do not return a result set. Using Batch updates with the CallableStatement or PreparedStatement is not supported. 2.7.6 Scrollable ResultSets The JDBC 2.0 scrollable result set allows for more flexibility by providing both forward and backward movement through their contents. In addition, scrollable result sets allow for relative and absolute positioning. The JDBC 1.2 result set only allows forward scrolling. 2.7.7 RowSet As its name implies, a rowset encapsulates a set of rows. An example of a rowset is where you have a large list of data and you only want to work with a small portion. A rowset may or may not maintain an open database connection. When a rowset is ‘disconnected’ from its data source, updates performed on the rowset are propagated to the underlying database using an optimistic concurrency control algorithm. Rowsets add support to the JDBC API for the JavaBeans component model. A rowset object is a bean. A rowset implementation may be serializable. Rowsets can be created at design time and used in conjunction with other JavaBeans components in a visual builder tool to construct an application. 2.7.8 XA Transactions In order to support distributed transactions, a JDBC driver vendor must implement the javax.sql.XADataSource and javax.sql.XAConnection. Support for distributed transactions is an included feature in WLS 6.0.
Page 59
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.7.9 Transactions The Java Transaction Services or JTS driver is a server-side Java Database Connectivity (JDBC) driver that provides access to both connection pools and SQL transactions from applications running in WebLogic Server. Connections to a database are made from a connection pool and use a two-tier JDBC driver running in WebLogic Server to connect to the Database Management System (DBMS) on behalf of your application. Once a transaction is begun, all of the database operations in an execute thread that get their connection from the same connection pool will share the same connection from that pool. These operations may be made through services such as Enterprise JavaBeans (EJB), or Java Messaging Service (JMS), or by directly sending SQL statements using standard JDBC calls. All of these operations will, by default, share the same connection and participate in the same transaction. When the transaction is committed or rolled back, the connection will be returned to the pool. 2.7.10 Other JDBC Design Recommendations Since you can use JDBC from either entity or session beans, it is important to understand when each technique is appropriate. Since these guidelines are biased towards a stateless server, the answer is simple, and is related to modeling criteria and to caching restrictions in a clustered environment: As much as possible use JDBC from stateless session beans. Stateless session beans are preferred over RW entity beans because they are light-weight, efficient, easily scalable, provide high transactional throughput and can generate the most effective SQL. Use JDBC from Read Only entity beans to load information, if data can be modeled using such a component. Use JDBC from RW entity bean only when you need to cache large, dynamic data structure. The bean will utilize JDBC to load data from the database, and then populate a JNDI bound data object. On passivation, the bean will use JDBC to persist the bound object to the database. By using EJB and JMS, you can often get a more useful abstraction than you can get by using JDBC directly in an application. WebLogic EJB and WebLogic JMS rely on connections from a JDBC connection pool to load and save persistent objects. Sometimes it is more convenient to use EJB and JMS, instead of using JDBC. For example, using an enterprise bean to represent a data object allows you to change the underlying store later without modifying JDBC code. If you use
Page 60
J2EE Design Considerations for WebLogic Server ___________________________________________________________ persistent JMS messages instead of coding database operations with JDBC, it will also be easier to adapt your application to a third-party messaging system later.
Page 61
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.8 Java Mail API - Asynchronous Processing and Results Notification JMS is normally the technology of choice for transmitting messages between loosely coupled services or components. In a very short period of time, it has become sort of the "Britney Spears" of most Java-based messaging backbones. Surrounding it are hoards of screaming fans (a.k.a J2EE developers), snapping up every juicy tidbit about their new pop culture icon. This section of the document looks at an alternative messaging mechanism that is "tried-and-true", but often overlooked. The alternative mechanism is JavaMail API: The "Aretha Franklin" of Asynchronous Messaging. 2.8.1 JavaMail API: The "Aretha Franklin" of Asynchronous Messaging Like Aretha, the JavaMail API is "old school". It doesn't appear as often on the cover of the Java tabloids as JMS, but it can still belt out a great hit or two! These next couple subsections explore some areas where the JavaMail API is still the undisputed "Queen of Asynchronous Messaging"! For fun, we'll be presenting these areas under the guise of a few of Aretha's greatest hits. 2.8.1.1 R-E-S-P-E-C-T (circa 1967) The [JavaMail API] can be loosely thought of as an object-oriented wrapper around the standards-based messaging protocols- SMTP, POP3 and IMAP. SMTP is used for sending e-mail, while POP3 and IMAP are used for receiving it. Of the three, SMTP and POP3 are probably the easiest to use and understand. From a J2EE perspective, SMTP is probably more frequently used. It is pretty common place to find Servlets or EJBs that use the JavaMail API to send email to the e-mail address a customer provided on a registration screen. Not extremely imaginative, but a R-E-S-P-E-C-T-A-B-L-E usage none the less. It is pretty easy to work with the JavaMail API from within WLS. All you need to do is:
• Download (or obtain) a copy of the mail.jar and activation.jar files from Sun, and
• Add the mail.jar and activation.jar files to the CLASSPATH variable WLS uses when it starts up, and
• Add the necessary import javax.mail.* entries to the Servlet or EJB you want to send and receive e-mail messages from, and
Page 62
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • Write the code that uses the API interfaces and classes to create, send and/or receive the desired e-mail messages. WLS does not have anything "special" in it to make it work or not work with the JavaMail API. It does have the following classes that have something to do with e-mail, but they are not part of the JavaMail API:
• weblogic.utils.MailUtils This is a utility class that uses the weblogic.common.internal.SmtpClient class to send an e-mail message.
• weblogic.common.internal.SmtpClient This class basically encapsulates the SMTP protocol. It completely shields the WLS developer from the details associated with using the SMTP protocol to send an e-mail message. 2.8.1.2 Rock Steady (circa 1969) Next, we'll look at a more ambitious use of the JavaMail API from within WLS. Let's suppose you have a client that needs to send an XML-ized version of its parts catalog to a group of interested businesses, whenever something changes. The client is providing this service for free, so things like guaranteed one-time delivery are not required. Adding to this: Some of the businesses interested in the XML-ized catalog don't currently use Java technology. All of their "outside the firewall" stuff uses Microsoft's ASP technology and their "behind the firewall" stuff uses MTS and MSMQ. Some of the businesses interested in the XML-ized catalog have IT restrictions that prohibit the use of any protocol other than HTTP and SMTP, outside the firewall. The client doesn't have the resources (time, money or skill set) to do a really robust JMSbased solution.
Page 63
J2EE Design Considerations for WebLogic Server ___________________________________________________________
Figure 2-3 High Level Architecture for JavaMail-based Catalog Distribution Service (one-way) In this hypothetical (but realistic) scenario, JMS is clearly not going to be an option. The JavaMail API provides a viable alternative that knows all about the RFC822 and MIME Internet standards. On the sending side, your client can use the JavaMail API in a Servlet or EJB to send the XML-ized catalog to a list of recipients. On the receiving side, the email Inbox acts like a JMS queue or topic. The recipient simply uses an e-mail API to read the e-mail messages (the XML-ized catalog) from the Inbox and process them. Admittedly, this can be categorized as a "poor man's" JMS, but it does in fact satisfy all the requirements. 2.8.1.3 Freeway of Love (circa 1986) If the Internet is the "freeway of love", then WLS can easily be seen as the pink Cadillac you want to drive on it. In this section, we look at using the JavaMail API in concert with the other J2EE-based technologies provided by WLS. The following table describes some hypothetical (but realistic) WLS-based solutions that can be designed and built using the JavaMail API, in concert with other J2EE-based technologies.
Page 64
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Solution
J2EE Technologies Used
Synopsis
Personalized Alerts
JavaMail, JMS, EJB, JDBC
This solution allows a client to provide its customers with personalized e-mail alerts. The J2EE components (running on WLS) in the solution send application events to a JMS topic that is subscribed to by a Message-Driven EJB. The Message-Driven EJB then uses the JavaMail API to send an e-mail message to the e-mail address of the client's registered users. The e-mail addresses are obtained from a database using JDBC.
Distributed Computation
JavaMail, JMS, EJB
This type of solution uses multiple nodes to solve a larger problem by breaking it up into discrete tasks that run on disparate nodes. Normally, these tasks don't share state but this is not guaranteed. For our hypothetical solution, these tasks are multipart/related MIME e-mail messages. Some body parts are XML-based service requests and others are attachments that are base64encoded, binary data. The caller wants these service requests to be processed as a group, in the order they appear as body parts. If there is a failure during the processing of any of the service requests, the caller wants to: Get a notification (via e-mail, of course) containing the reason for the failure, and Cease processing of subsequent service requests in the other body parts. The service requests are operations that don't require transactional semantics, because the final service request is the only one that attempts to commit anything. If a service request fails, the caller simply attempts to fix the problem and resubmits a new e-mail message.
Page 65
J2EE Design Considerations for WebLogic Server ___________________________________________________________ The J2EE components (running on WLS) use the JavaMail API to send and receive the e-mail messages between nodes. Message-Driven EJBs might be used to parse and process received e-mail messages. Other EJBs can be recruited to handle the construction and submission of e-mail messages. Servlets and EJBs are used to implement other functionality required by the solution. Offer Provisioning
JavaMail, Servlet, JSP, JDBC, EJB
This solution allows a client to use their customer's e-mail clients (e.g. Outlook, Eudora, etc.) as the client-side of dynamic offer provisioning services. Offer provisioning services are things like DSL sign-up, special-purpose promotions, etc. These usually come in the form of HTML pages with HTML form elements (i.e. text fields, radio buttons, etc.) that the customer manipulates and then clicks a Submit button. The J2EE components (running on WLS) create the HTML pages using information retrieved from a database via JDBC, or contained in XML documents located on the file system. JSPs and Servlets are used to create the HTML pages. Servlets are used to process the HTTP POST request sent when the Submit button is clicked. EJBs are used to persist the information assigned to the HTML elements in the HTML page.
Page 66
J2EE Design Considerations for WebLogic Server ___________________________________________________________
Figure 2-4 High-Level Architecture for JavaMail-based Distributed Solutions (bidirectional) 2.8.1.4 Fade to Black Most e-mail clients are able to handle HTML and attachments, so with a little imagination, one could use the JavaMail API to design some pretty sophisticated (and dynamic) services-based offerings on top of WLS. But as it is with most technologies, the JavaMail API has limitations that make it unsuitable for some solutions. Advantages The following bulleted-list presents some of the key advantages to using the JavaMail API from within a WLS-based solution:
• Receiver doesn't need JMS This is significant for shops that prefer to use non-J2EE environments like CORBA or Microsoft's MTS and MSMQ products.
Page 67
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • Support for encrypting/signing messages Security is always an issue, so it is nice to know that you can leverage (or complement) the encryption/signing facilities of the JavaMail API from within WLS.
• IT already has infrastructure in place for HA e-mail E-mail is the lifeblood of every company on the Internet. There is usually already a "99.9999% uptime" policy in place for e-mail, so you can be pretty sure that WLS will be able to successfully send and receive all the e-mail messages it needs to.
• Provides search facility for locating messages This comes in pretty handy when the message reader is an application, not a human. "Subject" field is used to an application needs
• Supports MAILBOX monitoring Again, this comes in pretty handy when the message reader is an application, not a human. It allows the class containing the MAILBOX monitor to process new messages without having to resort to polling. Limitations The following bulleted-list presents some of the limitations of using the JavaMail API from within a WLS-based solution:
• No support for transactions This can be a real showstopper for some. To them, no transaction support = not enterprise ready.
• Same message may be received multiple times This means you'll have to come up with your own mechanisms to determine when a message was previously received, if repeat processing is undesirable.
Page 68
J2EE Design Considerations for WebLogic Server ___________________________________________________________
2.9 Peripheral Topics This section of the document presents topics that are relevant in the design and implementation of J2EE-based WLS applications. 2.9.1 Smart Proxy A proxy is a software component that provides access to a resource, typically a service of some sort. The idea is to de-couple the caller of a service (the client) from the service itself. A proxy intercepts the client call and directs it to the target service, typically, according to some rules. A smart proxy is the same thing but provides more functionality (smarts) to do its job more effectively. Another term for a smart proxy is a smart stub. In WebLogic, smart stubs (also known as replica-aware stubs) enable clustering. The reason these stubs are smart is because they provide all the necessary information for failover and load balancing across multiple server environments. More specifically, a smart stub has a replica handler that determines the specific algorithms that it must use for load balancing and failover. When the invocation of a method fails, the replica handler determines if a retry should be attempted. Retries are not always necessary but when it is possible, the replica handler will chose a new server offering that specific service to handle the request. Load balancing occurs in a similar fashion. Immediately before invoking any method, the replica handler chooses a server to handle the request. The handler will not always select another server as it prefers to use what is called the “cheapest invocation” – it will try to use existing sockets or choose the server where all (or most) of the objects related to this invocation live. Another instance of a smart proxy is through the implementation of the Process-Entity design pattern. The use of this pattern enables a high degree of scalability by providing proxy access to backend services. An example of this pattern is illustrated by considering the work of a bank teller. The teller provides client access to account data for either read or update reasons. The teller takes care of processing requests to the required data. Within the context of J2EE, the Process Entity pattern is realized by implementing the teller as a stateless session bean. This bean then coordinates access to account information implemented as an entity bean(s). Thus, clients do not access the information directly, significantly reducing network connections and server resources – ultimately improving scalability. A client should rarely be allowed direct access to a data source. The reason for this is that direct access increases network traffic, compromises server performance, and promotes architectural inflexibility.
Page 69
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.9.2 Firewall / DMZ A firewall is a combination of hardware and software that restricts the type of information that can pass through it – checking known methods of attack. This generally means that communications are limited to HTTP, typically on port 80 and secure HTTP on port 443. The web server at this port could be a WebLogic Server or a third-party web server set up to proxy requests to WebLogic Server. For example, you could set up Netscape Enterprise Server, Microsoft Internet Server, or an Apache Server to serve static web pages and proxy servlet and JSP requests to WebLogic Server. Figure 4-5 illustrates the architecture.
Figure 4-5 Firewall with Web Server Gateway With this configuration, the web server is a gateway, operating in the "demilitarized zone" (DMZ). Clients interact exclusively with the web server. WebLogic Server connections come only from proxied web server requests, enhancing the security of your WebLogic Server applications and back-end resources. If you use a supported third-party web server as a gateway, you can use the WebLogic-toNetscape Enterprise Server Bridge (NSAPI), WebLogic-to-Microsoft IIS Bridge (ISAPI), or WebLogic-to-Apache Server Bridge to redirect requests to WebLogic Server. If you use WebLogic Server as the gateway, no bridge is needed to redirect to another WebLogic Server or cluster. The RMI-IIOP protocol does not usually go through firewalls without additional setup on the firewall host. This makes use of EJB clients on the Internet very limited. By default WebLogic Server stores its IP address in the HomeHandle object for EJBs. This can cause problems with certain firewall systems. If you are unable to locate
Page 70
J2EE Design Considerations for WebLogic Server ___________________________________________________________ EJBHome objects using home handles passed across a firewall, set the following property in your weblogic.properties file: weblogic.system.enableReverseDNSLookups=true When you enable reverse DNS lookups, WebLogic Server stores the DNS name of the server, rather than the IP address, in EJB home handles.
Although it may be possible to tunnel multicast traffic through a firewall, this practice is not recommended for WebLogic Server clusters. Each WebLogic Server cluster should be treated as a logical unit that provides one or more distinct services to clients of a web application. Such a logical unit should not be split between different security zones. Furthermore, any technologies that can potentially delay or interrupt IP traffic can prove disruptive to a WebLogic Server cluster, generating false failures due to missed heartbeats. 2.9.2.1 HTTP Tunneling HTTP tunneling provides a way to simulate a stateful socket connection between the WebLogic Server and a Java client when your only option is to use the HTTP protocol. It is generally used to 'tunnel' through an HTTP port in a security firewall. HTTP is a stateless protocol, but WebLogic provides tunneling functionality to make the connection appear to be a regular T3Connection. However, you can expect some performance loss in comparison to a normal socket connection. It has been optimized somewhat but because everything is encapsulated in HTTP, it is slower than non-secure communications. Under the HTTP protocol, a client may only make a request, and then accept a reply from a server. The server may not voluntarily communicate with the client, and the protocol is stateless, meaning that a continuous two-way connection is not possible. WebLogic HTTP tunneling simulates a T3Connection via the HTTP protocol, overcoming these limitations. There are two properties that you may configure in the weblogic.properties file on the server to tune a tunneled connection for performance. It is advised that you leave them at their default settings unless you experience connection problems. These properties are used by the server to determine that the client connection is still valid, or that the client is still alive.
Be sure that you really need to use HTTP tunneling. For example, if your firewall can pass IP packets through port 80, you can use the fast t3 protocol on port 80. If you
Page 71
J2EE Design Considerations for WebLogic Server ___________________________________________________________ must use HTTP tunneling to go through a firewall, http://www.socks5.com/ has a product that performs better than HTTP proxies. 2.9.3 LAN / WAN Considerations WLS is designed to operate within a LAN environment only. The reason for this is that WLS makes use of the IP multicast protocol for: •
Cluster-wide JNDI updates. All servers use multicast to announce the availability of clustered objects that are deployed or removed locally. Servers monitor these announcements so that they can update their local JNDI tree to reflect current deployments.
•
Cluster "heartbeats:" WebLogic Server uses multicast to broadcast regular "heartbeat" messages that advertise the availability of individual server instances in a cluster. All servers in the cluster listen to heartbeat messages as a way to determine when a server has failed.
Simple IP multicast communication requires that all subscribers to the multicast address reside on the same sub-net. For this reason, you cannot distribute members of a WebLogic Server cluster across WAN. WebLogic Server does not support WAN-level multicast tunneling. 2.9.4 Execute Thread Count The Weblogic.system.executeThreadCount value in the Weblogic.Properties file equals the number of simultaneous operations that can be performed by the WebLogic Server. As work enters a WebLogic Server, it is placed on an execute queue while waiting to be performed. This work is then assigned to a thread that does the work on it. The default value is 15. For most applications, you should leave this value unchanged. You will only see marginal benefit from increasing this value if you do not know what you are doing. If you are in doubt about this parameter, leave it at the default. Adding more threads does not necessarily imply that you will be able to process more work. Even if you add more threads, you are still limited by the power of your processor. As such, you can degrade performance by increasing this value unnecessarily. Since threads are resources that consume memory, a very high execute thread count causes more memory to be used and increased context switches. This will degrade your performance as the following explanation illustrates: Setting the executeThreadCount too high will cause too much context switching. The executeThreadCount value is more CPU related than WebLogic related, so the general rules of thumb regarding threads and CPUs apply. Assume that:
Page 72
J2EE Design Considerations for WebLogic Server ___________________________________________________________ n = executeThreadCount (number of threads) and k = number of CPUs The following scenarios are possible: 1. If (n < k) this results in an under utilized CPU, we need to increase the thread count. 2. If (n == k) that is theoretically ideal, but the CPUs are under utilized, we need to add more threads 3. If (n > k) by a "moderate amount of threads". This is practically ideal, resulting in a moderate amount of context switching and a high CPU utilization rate. Tune the "moderate amount of threads" and compare performance results. 4. If (n > k) by "many threads". This could lead to significant performance degradation as it results in too much context switching, so reduce the number of threads. For example, if you have 4 processors, then 4 threads can concurrently be running. So, you want the execute threads to be 4 + (the number of blocked threads). This is very dependent upon the application. For instance, how long the application might block on threads, which can invalidate the formula above. The value of the executethreadCount depends very much on the type of work the application does. For example, if your client application is thin and does a lot of its work through remote invocation, the time your client app spends connected will be greater than for a client application that does a lot of client-side processing, for example. If your application makes database calls that takes a long time to return, then you will need more execute threads than an application that makes calls that are short and turnover very rapidly. For the latter, you can use a small number of execute threads and improve performance. It is also important to note that when the native performance packs are not being used, some of the execute threads will be used to read from the sockets (see weblogic.system.percentSocketReaders). If your executeThreadCount is too low, you will see the following symptoms under maximum load on your server: •
CPU is waiting to do work, but there is work that could be done.
•
Can not get 100% CPU and
•
All threads are blocked and runnable when you do an execution snapshot.
If your executeThreadCount is too high, you will see the following symptoms when running the WebLogic Server under maximum load:
Page 73
J2EE Design Considerations for WebLogic Server •
___________________________________________________________ An execution snapshot shows that there is a lot of context switching going on in your JVM.
Your performance increases as you decrease the number of threads. 2.9.5 Data Caching A common task in Web applications is to cache data used by multiple objects for a period of time to avoid the overhead associated with data computation or connecting to another service. However, in a clustered environment caching becomes a tricky issue, and there are several consideration to be made. A good caching strategy is also required to reduce application’s memory consumption to minimal amount. 2.9.5.1 Cache Types A WLS J2EE application may utilizes several types of cache memory. Good design will load balance the usage of these caches according to limitation of each cache and the technical and functional requirements. The following section presents the natively available caching options in most n-tier J2EE applications. For all practical purposes, it makes sesnse to devide caching options into two groups: client-specific memory and server-side cache.
2.9.5.1.1 Client-Specific Memory Memory is available for client-specific usage on both side of the network boundary. Usage of this memory should be basically restricted to storing temporary, non-persistant state.
• Client’s browser memory can be used to store and manipulate local information for a user.
• HttpSession accessed by servlets may store conversational state on behalf of specific client on the Web tier.
• Stateful session beans may store and manipulate conversational state on behalf of specific client on the EJB tier.
2.9.5.1.2 Server-Side Cache Server-Side cache is the unified set of components and data-structure that reside in the application-server or database-server memory. Server-Side cache provides faster access to persistant information.
• Read-only entity beans can cache database information to be read by many EJB tier clients.
Page 74
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • Read-Write entity beans can cache database information to be read and manipulated by many EJB tier clients.
• The JNDI tree can serve as an in-memory data storage (similar to the sharedproperty-manager of MTS/COM+).
• Finally, the database cache is used implicitly when directly accessing database from EJB tier. 2.9.5.2 Caching Principals An important realization is that caching is a performance optimization technique. The first, no-brainer rule of every optimization is: since every optimization has a price, don’t optimize when there isn’t a need to optimize. In our case, the price of non-necessary caching is, paradoxically, performance degredation and reduced application stability. The reasons for this follows:
• Excessive replication in a clustered environment. This involves serialization and deserialization of cached objects, and transfering them over the wire to other machines.
• Saturation of application-server’s memory will degrade perfomance because of caching algorithms and activation-passivation processes. This also increases chances for out-of-memory situations and server crashes.
• Excessive garbage collector activity degrades performance. In short, it is clear that caching data when there is no gain but only pain is a bad habit. Because of that, it is necessary to understand when caching doesn’t bring value. Caching doesn’t bring much value if the cache hit-ratio is low. 2.9.5.3 Caching Criteria The discussion in the last paragraph leads to the following questions: what are the basic criteria for data to be cached on specific layer of the application? This section will try to give directions for this issue.
• In the browser, store non-persistent data that reflects the presentation state, and is frequently required to process user’s interactions. Data stored at browser memory does not hold state for client-server conversations, but is related to general state of the functionality rendered by the browser.
Page 75
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • In HttpSession store temporary, non-persistent data that is client-specific, and represents conversational state on behalf of this client. When the conversation is over, this data needs to be removed from the HttpSession. Another good candidate for session data is global state information for a user, that is frequently needed but cannot be stored on the browser (security parameters, for instance).
• In Stateful EJBs store temporary, non-persistent data that is client-specific, and represents conversational state on behalf of this client. One can load-balance usage of stateful session bean and HttpSession. On stateful session store information that is accessed in lower frequency than that stored on HttpSession. 76Please be aware that in version 5.1 of WLS there is no failover of the STATE of a stateful session bean via in-memory replication. Usually the recommendation is to keep the whole client state in the servlet/JSP session. Whether an extra JNDI lookup, and (possibly) remote access to a stateful EJB is more expensive than having a serialized lightweight Java object replicated every time, it’s hard to tell, and it can only be determined case by case. Most of the EJB gurus discourage the usage of stateful session beans and promote design patterns that use Servlet/HttpSession – Stateless EJB façade – Entity EJB
• Read-only entity beans should cache persistant data that is static, or updated with low frequency by non-EJB source. They should be used to cache data that can be accessed by many clients.
• Read-Write entity beans can cache persistant dynamic data, which can be accessed frequently or by many clients, in a non-clustered or non-transactional environments.
2.9.5.4 Caching Limitations Even in a non-clustered environment, using RW entity EJBs to cache database data may cause significant problems, if not done properly. This is because of the following reasons:
• If RW entity EJB caches non-necessary data, this may rapidly saturate the application server memory, since that data is loaded for every instance of in-memory entity EJB. Also, keep in mind that every instance of entity EJB is bound to a single database entity, which also contribute to proliferation of in-memory EJB instances. Together, this may cause out-of-memory problems and crashing of the application server, even for relatively low number of users.
• Since RW entity EJBs are bound to a specific database entity, they require bigger initial pool. That means higher initial memory consumption.
Page 76
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • Since RW entity EJBs are bound to a specific specific database entity, there is a bigger chance that their pool wil be saturated. When this happens, the EJB server starts using caching algorithms to passivate beans and activate others. This bookkeeping is expensive, and may degrade performance. This can be summarized as follows: When you use RE entity EJBs to cache and manipulate data in a non-clustered environment, make sure that you model your functionality in a proper granularity, and that you cache only data that has to be cached. Using RW entity EJBs to cache data in a clustered WebLogic environment doesn’t make much sense. Since the database is always shared in such an environment, every transactional method of the bean will load it’s state from the database, and write it back when method ends. This will effectively diminish the whole purpose of caching, and will degrade performance significantly. If you expect to cluster your application, do not use RW entity beans to cache dynamic data.
If you use JNDI to cache dynamic information on the EJB tier, keep in mind that this has a price. In order to facilitate fail-over of in-memory data-structures, WebLogic will automatically replicate the state of JNDI bound objects in all cluster’s instances. That means serialization and multicasting on every change to the bound object’s state. If the data is large enough, this may cause significant performance degradation.
If your environment need to support automatic fail over , limit the size of objects you bind to JNDI tree. Otherwise, you can expect significant performance degredation. The threshold for object size depends on the frequency of manipulations and on the number of cluster instances. As a rule of thumb, in a fail-safe homogeneous cluster do not exceed 50K for such im-memory structures.
If your applications uses HttpSession to store state on behalf of clients, and you expect to provide automatic fail-over for your Web tier, make sure that you limit the size of objects stored in it. This is due to heavy price of in-memory (or JDBC persistency) required for fail-over support. If your Web tier need to support automatic fail over , limit the size of objects you store in HttpSession to 50K.
Page 77
J2EE Design Considerations for WebLogic Server ___________________________________________________________ 2.9.5.5 Cached attributes When you model functinality as an entity EJB, every logical attribute your entity declare has a memory price. This paragraph presents rules for declaring logical attributes in your entity beans.
• Designer should strive not to cache entity attributes, which tend to have large, unpredictable volume.
• Create fine-grained cached attributes. Large, serialized blobs of cached data tend to be non-efficient regarding to database access, since every change to small part of the cached data will create significant data-stream to the database. This restriction is less important if modifications the cached data is relatively non-frequent.
2.9.5.6 Preferred Caching Approaches This section presents preferred caching solutions, based on the information provided in previous paragraphs.
• Static, or low-frequncy updated information, shared by many clients, or frequently accessed by single client, should be modeled as a read-only entity EJB.
• If you store temporary information in the HttpSession, and your data size may temporarily exceed 50K, create a stateful-sesion EJB on behalf of your client in the EJB tier, and store the data there. Hold a handle to the stateful session in the HttpSession.
• When fail-over may be compromized in a clustered environment, caching large, dynamic data structures should be done by binding serializable data-cache to a JNDI srvice. To prevent performance problems, override automatic replication when binding the data-cache. This cache should be managed through a RW entity bean. Use container callbacks ejbActivate() and ejbPassivate() to bind and unbind the cache, and ejbLoad() to build cache data.
• When fail-over may not be compromized in a clustered environment, caching large, dynamic data structures should be privded by a dedicated cache server, utilizing highavailability hardware.
Page 78
J2EE Design Considerations for WebLogic Server ___________________________________________________________ • When fail-over may not be compromized in a clustered environment, cache samll or relatively static data structures by binding data-cache to JNDI tree, with default replication settings
• Load-balance between database cache and application-server memory. Remember that database stores lately fetched data in its own cache, and that the latency between bringing data from this cache and bringing it from application-server memory is relatively small. (It is unbelievable but known, that people have developed database applications even before entity beans became part of our everyday lives).
Page 79
J2EE Design Considerations for WebLogic Server ___________________________________________________________
3.0 Appendix A – Using JMS with MQ Series - Sample Code The following sample code is based on a posting in the BEA WLS newsgroup, regarding support for foreign JMS providers. The code here was modified to run on the server side. There are many ways that the code could have been modified – a startup class with all of the code, a servlet, multiple RMI objects with more functional methods, an EJB, etc. The sample listed below chose to simply put the code in a startup class (with more ambitious changes left as an exercise for the reader). Running this example requires the 5.2 version of MQSeries JMS, which supports JMS JTA/XA. This latest version of the SupportPac depends on a jar file that you will have to obtain from Sun at http://www.java.sun.com/j2ee/download.html#connectorspec This page contains several tables, the relevant one being the "J2EE Connector Specification" from which you need the 'continue' button in the row marked "Download class file". This should provide you with a zip file containing connector.jar. The jar file should be extracted from the zip into the <ma88 install dir>/lib directory after installing the new release of MA88 and must be added to the CLASSPATH. This note assumes that you will look at the prior note for more details for setting up the application and discusses only the differences. (editor note: looks like the “note” referred to here is listed in the WLS newsgroup entry, dated 9-March-01 entitled “WebLogic 6.0 MQSeries – JMS”) To create an XAQueueConnectionFactory in MQSeries JMS, run JMSAdmin DEFINE XAQCF(myXAQCF) END Change config.xml to add the startup class for the server as follows: <StartupClass Name="JMSStartUp" ClassName="JMSStartUpImpl"/>
Targets="myserver"
Attached are two example files, JMSStartUp.java and JMSStartUpImpl.java. Create these files and generate the class files as follows. javac JMSStartUp.java JMSStartUpImpl.java java weblogic.rmic -nomanglednames JMSStartUpImpl
Page 80
J2EE Design Considerations for WebLogic Server ___________________________________________________________ Copy the resulting class files into a directory that is in the CLASSPATH. Upon booting the server, the startup class will be run. It will cause the MQSeries JMS XAResource to be registered. The program logic is similar to the earlier note except that all send and receive operations are bracketed by a begin/commit pair. Note that you can turn off the JTA processing by changing the runtrans boolean to be set to false. When the JMSobject is created, the processing looks queue connection factory returned from JNDI to see if it is the XA variant or not. It will only use the XA methods when the XA variant is used for MQSeries; it will never happen for WLS JMS (nor need it to use XA). Finally, let me say that only minimal testing has been done on this combination. Further study is needed to see if there are other limitations, particularly with respect to threads (which might have an impact its use in EJB's). Attachments:
File JMSStartUp.java: import weblogic.rmi.RemoteException; import weblogic.rmi.Remote; public interface JMSStartUp extends Remote { void dummy();
// need at least one method
} File: JMSStartUpImpl.java import import import import import import import import import import import import import
weblogic.rmi.RemoteException; weblogic.rmi.Remote; weblogic.rmi.Naming; javax.transaction.xa.XAException; javax.transaction.xa.XAResource; javax.transaction.SystemException; weblogic.transaction.TxHelper; weblogic.transaction.TransactionManager; weblogic.transaction.RollbackException; javax.jms.*; javax.naming.*; javax.naming.directory.*; java.util.Hashtable;
/** * RMI object */
Page 81
J2EE Design Considerations for WebLogic Server ___________________________________________________________ public class JMSStartUpImpl implements JMSStartUp { public static void main(String args[]) throws Exception { Naming.bind("JMSStartUpImpl", new JMSStartUpImpl()); } public void dummy() { } public static final boolean runtrans = true; private String MQqcf = "myQCF" public static final String WLSqcf = "javax.jms.QueueConnectionFactory"; public static final String MQqname = "myQueue"; public static final String WLSqname = "jms.queue.TestQueue1"; public static final String MQurl = file://localhost/d:/mqseries public static final String WLSurl = "t3://localhost:7001"; public static final String MQJNDIfactory = "com.sun.jndi.fscontext.RefFSContextFactory"; public static final String WLSJNDIfactory = "weblogic.jndi.WLInitialContextFactory";
public JMSStartUpImpl() { JMSobject MQobject = null; JMSobject WLSobject = null; TextMessage msg; TransactionManager tm; try { // Create the MQSeries connection factory, connection, session, queue if (runtrans) MQqcf = "myXAQCF"; // Use the XAQueueConnectionFactory MQobject = new JMSobject(MQurl, MQJNDIfactory, MQqcf, MQqname);
Page 82
J2EE Design Considerations for WebLogic Server ___________________________________________________________ // Create the WLS connection factory, connection, session, queue WLSobject = new JMSobject(WLSurl, WLSJNDIfactory, WLSqcf, WLSqname); if (runtrans) tm = TxHelper.getTransactionManager(); if (runtrans) tm.begin(); msg = MQobject.JMSMessage("Test String"); MQobject.JMSSend(msg); if (runtrans) tm.commit(); if (runtrans) tm.begin(); msg = MQobject.JMSReceive(); System.out.println("Received message: "+msg); WLSobject.JMSSend(msg); if (runtrans) tm.commit();
if (runtrans) tm.begin(); msg = WLSobject.JMSReceive(); System.out.println("Received message: "+msg); MQobject.JMSSend(msg); if (runtrans) tm.commit(); if (runtrans)
Page 83
J2EE Design Considerations for WebLogic Server ___________________________________________________________ tm.begin(); msg = MQobject.JMSReceive(); System.out.println("Received message: "+msg); if (runtrans) tm.commit(); } catch(JMSException je) { System.out.println("Caught JMSException: " + je); Exception le = je.getLinkedException(); if (le != null) System.out.println("Linked exception: "+le); je.printStackTrace(); } catch(Exception e) { e.printStackTrace(); System.out.println("Caught Exception: " + e); } finally { try { if (MQobject != null) MQobject.JMSCleanup(); if (WLSobject != null) WLSobject.JMSCleanup(); } catch (Exception e) { } } } } class JMSobject { private Queue ioQueue; private QueueSession session;
Page 84
J2EE Design Considerations for WebLogic Server ___________________________________________________________ private QueueConnection connection; private QueueConnectionFactory factory; private QueueSender queueSender; private QueueReceiver queueReceiver; private InitialContext ctx; private boolean xares; private XAQueueSession XAsession;
public JMSobject(String url, String jndi, String qcf, String qname) throws Exception { // Get the initial context Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, jndi); env.put(Context.PROVIDER_URL, url); env.put(Context.REFERRAL, "throw"); ctx = new InitialContext(env); factory = (QueueConnectionFactory)ctx.lookup(qcf); // Create a QueueConnection, QueueSession xares = (factory instanceof XAQueueConnectionFactory); if (xares) { connection = (QueueConnection) ((XAQueueConnectionFactory)factory).createXAQueueConnection(); XAsession = ((XAQueueConnection)connection).createXAQueueSession(); session = XAsession.getQueueSession(); XAResource XAres = XAsession.getXAResource();
Page 85
J2EE Design Considerations for WebLogic Server ___________________________________________________________ try { TransactionManager tm = TxHelper.getTransactionManager(); tm.registerStaticResource("MQSeries", XAres); } catch (SystemException s) { s.printStackTrace(); } } else { connection = factory.createQueueConnection(); session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); } ioQueue = (Queue)ctx.lookup(qname); connection.start(); queueSender = session.createSender(ioQueue); queueReceiver = session.createReceiver(ioQueue); } TextMessage JMSMessage(String text) throws Exception { TextMessage msg = session.createTextMessage(); msg.setText(text); return(msg); } void JMSSend(TextMessage msg) throws Exception { System.out.println("Sending the message on queue " + ioQueue.getQueueName()); msg.setJMSDestination(null);
// code around WLS bug - CR042458
if (msg.getJMSCorrelationID() == null)
Page 86
J2EE Design Considerations for WebLogic Server ___________________________________________________________ msg.setJMSCorrelationID("fix"); // code around WLS bug - CR042461 queueSender.send(msg); } TextMessage JMSReceive() throws Exception { TextMessage msg; System.out.println("Receiving the message on queue " + ioQueue.getQueueName()); msg = (TextMessage)queueReceiver.receive(1000); if (msg == null) throw new JMSException("Failed to receive message"); return(msg); } void JMSCleanup() throws Exception { if (session != null) { session.close(); session = null; } if (connection != null) { connection.close(); connection = null; } }
Page 87