Srikanth Shenoy (Srikanth@srikanth.org) J2EE Consultant May 2002
As J2EE becomes the election of the enterprise development platform, more and more J2EE-based applications will be put into production. One of the important components of the J2EE platform is Enterprise JavaBean (EJB) API. J2EE and EJB technology have provided many advantages, but there are some new challenges. Especially enterprise systems, any of these must be resolved quickly. In this article, the company Java programming veteran Srikanth Shenoy exhibits his best practices in EJB abnormal treatment, which can solve the problem faster.
In the Hello-World case, exception handling is very simple. Whenever a method is encountered, the exception is captured and the stack tracking or declares that this method throws an exception. Unfortunately, this approach is not enough to deal with various types of exceptions in reality. In the production system, when there is an abnormality, it is likely that the end user cannot process him or her request. When such an exception occurs, end users usually hope to be able to:
There is a clear message that there is a unique error number that has already occurred, which can be quickly resolved according to this access to the customer support system support system problem, and confident that his request has been processed, or will be set Treatment within the time period
Ideally, enterprise-level systems will not only provide these basic services, but will also have some necessary backend mechanisms. For example, the Customer Service Team should receive an instant error notification so that the service representative can be aware of the problem before the customer calls for help. In addition, the service representative should be able to cross the unique error number and product log of the user, so that the problem is quickly identified - it is best to position the problem to the exact line number or the exact method. In order to provide the end users and support teams to provide the tools and services they need, when building a system, you must have a number of all places where the system may have problems after being deployed.
In this article, we will talk about the exception handling in the system of EJB. We will start from the basics of reviewing exception handling, including the use of log utilities, and then quickly transfer to how to define and manage different types of exceptions more detailed in the EJB technology. Since then, we will study some of the advantages and disadvantages of some common exception handling solutions. I will also show my best practices that make full use of EJB abnormal processing.
Please note that this article assumes that you are familiar with J2EE and EJB technology. You should understand the differences between entity beans and session beans. If you have a persistence of bean-managed persistence (BMP) and container-managed persistence (cmp), what is much more understanding in entity bean context, but also help. See the Reference Information For more information on J2EE and EJB technology.
The first step of exception handling basic knowledge Solving the system error is to establish a test system with the same constructor as the production system, and then track all the code that throws an exception, and all the different branches in the code. In a distributed application, it is probably that the debugger does not work, so you may use the system.out.println () method to track exceptions. System.out.println despite it is very convenient, it is huge. During disk I / O, System.out.Println synchronizes I / O processing, which greatly reduces throughput. By default, stack tracking is recorded to the console. However, in the production system, browse the console to see unusual tracking. Moreover, you cannot guarantee that the stack tracking will be displayed in the production system, because in NT, the system administrator can map System.out and System.err to '', on UNIX, can be mapped to dev / null. Also, if you run the J2EE application server as a NT service, there will be no console. Even if you reverach the console log to an output file, this file is likely to be rewritten when the product J2EE application server is restarted. The principle of abnormal processing The following is some of the universal acceptable conditions:
If you can't handle an exception, don't capture it. If you capture an exception, please don't worry about it. Try to capture abnormalities near the abnormality. Incurcing it to the log in the place where you are captured, unless you plan to reap out it. Follow your abnormality to construct your way. There are several types of exceptions, especially for application exceptions. The first point is obvious to the third point. The actual solution is the following compromise: you caught it at a very close to the abnormality; before you completely lose the original anomaly, you can let the anomalies fall in how far. Note: Although these principles are applied throughout all EJB abnormal processing mechanisms, they are not particularly treated for EJB abnormalities.
Due to these reasons, the code group is loaded into a product and contains System.out.Println is not a choice. Use System.out.Println during the test, then remove System.out.Println before forming the product, because this means that your product code is running different from the test code. You need is a declaration control log mechanism to make your test code and product code, and when the log log is closed, the performance overhead brought to the product is minimized.
The solution here is obviously using a log utility. With the appropriate coding convention, the log utility will be responsible for accurately record any type of message, whether it is a system error or some warning. Therefore, we will talk about log utilities before further explaining.
Log field: Aerial view Each large application uses log utilities in development, testing, and product cycles. In today's log field, there are several competeeners, two of which are widely known. One is log4j, which is an open source project from Apache's Jakarta. The other is the J2SE 1.4 bundle, it is recently just added to this row. We will use log4j to explain the best practices discussed herein; however, these best practices do not specifically depend on log4j.
LOG4J has three main components: layout, appender and category. The Layou represents the message recorded in the format in the log. Appender is an alias for the physical location that will be recorded. Category is a nameful entity: You can use it as a handle of the log. Layout and Appender are declared in the XML configuration file. Each Category has its own Layout and Appender definitions. When you get a category and record the message to it, the message ends at the respective Appers associated with the Category, and all of these messages will be represented in the Layout format specified in the XML configuration file. Log4j gives the message four priorities: they are Error, Warn, INFO, and Debug. For the discussion of this article, all exceptions are recorded with ERROR priority. When an exception in this article is recorded, we will be able to find the code for category (using the category.getInstance (String Name) method, then call method category.Error () (which corresponds to a message with Error priority).
Although log utilities help us record messages to the appropriate persistent location, they can't eradicate issues. They cannot accurately find a customer's question report from the product log; this convenience is left to build it to the system you are developing.
To learn more about log utilities, please refer to the reference part of the log utility of the log4j log utility or J2SE.
Abnormal class abnormality has different ways. Here, we will discuss how the anomalies are classified from the angle of EJB. EJB specification will be abnormally divided into three categories:
JVM exception: This type of exception is thrown by JVM. OutofMemoryError is a common example of the JVM exception. You can't do anything about JVM. They show a fatal situation. The only amount of the exit is to stop the application server (you may have to add hardware resources) and then restart the system. Application exception: Application exception is a custom exception, thus being thrown by an application or third party. These are essentially checking (Checked Exception); they indicate that some conditions in business logic have not yet been met. In this case, the caller of the EJB method can deal with this situation and use another alternative pathway. The system is abnormal: In most cases, the system exception is thrown by the JVM as the subclass of RuntimeException. For example, NullPointersException or ArrayOutOfboundSexception will be thrown due to errors in the code. Another type of system exception occurs when the system encounters improper resources (for example, the JNDI lookup (JNDI Lookup)). In this case, the system will throw an extraordinary. The capture of these check systems is abnormal and the unchecked exception is quite significant. The most important rule is that if you have no power to an exception, it is a system anomaly and should be thrown as a non-acceptance exception.
Note: An exception is an Java class as a subclass of java.lang.exception. By derived subclasses from java.lang.exception, forced you to capture this exception at compile. Conversely, non-detection is a Java class as a subclass of java.lang.RuntimeException. From java.lang.runtimeException, the seizure class ensures that the compiler does not force you to capture this exception.
How does the EJB container handle an exception EJB container intercepting each method call on the EJB component. As a result, every exception that occurs in method calls is also intercepted by the EJB container. The EJB specification only handles two types of exceptions: application exceptions and system exceptions. The EJB specification defines the application to any abnormality (not RemoteException) declared in the method description in the remote interface. Application exception is a special situation in business workflow. When this type of abnormality is thrown, the client will get a recovery option, which is usually requested to process the request in a different way. However, this does not mean that any non-investigated exception declared in the throws clause of the remote interface method will be treated as an application. The EJB specification clearly indicates that the application exception should not inherit the runtimeException or its subclass.
When an application exception occurs, the EJB container will not do this unless it is explicitly requested (by calling the SetrollbackOnly () method of the associated EJBContext object. In fact, the application exception is guaranteed to transmit to the client with its original state: EJB container will never pack or modify an exception in any way.
System abnormal is defined as an abnormality or non-subject exception, and the EJB method cannot recover from this abnormality. When the EJB container is intercepted to non-examination, it will roll back the transaction and perform any necessary cleanup work. Next, it wraps the non-check exception to the RemoteException and then throws it to the client. In this way, the EJB container provides all non-subject as RemoteException (or as its sub-class, such as TransactionRolledBackexception).
For an abnormal survey, the container does not automatically perform the internal processing described above. To use the internal internal service processing of the EJB container, you will have to throw an audible abnormality as an unusual. Whenever an audible system exception occurs, you should throw javax.ejb.ejbexception or its subclasses through the original exception. Because EjBexception itself is not subject to an exception, it is not necessary to declare it in the throws clause of the method. The EJB container captures EJBEXCEPTION or their subclasses, package it into the RemoteException, and throws the RemoteException to the client.
Although the system exception is recorded by the application server (this is specified by the EJB specification), the recording format will vary depending on the application server. In order to access the required statistics, companies often need to run the shell / perl script for the generated log. In order to ensure the unity of the record format, the abnormality will be better in your code.
Note: The EJB 1.0 specification requires an exception of the check system as RemoteException. From the EJB 1.1 specification, the EJB implementation class should never throw RemoteException.
Common abnormal processing strategies If there is no exception handling policy, different developers of the project team are likely to write code that handles exceptions in different ways. Since the same exception may be described and processed in different ways, this is at least confused by the product support team. Lack of strategies will also result in records in multiple places across the system. The log should be concentrated or divided into several manageable units. Ideally, the abnormal log should be recorded as few places as possible, and the content is not lost. In this section, several parts thereafter, I will showcase coding strategies that can be implemented in a unified manner throughout the enterprise system. You can download the utility classes developed this article from the reference part.
Listing 1 shows a method from session EJB components. This method removes all orders under a certain customer at a specific date. First, it gets the ORDEREJB's HOME interface. Then, it retrieves all orders for a particular customer. When it encounters the order under a certain date, delete the item ordered, then delete the order itself. Please note that three exceptions have been thrown, showing three common exception handling practices. (To the simplicity, suppose the compiler optimization is not used.) List 1. Three common abnormal processing practices
100 try {
101 ORDERHOME HOMEOBJ = EjBhomeFactory.getInstance (). GetorderHome ();
102 Collection ORDERCOLLECTION = Homeobj.FindbyCustomerId (ID);
103 Iterator Order = OrderCollection.Iterator ();
104 While (ORDERITER.HASNEXT ()) {
105 ORDER OrderRemote = (OrderRemote) Orderiter.getNext ();
106 ORDERVALUE ORDERVAL = OrderRemote.getValue ();
107 if (OrderVal.getdate () <"mm / dd / yyyy") {
108 ORDERITEMHOMHOME =
EjbhomeFactory.getInstance (). GetItemHome ();
109 Collection Itemcol = ItemHome.FindbyOrderId (OrderID)
110 item temlicitr = itemcol.ITerator ();
111 While (itemiter.hasnext ()) {
112 ORDERITEM ITEM = (OrderItem) itemiter.getNext ();
113 item.remove ();
114}
115 ORDERREMOTE.REMOVE ();
116}
117}
118} catch (namingexception ne) {
119 throw new ejbexception ("Naming Exception Occurred");
120} catch (FINDEREXCEPTION Fe) {
121 fe.printStackTrace ();
122 throw new ejbexception ("Finder Exception Occurred");
123} catch (remoteexception re) {
124 Re.PrintStackTrace ();
125 // Some Code to Log The Message
126 throw new ejbexception (re);
127}
Now, let us use the code shown above to study the shortcomings of the three exception handling practices shown.
Throwing / heavy throwing an exception Namingexception with an error message may occur in row 101 or row 108. When namingexception occurs, the caller of this method gets RemoteException and tracks the exception to line 119. The caller does not inform Namingexception actually happen to Row 101 or line 108. Since the abnormal content is to be protected until the record is recorded, the root cause of this problem is difficult to find. In this case, we say that the abnormal content is "swallowed". As shown in this example, throw or re-throw an exception with messages is not a good exception handling solution. Record to the console and throw an exception FINDEREXCEPTION may occur in rows 102 or 109. However, since the abnormality is recorded to the console, the caller can then track the row 102 or 109 only when the console is available. This is obviously not feasible, so exception can only be followed by backward 122. The reasoning here is the same.
Packaging the original exception to protect its content RemoteException may occur in rows 102, 106, 109, 113 or 115. It is captured at the Catch block of the line 123. Next, this exception is packaged into EJBEXCeption, so where the caller records it, it can remain complete. This approach is better than the previous two methods, and it demonstrates that there is no log strategy. If the caller of the deleteolders () method records the exception, then the recording will result in repeated records. Moreover, despite logging, the product log or console cannot be cross-referenced when a customer reports a problem.
What exceptions should EJB abnormality to deal with the EJB component? Where should you record what places in the system? These two issues are rounded, and they should be solved together. The solution depends on the following factors:
Your EJB System Design: In a good EJB design, the client nelectives the method on the entity EJB component. Most entity EJB method calls occur in session EJB components. If your design follows these guidelines, you should use the session EJB component to record exceptions. If the client calls the entity EJB method, you should also record the message into the entity EJB component. However, there is a problem: the same entity EJB method may also be called by the session EJB component. In this case, how to avoid repeat recording? Similarly, how do you avoid recording when a session EJB component calls other entity EJB methods? Soon we will explore a general solution to handle these two situations. (Note that EJB 1.1 does not block the client to modify the method on the entity EJB component from the architecture. In EJB 2.0, you can define this restrictions for entity EJB components to define local interfaces.) Scheduled code Reuse range: The problem here is that you intend to add log code to multiple places, or to redesign, re-construct code to reduce log code. The type of client you want to serve is important to consider you will be a J2EE Web layer, stand-alone Java application, and PDA or will be important for other client services. Web layer design has various shapes and sizes. If you are using the command mode, in this mode, the Web layer calls the same method in the EJB layer each time, then the exception record to the command in the EJB component executed therein. useful. In most other web layer designs, it is more easier and better to record an exception to the web layer itself, because you need to add an exception log code to a less place. If your web layer and EJB layers are in the same place and do not need to support any other types of clients, then the latter choice should be considered. You will process an exception (application, or system): handling application exceptions vary widely. The occurrence of abnormal system is not controlled by EJB developers. Because the meaning of the system is unclear, the content should indicate an abnormal context. You have already seen that this problem has been best processed by packaging the original exception. On the other hand, the application exception is explicitly thrown by EJB developers, usually packaged with a message. Because the application exception has clear, there is no reason to protect its context. This type of exception does not have to record the EJB layer or client layer; it should be provided to the end user in a meaningful way, bringing another alternative way to the supplied solution. System abnormal messages are not necessary to make sense to end users. Processing application exceptions in this section and subsequent sections, we will carefully study the exception and system exceptions for EJB abnormal processing applications, and Web layer design. As part of this discussion, we will explore different ways to process abnormalities thrown from session and entity EJB components.
Application Abnormal Listing 2 in an entity EJB component shows an EJBCREATE () method of entity EJB. The caller of this method passes an ORDERITEMVALUE and requests to create an ORDERITEM entity. Because ORDERITEMVALUE has no name, it throws CreateException.
Listing 2. Sample ejbcreate () method in entity EJB components
Public Integer Ejbcreate (OrderItemValue Value) throws createException {
Value.getItemName () == null) {
Throw New CreateException ("Cannot Create Order Without a name);
}
.
.
Return NULL;
}
Listing 2 shows a typical usage of CreateException. Similarly, if the value of the input parameters of the method is incorrect, the lookup program method will throw a FINDEREXCEPTION.
However, if you are using container management persistence (CMP), developers cannot control find program methods, so FindEREXCEPTION will never be thrown by the CMP. Despite this, declare that FINDEREXCEPTION is still better in the throws clause of the HOME interface. RemoveException is another application exception, which is thrown when the entity is deleted.
Applications thrown from entity EJB components are basically limited to these three types (FINDEREXCEPTION and REMOVEEXCEPTION) and their subclasses. Most applications are from session EJB components because there is a place to make intelligence decisions. Entity EJB components are generally dumb, and their only responsibility is to create and retrieve data.
Application Abnormal Listing 3 in the session EJB component shows a method from a session EJB component. The caller of this method tries to order the N pieces of a particular type of item. The sessionejb () method calculates that the number in the warehouse is not enough, so throws notenoughstockexception. NOTENOUGHSTOCKEXCEPTION Suitable for business-specific applications; when this exception is thrown, the caller will receive a suggestion using another alternative way to order a smaller number of items.
Listing 3. Sample container callback method in session EJB components
Public itemvalueObject [] PlaceRder (int N, itemtype itemtype) throws
Notenoughstockexception {
// Check inventory.
Collection Orders = ItemHome.FindByItemType (ItemType);
IF (Orders.Size () Throw NotenoughStockexception ("Insufficient stock for" itemtype); } } Processing system exception system exception handling is more complex topics than applications. Since all examples of the session EJB component and entity EJB component processing system are similar, we will focus on entity EJB components, but remember that most of them apply to handling session EJB components. . When referenced to other EJB remote interfaces, entity EJB components will touch RemoteException, and when you find other EJB components, you will touch the Namingexception, if you use bean management persistence (BMP), you will encounter SQLException. An exception to these similar investigations should be captured and throw as EJBEXCEPTION or one subclass. The original exception should be packaged. Listing 4 shows a method of processing system anomalies, which is consistent with the behavior of the EJB container for processing system. By packaging the original exception and reappears it in the entity EJB component, you ensure that you can access the exception when you want to record it. Listing 4. A common way to handle system abnormalities Try { ORDERHOME ORDERHOME = EjBhomeFactory.getInstance (). GetorderHome (); ORDER ORDER = OrderHome.FindByPrimaryKey (Integer ID); } catch (namingexception ne) {throw new ejbexception (ne); } catch (sqlexception se) { Throw new ejbexception (se); } catch (remoteexception re) { Throw new ejbexception (re); } Avoid repeated records typically, abnormal records occur in session EJB components. But what if you access an entity EJB component outside the EJB layer? In this way, you have to record an exception in the entity EJB component and throw it. The problem here is that the caller has no way to know if the exception has been recorded, so it is likely to record it again, resulting in repeated records. More importantly, the caller can't access the unique identifier generated when the initial record is accessed. Any records without cross-reference mechanism are useless. Consider this worse case: Single machine Java application accesses a method foo () in an entity EJB component. The same method is also accessed in a session EJB method called BAR (). A web layer client calls a method BAR () of a session EJB component and also records the exception. If an exception occurs in the entity EJB method foo () when the session EJB method BAR () is called from the web layer, the exception will be recorded to three places: first in the entity EJB component, then in the session EJB component, Finally, it is in the web layer. Moreover, no stack tracking can be crossed! Fortunately, it can be easily done with conventional methods to solve these problems. What you need is just a mechanism that allows the caller to: Accessing the only ID identifies whether the exception has been recorded You can derive the subclass of EJBEXCeption to store such information. Listing 5 shows the loggableejbexception subclass: Listing 5. Loggableejbexception - a subclass of EJBEXCEPTION Public class loggableejbexception extends ejbexception { Protected boolean islogged; Protected String UniqueId; Public loggableejbexception (Exception EXC) { Super (exc); islogged = false; UniqueId = exceptionidgenerator.getexceptionId (); } . . } Class loggableejbexception has an indicator flag (islogged) for checking whether the exception has been recorded. Whenever the exception has been recorded whenever a loggableeejbexception is captured (islogged == false). If islogged is false, the exception is logged and the flag is set to True. The Exception IDGenerator class uses the current time and the host name of the machine to generate a unique identifier. If you like, you can also use an imagination algorithm to generate this unique identifier. This exception will not be recorded in other places if you have recorded an exception in an entity EJB component. If you don't have a record that throws LogGAbleEJBException in the entity EJB component, this exception will be recorded in the session EJB component, but not logged into the web layer. Listing 6 shows the list 4 after using this technology. You can also inherit the logGableException to fit your needs (by giving an error code, etc.). Listing 6. Handling Try {using loggableejbexception ORDERHOME ORDERHOME = EjBhomeFactory.getInstance (). GetorderHome (); ORDER ORDER = OrderHome.FindByPrimaryKey (Integer ID); } catch (namingexception ne) { Throw new loggableejbexception (ne); } catch (sqlexception se) { Throw new loggableejbexception (se); } catch (remoteexception re) { Throwable t = re.detail; IF (t! = null && t instanceof exception) { Throw new loggableejbexception (exception) Re.detail; } else { Throw new loggableejbexception (re); } } Record RemoteException From Listing 6, you can see that Naming and SQL exception are packaged in the loggableejbexception before being thrown. However, RemoteException is processed in a slightly different-and slightly spended. The system exception in the session EJB component If you decide to record the session EJB exception, use the record code shown in Listing 7; otherwise, throw an exception, as shown in Listing 6. You should notice that the session EJB component handles exceptions can have a different way to entity EJB components: Because most EJB systems can only access from the web layer, and the session EJB can act as a virtual package of the EJB layer, so conversation EJB Abnormal records are delayed to the web layer actually possible. It is different because In RemoteException, the actual exception will be stored as a Detail (it is THROWABLE types of public properties. In most cases, this public property saves an exception. If you call RemoteException PrintStackTrace, removes the stack tracking of the exception itself in addition to printing Detail's stack tracking. You don't need to be like this RemoteException stack tracking. In order to separate your application code from an intricate code (such as the RemoteException code), these rows are reconscribed into a class called ExceptionLogutil. With this class, you have to do just call ExceptionLogutiloggableEJBEXCEPTION (E) whenever you need to create loggableejbexception. Note that in Listing 6, the entity EJB component does not have an abnormality; however, even if you decide to record an abnormality in the entity EJB component, this solution is still running. Listing 7 shows an exception record in an entity EJB component: Listing 7. Abnormal records in entity EJB components Try { ORDERHOME ORDERHOME = EjBhomeFactory.getInstance (). GetorderHome (); ORDER ORDER = OrderHome.FindByPrimaryKey (Integer ID); } catch (remoteexception re) { Loggableejbexception le = ExceptionLogutil.createloggableejbexception (re); string tracestr = stacktraceutil.getstacktrace (le); Category.GetInstance (GetClass (). Getname ()). Error (le.getunique) ":" traceStr); Le.setlogged (TRUE); Throw Le; } What you see in Listing 7 is a very simple and clear abnormal recording mechanism. Once the captured system is abnormal, create a new LoggableEJBEXCEPTION. Next, use class StackTraceutil to get the stack trace of LogGableEJBEXCeption, use it as a string. Then, use log4j category to record the string as an error. The working principle of the StackTraceutil class In Listing 7, you see a new class called StackTraceutil. Because log4j can only record String messages, this class is responsible for resolving the problem of converting stack tracking into string. Listing 8 illustrates the working principle of the StackTraceutil class: Listing 8. StackTraceutil class Public class stacktraceutil { Public Static String GetStackTrace (Exception E) { StringWriter SW = new stringwriter (); PrintWriter PW = New PrintWriter (SW); Return sw.toString (); } . . } Java.lang.Throwable The default PrintStackTrace () method records the error message to System.err. Throwable has an overloaded PrintStackTrace () method that records an error message to PrintWriter or PrintStream. The method in StackTraceut has put StringWriter into the PrintWriter. When the PrintWriter contains stack tracking, it just calls StringWriter's toString () to get the string representation of the stack trace. The EJB exception handling of the Web layer is often more easier to put an exception record mechanism in the web layer design. It is necessary to do this, the web layer must be the only client of the EJB layer. In addition, the Web layer must be based on one of the following modes or frames: Mode: Business Delegate, a FRONTCONTROLLLER, or Intercepting Filter frame: Struts or any framework that contains hierarchies Why should an abnormal record happen on the client? Well, first, the control has not been transmitted to the application server. The so-called client layer runs on the J2EE application server itself, which consists of JSP page, servlet, or their assistant class. Second, there is a hierarchy in the design in the well-designed Web layer (for example: Business Delegate class, intercepting filter class, HTTP Request Handler) and JSP base class (JSP Base Class), or in the Struts Action class), or single point calls in the FrontController Servlet form. The base class of these hierarchies or central point in the Controller class may contain abnormal recording code. For a session EJB record, each method in the EJB component must have a recording code. As the business logic increases, the number of session EJB methods increases, and the number of recorded code will increase. Web layer systems will require fewer recording code. If your web layer and EJB layers are in the same place and do not need to support any other types of clients, you should consider this spare solution. In any case, the recording mechanism will not change; you can use the same techniques described above. The complexity of the real world is now, you have seen the simple situation of sessions and unusual processing techniques for entity EJB components. However, some combinations of application abnormalities may be more complete and have a variety of explanations. Listing 9 shows an example. Orderejb's EJBCREATE () method is trying to get a remote reference of CustomEREJB, which causes FINDEREXCEPTION. ORDEREJB and Customerejb are entity EJB components. How should you explain this FINDEREXCEPTION in EJBCREATE ()? Is it treated as an application as an application (because the EJB specification is defined as the standard application exception), or is it treated as a system? Listing 9. FINDEREXCEPTION in EJBCREATE () method Public Object Ejbcreate (OrderValue Val) THROWS CREATEEXCEPTION { Try { Value.getItemName () == null) { Throw New CreateException ("Cannot Create Order Without a name); } String custom = val.getcustomerid (); Customer Cust = Customerhome.fingbyPrimaryKey (CustId); This.customer = Cust; } catch (FINDEREXCEPTION NE) { // How do you have handle this exception? } catch (remoteexception re) { // this is Clearly a system exception Throw ExceptionLogutil.createloggableejbexception (re); } Return NULL; } Although there is nothing to prevent you from treating FingerException as an application is abnormally, it will take it when the system is exceptionally. The reason is that the EJB client tends to treat the EJB component as a black box. If the caller of the CreateOrder () method gets a FINDEREXCEPTION, this does not make sense to the caller. OrdereJB is trying to set up a customer remote reference to this matter is transparent to the caller. From the perspective of the client, failure only means that the order cannot be created. Another example of such a situation is that the session EJB component attempts to create another session EJB, thus causing a CREATEXCEPTION. A similar situation is that the entity EJB method attempts to create a session EJB component, thus causing a CREATEEXCEPTION. These two exceptions should be treated as an abnormality. Another challenge that may come is that session EJB components have obtained a FINDEREXCEPTION in its container callback method. You must process this kind of situation in an example. You may have to decide whether to treat FINDEREXCEPTION as an exception of the application or the system. Consider the case of Listing 1, where the caller calls the deleteoldORDER method for the session EJB component. If we don't catch FINDEREXCEPTION, how do you throw it? In this particular case, the FINDEREXCEPTION will seem to be logical when the system is abnormal. The reason here is that session EJB components tend to do a lot of work in their methods, as they handle workflow situations, and they are black boxes for the caller. On the other hand, consider the situation of session EJB is dealing with orders. To the next order, the user must have a profile - but this particular user has not yet. Business logic may wish to explicitly notify the user of her profile loss. Lost profiles are likely to behave as javax.eb.ObjectNotFoundException in the session EJB component. A subclass of FinderException. In this case, the best way is to capture ObjectNotFoundException in the session EJB component and throw an application exception, so that users know that her profile is lost. Even if you have a good exception handling strategy, another problem is often the appearance in the test and is more important in the product. Compilers and runtime optimizations change a class's overall structure, which limits the ability to track exceptions using the stack trace utility. This is where you need the help of code reconstruction. You should send a big method to a smaller, easier to manage blocks. Moreover, as long as it is possible, how much is the amount of abnormal types, it is divided into it; each time you capture an exception, you should capture a specified type of exception, not all types of exceptions. Conclusion We have discussed a lot of things in this article, you might want to know if we have already discussed whether there is money. My experience is that even in small and medium-sized projects, in the development cycle, your pay is already able to see the return, not to mention testing and product cycles. In addition, in the production system that has devastating in the business, how is the importance of a good abnormal treatment architecture, and it is not too much. I hope this paper is good for you. To understand some of the information provided here, see the list in the reference part. Reference Click on the discussion for discussion at the top or bottom of this article to participate in this article. Download the utility class discussed herein. You can read the Sun Microsystems EJB specification to learn more about the EJB architecture. Apache's Jakarta project has several treasures. The Log4j frame is one of them. The Struts framework is another treasure in the Jakarta project. Based on the MVC architecture, Struts provides a thorough separation, which separates the system's representation layer from the system's business logic layer. To learn more about Struts, read the very popular article "Struts, An Open-Source MVC Implementation" (DeveloperWorks, February 2001). Please note: One of the latest articles written by Wellie Chao is scheduled to publish in the summer of 2002. You can learn more about the new Java Logging API (Java.util.Logging) through reading the relevant J2SE documentation. Just contact J2EE? This article from "WebSphere Developer Garden" tells you how to develop and test J2EE applications with WebSphere Studio Application Developer (October 2001). If you want more to learn about testing EJB-based systems, please start from the nearest developerWorks article "TEST FLEXIBLY WITH Aspectj and Mock Objects" (May 2002). If you don't satisfy the unit test, you also want to understand the knowledge of enterprise-level system testing, please see what IBM Performance Management, Testing, And Scalability Services Enterprise Level Test Library provides. Sun's J2EE mode Web site focuses on using J2EE technology model, best practices, design strategies, and testing solutions. The tutorial "Java Design Patterns 101" (DEVELOPERWORKS, Jan 2002) is an introduction to the design mode. See why the mode is useful for object-oriented design and development, and how the mode is archived, classified, and catalog. This tutorial contains some important modes and examples of implementation. Check out the developerWorks tutorial homepage, there is a complete list of free tutorials from the developerWorks Java technology area. You can find hundreds of articles about Java programming in the developerWorks Java Technology area. About the author Srikanth Shenoy specializes in the architecture, design, development and deployment of large J2EE and EAI projects. When he appeared in the Java platform, he was fascinated by it, and he was in the heart. Srikanth has helped his manufacturing, logistics industry and financial industry customers to achieve the dream of Java platform "once written, run everywhere". You can contact him with Srikanth@srikanth.org.