- 浏览: 58538 次
- 性别:
- 来自: 武汉
-
文章分类
最新评论
-
hngmduyi:
楼主,我现在也在研究PORTAL ,能给点这方面的资料或指导吗 ...
准备跟进portal -
mickey_mjy:
您能写一下具体写session.flush的位置么
Session.flush()的一个用法 -
Beaterman2009:
可以把整个压缩包挂上去么,谢谢LZ
JQuery ajax Demo -
kjj:
phenom 写道查了不少,就是没发现有和struts的,比如 ...
JQuery ajax Demo -
freerambo:
楼主的帖子对我这个初学者就是福音啊! 支持!
JQuery ajax Demo
最近一直在弄异常 在JavaWorld上找到一篇好我文章 等忙过了一段时间在翻译 写的很好
从中学到了很多东西
The perpetual debate on exception handling in Java can at best be described as a religious war: On one side, you have the proponents of checked exceptions arguing that callers should always deal with error situations arising in code they call. On the other side stand the followers of unchecked exceptions pointing out that checked exceptions clutter code and often can't be handled in immediate clients anyway, so why force it?
As junior engineers, we first sided with the proselytes of checked exceptions, but over the years, and after many, many catch blocks later, we have gradually converted to the order of the unchecked. Why? We have come to believe in a simple set of rules for dealing with error situations:
1.If it makes sense to handle the exception, do so
2.If you can't handle it, throw it
3.If you can't throw it, wrap it in an unchecked base exception and then throw it
But what about those exceptions that bubble all the way to the top, you ask? For those, we install a last line of defense to ensure error messages are always logged and the user is properly notified.
This article presents yet another framework for exception handling, which extends the enterprise-wide application session facility presented in "Create an Application-Wide User Session for J2EE" (JavaWorld, March 2005). J2EE applications that use this framework will:
1.Always present meaningful error messages to users
2.Log unhandled error situations once and only once
3.Correlate exceptions with unique request IDs in log files for high-precision debugging
4.Have a powerful, extensible, yet simple strategy for exception handling at all tiers
To forge the framework, we wield aspect-oriented programming (AOP), design patterns, and code generation using XDoclet.
You will find all the code in Resources along with a sample J2EE application that uses it. The source constitutes a complete framework named Rampart, which was developed for Copenhagen County, Denmark in the context of J2EE-based electronic healthcare records (EHR) applications.
Why do we need common error handling?
During a project's initial state, significant architecture decisions are made: How will software elements interact? Where will session state reside? What communication protocols will be used? And so on. More often than not, however, these decisions do not include error handling. Thus, some variant on the happy-go-lucky strategy is implemented, and, subsequently, every developer arbitrarily decides how errors are declared, categorized, modeled, and handled. As an engineer, you most likely recognize the results of this "strategy":
1.Swollen logs: Every catch block contains a log statement, leading to bloated and redundant log entries caused by polluted source code.
2.Redundant implementations: The same type of error has different representations, which complicates how it is handled.
3.Broken encapsulation: Exceptions from other components are declared as part of the method signature, breaking the clear division between interface and implementation.
4.Noncommittal exception declaration: The method signature is generalized to throw java.lang.Exception. This way, clients are ensured not to have the least clue about the method's error semantics.
A common excuse for not defining a strategy is that "Java already provides error handling." This is true, but the language also offers facilities for consistently declaring, signaling, propagating, and responding to errors. The language user is responsible for deciding how these services should be used in an actual project. Several decisions must be made, including:
1.To check or not to check: Should new exception classes be checked or unchecked?
2.Error consumers: Who needs to know when an unhandled error occurs, and who is responsible for logging and notifying operations staff?
3.Basic exception hierarchy: What kind of information should an exception carry and what semantics does the exception hierarchy reflect?
4.Propagation: Are nonhandled exceptions declared or transformed into other exception classes, and how are they propagated in a distributed environment?
5.Interpretation: How are unhandled exceptions turned into human readable, even multilingual messages?
Encapsulate rules in a framework, but hurry!
Our recipe for a common error-handling strategy builds on the following shortlist of ingredients:
1.Use unchecked exceptions: By using checked exceptions, clients are forced to take a position on errors they can rarely handle. Unchecked exceptions leave the client with a choice. When using third-party libraries, you don't control whether exceptions are modeled as checked or unchecked ones. In this case, you need unchecked wrapper exceptions to carry the checked ones. The biggest tradeoff in using only unchecked exceptions is that you can't force clients to handle them anymore. Yet, when declared as part of the interface, they remain a crucial element of the contract and continue to be part of Javadoc documentation.
2.Encapsulate error handling and install a handler on top of each tier: By having a safety net, you can focus on handling only exceptions relevant to business logic. The handler performs the safe touchdown for the remaining exceptions at the specific tier executing standardized steps: logging, system management notification, transformations, etc.
3.Model the exception hierarchy using a "simple living" approach: Don't automatically create new exception classes whenever new error types are discovered. Ask yourself if you are simply dealing with a variation of another type and if the client code is likely to explicitly catch it. Remember that exceptions are objects whose attributes can, at least to some extent, model the variation of different situations. Less than a handful of exception classes will most likely prove enough to satisfy a starting point, and only those that are likely to be handled need specialized attributes.
4.Give meaningful messages to end users: Unhandled exceptions represent unpredictable events and bugs. Tell this to the user and save the details for the technical staff.
Although needs and constraints, exception hierarchies, and notification mechanisms will differ across projects, many elements remain constant. So why not go whole hog and implement common policies in a framework? A framework followed by simple rules of usage is the best way to enforce a policy. Executable artifacts talk to developers, and it is easier to preach architectural principles with a jar file and some Javadoc than with whitepapers and slide shows.
However, you cannot ask the development team to postpone error handling until a policy and complementing framework support is ready. Error handling must already be determined when the first source file is created. A good place to start is by defining the fundamental exception hierarchy.
A basic exception hierarchy
Our first practical task is to define an exception hierarchy common enough to be used across projects. The base class for our own unchecked exceptions is UnrecoverableException, a name that, for historical reasons, remains slightly misleading. You might consider a better title for your own hierarchies.
When you want to get rid of a checked exception, one that, conceivably, clients will always be able to handle, WrappedException offers a simple, generic transport mechanism: wrap and throw. The WrappedException keeps the cause as an internal reference, which works well when the classes for the original exception are still available. When this is not the case, use SerializableException, which resembles WrappedException except that it can be used when no assumptions are made on available libraries at the client side.
Although we prefer and recommend unchecked exceptions, you might keep checked exceptions as an option. The InstrumentedException interface acts as an interface for both checked and unchecked exceptions that follow a certain pattern of attribute implementation. The interface allows exception consumers to consistently inspect the source—whether it inherits from a checked or an unchecked base.
The class diagram below shows our basic exception hierarchy.
Figure 1. A basic exception hierarchy
At this point, we have a strategy and a set of exceptions that can be thrown. It is time to build the safety net.
The last line of defense
The article "Create an Application-Wide User Session" presented Rampart, a layered architecture consisting of an enterprise information system tier, a business logic tier made from stateless session beans, and a client tier with both Web and standalone J2SE clients. Exceptions can be thrown from all tiers in this architecture, and can either be handled on site or bubble up until they reach the end of the call chain. Then what? Both J2SE and J2EE application servers guard themselves against offensive behavior by catching stray Errors and RuntimeExceptions, and by dumping the stack trace to System.out, logging it, or performing some other default action. In any case, if a user is presented with any kind of output, mostly likely, it will prove absolutely meaningless, and, worse, the error will probably have disrupted program stability. We must install our own rampart to provide a more sound exception-handling mechanism for this last line of defense.
Consider Figure 2:
Figure 2. Exception paths in the sample architecture
Exceptions may occur on the server side in the EJB (Enterprise JavaBeans) tier and in the Web tier, or on the standalone client. In the first case, exceptions stay in the VM from which they originated as they make their way up to the Web tier. This is where we install our top-level exception handler.
In the standalone case, exceptions eventually reach the rim of the EJB container and travel along the RMI (remote method invocation) connection to the client tier. Care must be taken not to send any exceptions belonging to classes that live only on the server side, e.g., from object-relational mapping frameworks or the like. The EJB exception handler handles this responsibility by using SerializableException as a vehicle. On the client side, a top-level Swing exception handler catches any stray errors and takes appropriate action.
Exception-handler framework
An exception handler in the Rampart framework is a class that implements the ExceptionHandler interface. This interface's only method takes two arguments: Throwable, to handle, and the current Thread. For convenience, the framework contains an implementation, ExceptionHandlerBase, which tastes Throwable and delegates handling to dedicated abstract methods for the flavors RuntimeException, Error, Throwable, and the Rampart-specific Unrecoverable. Subclasses then provide implementations for these methods and handle each situation differently.
The class diagram below shows the exception-handler hierarchy with its three default exception handlers.
Figure 3. Exception-handler hierarchy. Click on thumbnail to view full-sized image.
Some among The Order of the Unchecked believe that Sun should have added hooks into all containers in the J2EE architecture on a per-application basis. This would have allowed custom error-handling schemes, security, and more to be gracefully installed, without reliance on vendor-specific schemes and frameworks. Unfortunately, Sun failed to provide such mechanisms in the EJB specification; so, we pull out the AOP hammer from our toolbox and add exception handling as around-aspects. AspectWerkz, our chosen AOP framework, uses the following aspect for that task:
The actual handler is configurable and obtained through the ConfigHelper class. If a RuntimeException or Error is thrown during execution of the bean business logic, the handler will be asked to handle it.
The DefaultEJBExceptionHandler serializes the stack trace of any exception not originating from Sun's core packages into a dedicated SerializableException, which, on the plus side, allows the stack trace of exceptions whose classes don't exist on remote clients to be propagated over anyway. On the downside, the original exception is lost in translation.
EJB containers faithfully take any RuntimeException or Error and wrap it in a java.rmi.RemoteException, if the client is remote, and in a javax.ejb.EJBException, otherwise. In the interest of keeping causes precise and stack traces at a minimum, the framework peels off these transport exceptions inside client BusinessDelegates and rethrows the original.
A Rampart BusinessDelegate class exposes an EJB-agnostic interface to clients, while wrapping local and remote EJB interfaces internally. BusinessDelegate classes are generated via XDoclet from EJB implementation classes and follow the structure shown in Figure 4's UML diagram:
Figure 4. An example BusinessDelegate
The BusinessDelegate class exposes all business methods from the source EJB implementation class and delegates to the LocalProxy class or the RemoteProxy class as appropriate. Internally, the two proxies handle EJB-specific exceptions and, hence, shield the calling BusinessDelegate from implementation details. The code below is a method from some LocalProxy class:
The serviceInterface variable represents the EJB local interface. Any EJBException instances thrown by the container to indicate an unexpected error are caught and handled by the BusinessDelegateUtil class, in which the following action takes place:
The actual exception is extracted and rethrown to the top-level client exception handler. When the exception reaches the handler, the stack trace will be that of the original exception from the server containing the actual error. No superfluous client-side trace is added.
Swing exception handler
The JVM provides a default top-level exception handler for each control thread. When exercised, this handler dumps the stack trace of Error and RuntimeException instances onto System.err and kills the thread! This rather obstructive behavior is quite far from anything a user needs and not elegant from a debugging perspective. We want a mechanism that allows us to notify the user while retaining the stack trace and a unique request ID for later debugging. "Create an Application-Wide User Session for J2EE" describes how such a request ID becomes available at all tiers.
For J2SE versions up to 1.4, uncaught exceptions in Thread instances cause the owner ThreadGroup's uncaughtException() method to execute. A simple way to control exception handling in an application, then, is to simply extend the ThreadGroup class, overwrite the uncaughtException() method, and ensure all Thread instances start within an instance of the custom ThreadGroup class.
J2SE 5 provides an even sweeter mechanism by allowing the installation of an UncaughtExceptionHandler implementation on instances of the Thread class itself. The handler is used as a callback mechanism when uncaught exceptions reach the Thread instance's run method. We built the framework with J2SE 1.3+ compatibility in mind; hence we used the ThreadGroup inheritance approach:
Swing exception handler
The SwingThreadGroup class shown in the code snippet above overrides the uncaughtException() method and passes the current Thread instance and the thrown Throwable to the configured exception handler.
A little more magic is needed before we can claim control of all stray exceptions in the client tier. For the scheme to work, all threads must be associated with our specialized SwingThreadGroup instance. This is accomplished by spawning a new master Thread instance and passing the SwingThreadGroup instance with a Runnable implementation, which executes the entire main program. All Thread instances spawned from the body of this new master Thread instance automatically join the SwingThreadGroup instance and, hence, use our new exception handler when unchecked exceptions are thrown.
Figure 5. Swing exception handler class hierarchy. Click on thumbnail to view full-sized image.
The framework implements this logic in the SwingExceptionHandlerController convenience class shown in Figure 5. Applications provide an implementation of the SwingMain interface along with an exception handler to the controller. The controller must then be started, and the old main Thread can join the new one and wait for termination. The code below shows how the demo application that accompanies this article accomplishes that task. The method createAndShowGUI() constitutes the actual application body, which initializes Swing components and transfers control to the user.
The last line of defense is now in place for the Swing layer, but we still need to provide a meaningful message to the user. The demo application supplies a rather basic implementation that simply displays a dialog box with an internationalized message and the unique request ID as a support ticket. At the same time, the exception is logged via log4j along with the unique request ID. A more sophisticated error handler might send an email, SNMP message, or the like to technical support with the ID in it. The point is that both client and server logs can be filtered on the support ticket ID to allow precise pinpointing of errors on a per-request basis.
Figure 6 shows merged Swing client and J2EE server logs to provide the precise flow for the request with ID 1cffeb4:feb53del38:-7ff6, where an exception was thrown. Note that the stack trace contains only information from the server side, where the exception was thrown.
Figure 6. Log trace from both client and server with request ID and server stack trace. Click on thumbnail to view full-sized image.
While the infrastructure for adding exception handling to standalone J2SE applications is basic, things are different as we move to Web-based clients.
WAR exception handler
Web applications are among the fortunate components in the J2EE world to have their own explicit way of installing exception-handling capabilities. Through the web.xml deployment descriptor, exceptions and HTTP errors can be mapped to error pages in the shape of servlets or JavaServer Pages (JSP) pages. Consider the following fragment from a sample web.xml file:
These tags direct all uncaught exceptions to the URL /errorhandler, which in this case is mapped to the ErrorHandlerServlet class. The latter is a dedicated servlet whose sole raison d'etre is to act as a bridge between Web components and the exception-handling framework. When an uncaught exception from this Web application reaches the servlet container, a set of parameters with information about the exception will be added to the HttpServletRequest instance and passed to the ErrorHandlerServlet class's service method. The fragment below shows the service() method:
In the service() method, first, the actual exception from the HttpServletRequest instance is retrieved through the key javax.servlet.error.exception. Next, the exception handler instance is retrieved. From there on, the handler is invoked, and the HttpServletRequest instance is forwarded to the page specified by the key rampart.servlet.exception.responsepage.
The DefaultWARExceptionHandler class looks up an internationalized text based on the exception message and redirects output response to the JSP /error.jsp. This page is then free to display the message to the user, including the current request ID as a support ticket. A much more sophisticated mechanism can easily be implemented by simply extending or replacing this handler.
Wrap up
Often, exception handling is not handled stringently enough, thereby complicating debugging and error tracking, and, many times, disrupting the overall user experience. It is therefore crucial to have policies and frameworks in place before system development starts. Adding this aspect as an afterthought is doable, but time consuming and expensive.
This article has armed you with a starting point for defining an exception policy and introduced you to a simple, yet extensible, unchecked exception hierarchy. We have walked through business and client tiers of a sample J2EE architecture and shown how you can install top-level exception handlers for each tier to provide a last line of defense. The framework code has given you a way to precisely pinpoint errors on a per-user request basis through the unique request ID attached to exceptions and log entries.
So download the framework, try it out, modify it to your heart's delight, and get those exceptions under control.
从中学到了很多东西
The perpetual debate on exception handling in Java can at best be described as a religious war: On one side, you have the proponents of checked exceptions arguing that callers should always deal with error situations arising in code they call. On the other side stand the followers of unchecked exceptions pointing out that checked exceptions clutter code and often can't be handled in immediate clients anyway, so why force it?
As junior engineers, we first sided with the proselytes of checked exceptions, but over the years, and after many, many catch blocks later, we have gradually converted to the order of the unchecked. Why? We have come to believe in a simple set of rules for dealing with error situations:
1.If it makes sense to handle the exception, do so
2.If you can't handle it, throw it
3.If you can't throw it, wrap it in an unchecked base exception and then throw it
But what about those exceptions that bubble all the way to the top, you ask? For those, we install a last line of defense to ensure error messages are always logged and the user is properly notified.
This article presents yet another framework for exception handling, which extends the enterprise-wide application session facility presented in "Create an Application-Wide User Session for J2EE" (JavaWorld, March 2005). J2EE applications that use this framework will:
1.Always present meaningful error messages to users
2.Log unhandled error situations once and only once
3.Correlate exceptions with unique request IDs in log files for high-precision debugging
4.Have a powerful, extensible, yet simple strategy for exception handling at all tiers
To forge the framework, we wield aspect-oriented programming (AOP), design patterns, and code generation using XDoclet.
You will find all the code in Resources along with a sample J2EE application that uses it. The source constitutes a complete framework named Rampart, which was developed for Copenhagen County, Denmark in the context of J2EE-based electronic healthcare records (EHR) applications.
Why do we need common error handling?
During a project's initial state, significant architecture decisions are made: How will software elements interact? Where will session state reside? What communication protocols will be used? And so on. More often than not, however, these decisions do not include error handling. Thus, some variant on the happy-go-lucky strategy is implemented, and, subsequently, every developer arbitrarily decides how errors are declared, categorized, modeled, and handled. As an engineer, you most likely recognize the results of this "strategy":
1.Swollen logs: Every catch block contains a log statement, leading to bloated and redundant log entries caused by polluted source code.
2.Redundant implementations: The same type of error has different representations, which complicates how it is handled.
3.Broken encapsulation: Exceptions from other components are declared as part of the method signature, breaking the clear division between interface and implementation.
4.Noncommittal exception declaration: The method signature is generalized to throw java.lang.Exception. This way, clients are ensured not to have the least clue about the method's error semantics.
A common excuse for not defining a strategy is that "Java already provides error handling." This is true, but the language also offers facilities for consistently declaring, signaling, propagating, and responding to errors. The language user is responsible for deciding how these services should be used in an actual project. Several decisions must be made, including:
1.To check or not to check: Should new exception classes be checked or unchecked?
2.Error consumers: Who needs to know when an unhandled error occurs, and who is responsible for logging and notifying operations staff?
3.Basic exception hierarchy: What kind of information should an exception carry and what semantics does the exception hierarchy reflect?
4.Propagation: Are nonhandled exceptions declared or transformed into other exception classes, and how are they propagated in a distributed environment?
5.Interpretation: How are unhandled exceptions turned into human readable, even multilingual messages?
Encapsulate rules in a framework, but hurry!
Our recipe for a common error-handling strategy builds on the following shortlist of ingredients:
1.Use unchecked exceptions: By using checked exceptions, clients are forced to take a position on errors they can rarely handle. Unchecked exceptions leave the client with a choice. When using third-party libraries, you don't control whether exceptions are modeled as checked or unchecked ones. In this case, you need unchecked wrapper exceptions to carry the checked ones. The biggest tradeoff in using only unchecked exceptions is that you can't force clients to handle them anymore. Yet, when declared as part of the interface, they remain a crucial element of the contract and continue to be part of Javadoc documentation.
2.Encapsulate error handling and install a handler on top of each tier: By having a safety net, you can focus on handling only exceptions relevant to business logic. The handler performs the safe touchdown for the remaining exceptions at the specific tier executing standardized steps: logging, system management notification, transformations, etc.
3.Model the exception hierarchy using a "simple living" approach: Don't automatically create new exception classes whenever new error types are discovered. Ask yourself if you are simply dealing with a variation of another type and if the client code is likely to explicitly catch it. Remember that exceptions are objects whose attributes can, at least to some extent, model the variation of different situations. Less than a handful of exception classes will most likely prove enough to satisfy a starting point, and only those that are likely to be handled need specialized attributes.
4.Give meaningful messages to end users: Unhandled exceptions represent unpredictable events and bugs. Tell this to the user and save the details for the technical staff.
Although needs and constraints, exception hierarchies, and notification mechanisms will differ across projects, many elements remain constant. So why not go whole hog and implement common policies in a framework? A framework followed by simple rules of usage is the best way to enforce a policy. Executable artifacts talk to developers, and it is easier to preach architectural principles with a jar file and some Javadoc than with whitepapers and slide shows.
However, you cannot ask the development team to postpone error handling until a policy and complementing framework support is ready. Error handling must already be determined when the first source file is created. A good place to start is by defining the fundamental exception hierarchy.
A basic exception hierarchy
Our first practical task is to define an exception hierarchy common enough to be used across projects. The base class for our own unchecked exceptions is UnrecoverableException, a name that, for historical reasons, remains slightly misleading. You might consider a better title for your own hierarchies.
When you want to get rid of a checked exception, one that, conceivably, clients will always be able to handle, WrappedException offers a simple, generic transport mechanism: wrap and throw. The WrappedException keeps the cause as an internal reference, which works well when the classes for the original exception are still available. When this is not the case, use SerializableException, which resembles WrappedException except that it can be used when no assumptions are made on available libraries at the client side.
Although we prefer and recommend unchecked exceptions, you might keep checked exceptions as an option. The InstrumentedException interface acts as an interface for both checked and unchecked exceptions that follow a certain pattern of attribute implementation. The interface allows exception consumers to consistently inspect the source—whether it inherits from a checked or an unchecked base.
The class diagram below shows our basic exception hierarchy.

Figure 1. A basic exception hierarchy
At this point, we have a strategy and a set of exceptions that can be thrown. It is time to build the safety net.
The last line of defense
The article "Create an Application-Wide User Session" presented Rampart, a layered architecture consisting of an enterprise information system tier, a business logic tier made from stateless session beans, and a client tier with both Web and standalone J2SE clients. Exceptions can be thrown from all tiers in this architecture, and can either be handled on site or bubble up until they reach the end of the call chain. Then what? Both J2SE and J2EE application servers guard themselves against offensive behavior by catching stray Errors and RuntimeExceptions, and by dumping the stack trace to System.out, logging it, or performing some other default action. In any case, if a user is presented with any kind of output, mostly likely, it will prove absolutely meaningless, and, worse, the error will probably have disrupted program stability. We must install our own rampart to provide a more sound exception-handling mechanism for this last line of defense.
Consider Figure 2:

Figure 2. Exception paths in the sample architecture
Exceptions may occur on the server side in the EJB (Enterprise JavaBeans) tier and in the Web tier, or on the standalone client. In the first case, exceptions stay in the VM from which they originated as they make their way up to the Web tier. This is where we install our top-level exception handler.
In the standalone case, exceptions eventually reach the rim of the EJB container and travel along the RMI (remote method invocation) connection to the client tier. Care must be taken not to send any exceptions belonging to classes that live only on the server side, e.g., from object-relational mapping frameworks or the like. The EJB exception handler handles this responsibility by using SerializableException as a vehicle. On the client side, a top-level Swing exception handler catches any stray errors and takes appropriate action.
Exception-handler framework
An exception handler in the Rampart framework is a class that implements the ExceptionHandler interface. This interface's only method takes two arguments: Throwable, to handle, and the current Thread. For convenience, the framework contains an implementation, ExceptionHandlerBase, which tastes Throwable and delegates handling to dedicated abstract methods for the flavors RuntimeException, Error, Throwable, and the Rampart-specific Unrecoverable. Subclasses then provide implementations for these methods and handle each situation differently.
The class diagram below shows the exception-handler hierarchy with its three default exception handlers.

Figure 3. Exception-handler hierarchy. Click on thumbnail to view full-sized image.
Some among The Order of the Unchecked believe that Sun should have added hooks into all containers in the J2EE architecture on a per-application basis. This would have allowed custom error-handling schemes, security, and more to be gracefully installed, without reliance on vendor-specific schemes and frameworks. Unfortunately, Sun failed to provide such mechanisms in the EJB specification; so, we pull out the AOP hammer from our toolbox and add exception handling as around-aspects. AspectWerkz, our chosen AOP framework, uses the following aspect for that task:
public class EJBExceptionHandler implements AroundAdvice { private ExceptionHandler handler; public EJBExceptionHandler() { handler = ConfigHelper.getEJBExceptionHandler(); } public Object invoke(JoinPoint joinPoint) throws Throwable { Log log = LogFactory.getLog(joinPoint.getEnclosingStaticJoinPoint().getClass().getName()); log.debug("EJB Exception Handler bean context aspect!!"); try { return joinPoint.proceed(); } catch (RuntimeException e) { handler.handle(Thread.currentThread(), e); } catch (Error e) { handler.handle(Thread.currentThread(), e); } return null; } }
The actual handler is configurable and obtained through the ConfigHelper class. If a RuntimeException or Error is thrown during execution of the bean business logic, the handler will be asked to handle it.
The DefaultEJBExceptionHandler serializes the stack trace of any exception not originating from Sun's core packages into a dedicated SerializableException, which, on the plus side, allows the stack trace of exceptions whose classes don't exist on remote clients to be propagated over anyway. On the downside, the original exception is lost in translation.
EJB containers faithfully take any RuntimeException or Error and wrap it in a java.rmi.RemoteException, if the client is remote, and in a javax.ejb.EJBException, otherwise. In the interest of keeping causes precise and stack traces at a minimum, the framework peels off these transport exceptions inside client BusinessDelegates and rethrows the original.
A Rampart BusinessDelegate class exposes an EJB-agnostic interface to clients, while wrapping local and remote EJB interfaces internally. BusinessDelegate classes are generated via XDoclet from EJB implementation classes and follow the structure shown in Figure 4's UML diagram:

Figure 4. An example BusinessDelegate
The BusinessDelegate class exposes all business methods from the source EJB implementation class and delegates to the LocalProxy class or the RemoteProxy class as appropriate. Internally, the two proxies handle EJB-specific exceptions and, hence, shield the calling BusinessDelegate from implementation details. The code below is a method from some LocalProxy class:
public java.lang.String someOtherMethod() { try { return serviceInterface.someOtherMethod(); } catch (EJBException e) { BusinessDelegateUtil.throwActualException(e); } return null; // Statement is never reached }
The serviceInterface variable represents the EJB local interface. Any EJBException instances thrown by the container to indicate an unexpected error are caught and handled by the BusinessDelegateUtil class, in which the following action takes place:
public static void throwActualException(EJBException e) { doThrowActualException(e); } private static void doThrowActualException(Throwable actual) { boolean done = false; while(!done) { if(actual instanceof RemoteException) { actual = ((RemoteException)actual).detail; } else if (actual instanceof EJBException) { actual = ((EJBException)actual).getCausedByException(); } else { done = true; } } if(actual instanceof RuntimeException) { throw (RuntimeException)actual; } else if (actual instanceof Error) { throw (Error)actual; } }
The actual exception is extracted and rethrown to the top-level client exception handler. When the exception reaches the handler, the stack trace will be that of the original exception from the server containing the actual error. No superfluous client-side trace is added.
Swing exception handler
The JVM provides a default top-level exception handler for each control thread. When exercised, this handler dumps the stack trace of Error and RuntimeException instances onto System.err and kills the thread! This rather obstructive behavior is quite far from anything a user needs and not elegant from a debugging perspective. We want a mechanism that allows us to notify the user while retaining the stack trace and a unique request ID for later debugging. "Create an Application-Wide User Session for J2EE" describes how such a request ID becomes available at all tiers.
For J2SE versions up to 1.4, uncaught exceptions in Thread instances cause the owner ThreadGroup's uncaughtException() method to execute. A simple way to control exception handling in an application, then, is to simply extend the ThreadGroup class, overwrite the uncaughtException() method, and ensure all Thread instances start within an instance of the custom ThreadGroup class.
J2SE 5 provides an even sweeter mechanism by allowing the installation of an UncaughtExceptionHandler implementation on instances of the Thread class itself. The handler is used as a callback mechanism when uncaught exceptions reach the Thread instance's run method. We built the framework with J2SE 1.3+ compatibility in mind; hence we used the ThreadGroup inheritance approach:
Swing exception handler
private static class SwingThreadGroup extends ThreadGroup { private ExceptionHandler handler; public SwingThreadGroup(ExceptionHandler handler) { super("Swing ThreadGroup"); this.handler = handler; } public void uncaughtException(Thread t, Throwable e) { handler.handle(t, e); } }
The SwingThreadGroup class shown in the code snippet above overrides the uncaughtException() method and passes the current Thread instance and the thrown Throwable to the configured exception handler.
A little more magic is needed before we can claim control of all stray exceptions in the client tier. For the scheme to work, all threads must be associated with our specialized SwingThreadGroup instance. This is accomplished by spawning a new master Thread instance and passing the SwingThreadGroup instance with a Runnable implementation, which executes the entire main program. All Thread instances spawned from the body of this new master Thread instance automatically join the SwingThreadGroup instance and, hence, use our new exception handler when unchecked exceptions are thrown.

Figure 5. Swing exception handler class hierarchy. Click on thumbnail to view full-sized image.
The framework implements this logic in the SwingExceptionHandlerController convenience class shown in Figure 5. Applications provide an implementation of the SwingMain interface along with an exception handler to the controller. The controller must then be started, and the old main Thread can join the new one and wait for termination. The code below shows how the demo application that accompanies this article accomplishes that task. The method createAndShowGUI() constitutes the actual application body, which initializes Swing components and transfers control to the user.
public DemoApp() { SwingExceptionHandlerController.setHandler(new DefaultSwingExceptionHandler()); SwingExceptionHandlerController.setMain(new SwingMain() { public Component getParentComponent() { return frame; } public void run() { createAndShowGUI(); } }); SwingExceptionHandlerController.start(); SwingExceptionHandlerController.join(); }
The last line of defense is now in place for the Swing layer, but we still need to provide a meaningful message to the user. The demo application supplies a rather basic implementation that simply displays a dialog box with an internationalized message and the unique request ID as a support ticket. At the same time, the exception is logged via log4j along with the unique request ID. A more sophisticated error handler might send an email, SNMP message, or the like to technical support with the ID in it. The point is that both client and server logs can be filtered on the support ticket ID to allow precise pinpointing of errors on a per-request basis.
Figure 6 shows merged Swing client and J2EE server logs to provide the precise flow for the request with ID 1cffeb4:feb53del38:-7ff6, where an exception was thrown. Note that the stack trace contains only information from the server side, where the exception was thrown.

Figure 6. Log trace from both client and server with request ID and server stack trace. Click on thumbnail to view full-sized image.
While the infrastructure for adding exception handling to standalone J2SE applications is basic, things are different as we move to Web-based clients.
WAR exception handler
Web applications are among the fortunate components in the J2EE world to have their own explicit way of installing exception-handling capabilities. Through the web.xml deployment descriptor, exceptions and HTTP errors can be mapped to error pages in the shape of servlets or JavaServer Pages (JSP) pages. Consider the following fragment from a sample web.xml file:
<servlet> <servlet-name>ErrorHandlerServlet</servlet-name> <servlet-class>dk.rhos.fw.rampart.util.errorhandling.ErrorHandlerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ErrorHandlerServlet</servlet-name> <url-pattern>/errorhandler</url-pattern> </servlet-mapping> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/errorhandler</location> </error-page>
These tags direct all uncaught exceptions to the URL /errorhandler, which in this case is mapped to the ErrorHandlerServlet class. The latter is a dedicated servlet whose sole raison d'etre is to act as a bridge between Web components and the exception-handling framework. When an uncaught exception from this Web application reaches the servlet container, a set of parameters with information about the exception will be added to the HttpServletRequest instance and passed to the ErrorHandlerServlet class's service method. The fragment below shows the service() method:
... private static final String CONST_EXCEPTION = "javax.servlet.error.exception"; ... protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException { Throwable exception = (Throwable)httpServletRequest.getAttribute(CONST_EXCEPTION); ExceptionHandler handler = ConfigHelper.getWARExceptionHandler(); handler.handle(Thread.currentThread(), exception); String responsePage = (String)ConfigHelper.getRequestContextFactory(). getRequestContext(). getAttribute(ExceptionConstants.CONST_RESPONSEPAGE); if(responsePage == null) { responsePage = "/error.jsp"; } httpServletResponse.setStatus(HttpServletResponse.SC_OK); RequestDispatcher dispatcher = httpServletRequest.getRequestDispatcher(responsePage); try { dispatcher.include(httpServletRequest, httpServletResponse); } catch (Exception e) { log.error("Failed to dispatch error to responsePage " + responsePage, e); } }
In the service() method, first, the actual exception from the HttpServletRequest instance is retrieved through the key javax.servlet.error.exception. Next, the exception handler instance is retrieved. From there on, the handler is invoked, and the HttpServletRequest instance is forwarded to the page specified by the key rampart.servlet.exception.responsepage.
The DefaultWARExceptionHandler class looks up an internationalized text based on the exception message and redirects output response to the JSP /error.jsp. This page is then free to display the message to the user, including the current request ID as a support ticket. A much more sophisticated mechanism can easily be implemented by simply extending or replacing this handler.
Wrap up
Often, exception handling is not handled stringently enough, thereby complicating debugging and error tracking, and, many times, disrupting the overall user experience. It is therefore crucial to have policies and frameworks in place before system development starts. Adding this aspect as an afterthought is doable, but time consuming and expensive.
This article has armed you with a starting point for defining an exception policy and introduced you to a simple, yet extensible, unchecked exception hierarchy. We have walked through business and client tiers of a sample J2EE architecture and shown how you can install top-level exception handlers for each tier to provide a last line of defense. The framework code has given you a way to precisely pinpoint errors on a per-user request basis through the unique request ID attached to exceptions and log entries.
So download the framework, try it out, modify it to your heart's delight, and get those exceptions under control.
相关推荐
内容概要:本文详细介绍了新能源电动汽车中VCU(车辆控制单元)和BMS(电池管理系统)的硬件在环(HIL)仿真技术及其重要性。文中阐述了VCU和BMS在电动汽车中的角色,解释了硬件在环仿真技术的概念及其在电动汽车研发中的应用。重点讨论了电动汽车整车建模的方法,涵盖驾驶员模块、仪表模块、BCU整车控制器模块、MCU电机模块、TCU变速箱模块、减速器模块、BMS电池管理模块等多个子系统的建模。此外,文章还探讨了HIL仿真的具体应用场景和优势,强调其在降低成本、提高效率和安全性方面的作用。 适合人群:从事新能源汽车研发的技术人员、研究人员及相关领域的学生。 使用场景及目标:适用于希望深入了解电动汽车VCU和BMS硬件在环仿真技术的研究人员和技术人员,旨在帮助他们掌握相关技术和工具,提升电动汽车的研发和测试能力。 其他说明:文章提供了详细的模块介绍和仿真技术的应用案例,有助于读者更好地理解和应用HIL仿真技术于实际项目中。
内容概要:本文介绍了利用MATLAB代码实现的综合能源系统优化调度模型,重点在于结合绿色证书(Green Certificates)和综合需求响应(Integrated Demand Response),以提升系统总收益并兼顾环境效益。文中详细描述了模型的构建过程,包括定义决策变量、目标函数和约束条件,并通过yalmip工具包结合gurobi/cplex求解器进行了求解。此外,通过多个场景的算例分析验证了模型的有效性和优越性。 适合人群:对综合能源系统优化调度感兴趣的科研人员、工程师以及相关专业的学生。 使用场景及目标:适用于需要优化能源系统调度的研究项目或工业应用,特别是在考虑可再生能源消纳责任权重的情况下,旨在提高系统经济效益的同时减少碳排放,实现绿色环保的目标。 其他说明:该模型不仅有助于学术研究,也为实际工程提供了有价值的参考。通过对不同场景的模拟,可以更好地理解和应对未来的能源挑战。
内容概要:本文详细介绍了利用COMSOL软件模拟水泥浆在岩石裂隙中扩散的过程,特别是关注浆液粘度随时间的变化(时变性)。首先,通过MATLAB生成随机裂隙网络,并将其导入COMSOL进行几何建模。然后,设置物理场,采用自由流动模型用于裂隙通道,而多孔介质则使用达西定律,两者相互耦合。对于粘度时变性,引入自定义材料属性,设定初始粘度和凝固速率。求解过程中,先进行稳态计算获得初始条件,再用瞬态求解器逐步推进。文中还讨论了网格划分技巧以及如何优化求解器配置以确保数值稳定性。最终展示了不同时间点下浆液扩散形态,如分形特征和涡旋结构,并探讨了凝固速率对扩散范围的影响。 适用人群:从事岩土工程、地质勘探、水利工程等相关领域的科研人员和技术工程师。 使用场景及目标:适用于研究复杂地质条件下注浆加固技术的应用,旨在提高对浆液扩散规律的理解,从而优化施工工艺和参数选择。 其他说明:文中提供了具体的数学公式和代码片段,帮助读者更好地理解和复现实验结果。同时强调了实际工程中可能遇到的问题及解决方案。
实训商业源码-婚纱店官网小程序模板-毕业设计.zip
内容概要:本文介绍了基于改进SMO滑模观测器的转子磁链模型在PMSM(永磁同步电机)无传感器矢量控制中的应用。传统的SMO滑模观测器在带载转速抖动和低转速估算方面存在问题,而改进后的方案通过引入转子磁链幅值计算、动态调整滑模面参数K_sw以及优化锁相环部分的非线性积分项,显著提高了角度观测精度并解决了这些问题。实验结果显示,在10%额定转速下,角度误差由±5度缩小到±1.2度;满负载情况下,转速波动从±30rpm降低到±8rpm;电机反转瞬间,角度重锁定时间缩短至20ms以内。 适合人群:从事电机控制系统研究与开发的技术人员,特别是关注PMSM无传感器矢量控制领域的研究人员和技术爱好者。 使用场景及目标:适用于需要提高PMSM无传感器矢量控制系统的性能,特别是在低转速和负载变化频繁的应用场合。目标是减少转速抖动,提高角度估算精度,加快响应速度。 其他说明:尽管改进方案对电机参数较为敏感,但由于PMSM的特性使得这种敏感性在实际应用中得到了较好的控制。未来的研究方向可能包括在线参数辨识,进一步提升系统的自适应能力。
实训商业源码-喝酒神器微信小程序源码-毕业设计.zip
数据集介绍:无人机视角水域目标检测数据集 一、基础信息 数据集名称:无人机视角水域目标检测数据集 图片数量: - 训练集:2,752张图片 - 验证集:605张图片 分类类别: - Boat(船只):水域交通与作业场景中的常见载具 - Buoy(浮标):水域导航与安全标志物 - Jetski(喷气滑艇):高速水上运动载具 - Kayak(皮划艇):小型人力划桨船只 - Paddle_board(桨板):休闲运动类浮板 - Person(人员):水域活动参与者的目标检测 标注格式: YOLO格式标注,含目标边界框与类别标签,适配主流目标检测框架 数据特性: 无人机航拍视角数据,覆盖不同高度与光照条件的水域场景 二、适用场景 水域智能监测系统开发: 支持构建船只流量统计、异常行为检测等水域管理AI系统 水上救援辅助系统: 用于训练快速定位落水人员与小型船只的检测模型 水上运动安全监控: 适配冲浪区、赛艇场等场景的运动安全预警系统开发 环境生态研究: 支持浮标分布监测、水域人类活动影响分析等研究场景 三、数据集优势 视角独特性: 纯无人机高空视角数据,有效模拟真实航拍检测场景 目标多样性: 覆盖6类水域高频目标,包含动态载具与静态标志物组合 标注精准性: 严格遵循YOLO标注规范,边界框与目标实际尺寸高度吻合 场景适配性: 包含近岸与开阔水域场景,支持模型泛化能力训练 任务扩展性: 适用于目标检测、运动物体追踪等多任务模型开发
内容概要:本文详细介绍了如何利用多尺度一维卷积神经网络(MS-1DCNN)在PyTorch框架下进行轴承故障诊断。首先,通过对凯斯西储大学(CWRU)提供的轴承数据集进行预处理,提取振动信号并将其转换为适合模型输入的格式。然后,构建了一个包含三个不同尺度卷积核的MS-1DCNN模型,能够捕捉到不同时间尺度的特征。接下来,采用AdamW优化器和余弦退火学习率调度器对模型进行了训练,并加入了早停机制以避免过拟合。最终,在验证集上实现了超过97.5%的高精度。此外,还展示了如何使用混淆矩阵对预测结果进行可视化。 适合人群:对机器学习尤其是深度学习感兴趣的初学者以及从事机械故障诊断的研究人员。 使用场景及目标:本教程旨在帮助读者掌握从数据准备到模型部署的完整故障诊断流程,特别适合希望快速入门故障诊断领域的学生和技术人员。 其他说明:文中提供了详细的代码片段,涵盖了数据读取、预处理、模型定义、训练及评估等多个方面,确保读者能够复现实验结果。同时,针对可能出现的问题给出了相应的解决方案。
内容概要:本文介绍了一款基于YOLOv5的手势识别系统,该系统整合了Python、PyTorch、CUDA和PyQt5等技术,实现了对四种手势的实时识别。文中详细阐述了系统的各个组成部分和技术背景,包括数据集的准备、模型的训练与优化、用户界面的设计与实现。此外,还强调了系统的灵活性和扩展性,允许用户自定义数据集以识别更多种类的手势。 适合人群:对机器学习、深度学习感兴趣的开发者,尤其是希望通过实际项目深入理解YOLOv5及其应用场景的研究人员和工程师。 使用场景及目标:适用于需要快速部署手势识别功能的项目,如人机交互、智能家居、虚拟现实等。目标是提供一个易于使用的工具包,帮助用户快速上手并根据自身需求进行定制化开发。 其他说明:该系统不仅提供了完整的代码和数据集,还附带详细的代码注释和操作指南,便于用户理解和修改。
内容概要:本文详细介绍了利用CST Studio进行极化转换和非对称传输仿真的方法和技术要点。首先讲解了如何通过参数化建模构建用于极化转换的关键结构(如箭头型金属贴片),并强调了参数化设计的优势。接着讨论了边界条件和端口设置的具体步骤,确保仿真结果的准确性。随后提供了电场矢量图的后处理脚本,帮助直观判断极化转换的效果。最后探讨了非对称传输特性的验证方法,包括参数扫描和数据处理技巧。文中还分享了一些常见的仿真陷阱及其解决方案。 适合人群:从事微波工程、天线设计以及电磁兼容性研究的专业人士,尤其是有一定CST仿真经验的研究人员。 使用场景及目标:适用于需要深入理解和掌握CST仿真工具在极化转换和非对称传输领域的应用场合。目标是提高仿真精度,优化设计方案,缩短研发周期。 其他说明:文章不仅提供具体的技术细节,还包括实用的经验分享和避坑指南,有助于读者快速上手并解决实际问题。
内容概要:本文详细介绍了如何在COMSOL中实现高斯光束、超高斯光束以及贝塞尔光束的方法及其操作难点。首先解释了高斯光束的基本概念和实现方式,指出COMSOL内置的高斯背景场存在局限性,并提供了自定义束腰半径和相位曲率的具体公式。接着讨论了超高斯光束的特点及其在光刻胶模拟中的应用,强调了非线性折射率设置的重要性。对于贝塞尔光束,则重点讲解了柱坐标系的应用及避免边界反射的方法。此外,还分享了一些实用技巧,如利用探针函数监控相位分布、通过事件接口实现动态束腰调节等。 适用人群:从事光学仿真研究的专业人士,尤其是那些需要在COMSOL中进行复杂光束仿真的研究人员和技术人员。 使用场景及目标:帮助用户掌握在COMSOL中创建不同类型光束的技术要点,解决实际操作过程中可能遇到的问题,提高仿真精度和效率。 其他说明:文中不仅提供了详细的数学表达式,还给出了具体的实施步骤和注意事项,确保读者能够顺利地将理论应用于实践。同时,作者还分享了许多个人经验,使文章更具指导性和实用性。
内容概要:本文详细介绍了基于IEEE9三机九节点的经典电力系统模型,在Simulink环境下实现了风电并网、储能系统和SVC(静态无功补偿器)的集成。首先,构建了基本的三机九节点模型,然后分别引入了风力发电模块、电池储能模块和SVC模块,通过调整各模块参数,模拟了不同条件下电力系统的动态行为。实验结果显示,风电并网使系统输出随风速波动,储能系统能平衡供需,SVC提高了系统的稳定性。 适合人群:从事电力系统研究、可再生能源接入、智能电网建设和电力系统稳定性分析的专业人士和技术爱好者。 使用场景及目标:适用于需要对现代电力系统进行建模和仿真的场合,特别是关注风电并网、储能技术和SVC应用的研究人员。目标是提升对复杂电力系统的理解和优化能力。 其他说明:文中提供的MATLAB/Simulink代码片段展示了具体实现方法,便于读者动手实践。同时,对未来模型扩展的方向提出了展望,如增加更多类型的可再生能源和复杂控制策略。
实训商业源码-多用途响应式ppt资源下载平台html模板-毕业设计.zip
美容美发营销版 最新版v1.9.6.zip
基于深度学习的云端大数据安全防护技术.pdf
vlife是一款模型驱动的低代码平台,编写模型即可轻松完成全栈功能开发。对于更复杂的业务逻辑,提供了强大的配置功能和低代码开发能力,极大地提升了开发效率和质量
内容概要:本文详细介绍了利用Matlab实现K-Means聚类算法的具体步骤,包括如何设定聚类数目、保存聚类结果以及对结果进行可视化呈现。文中提供了完整的代码实例,从加载数据到最终绘制聚类效果图,每一步都有详细的注释解释。此外,还分享了一些常见的注意事项,如数据标准化处理、K值的选择方法(肘部法则)以及确保结果可重复性的技巧。通过这些指导,可以帮助初学者快速掌握K-Means聚类的基本操作流程。 适合人群:对机器学习感兴趣的学生、研究人员或工程师,尤其是那些希望通过Matlab工具来理解和应用K-Means聚类算法的人群。 使用场景及目标:适用于需要对多维数据集进行分类或分组的研究项目,目的是找到数据内部潜在的结构模式。具体应用场景包括但不限于市场细分、图像压缩、异常检测等领域。通过本教程的学习,读者能够独立完成简单的K-Means聚类任务,并能根据实际情况调整参数优化模型性能。 其他说明:为了提高代码的通用性和易用性,作者建议将绘图部分分离出来作为独立的子函数,以便于后续扩展和维护。同时,对于想要深入研究的朋友,还可以进一步探索更多高级特性和改进措施。
实训商业源码-漫画小程序-毕业设计.zip
太阳影子定 位模型的研究及应用.pdf
内容概要:本文详细介绍了单相H桥级联五电平逆变器的SPWM调制闭环仿真方法及其优化要点。首先解释了H桥级联的基本概念,接着阐述了SPWM调制的具体实现方式,包括载波相位错开90度的设计思路。文中还重点讲解了闭环控制系统的设计,特别是电压外环加电流内环的双环控制结构以及PID参数的整定方法。此外,对仿真过程中需要注意的关键波形进行了细致分析,如载波与调制波的交互、桥臂输出电压的合成效果等。最后讨论了谐波抑制措施,强调了LC滤波器的作用。 适合人群:从事电力电子、电机驱动等领域研究的技术人员,尤其是对逆变器仿真感兴趣的工程师。 使用场景及目标:适用于需要进行逆变器性能评估、优化设计的研究项目。主要目标是帮助读者掌握单相H桥级联五电平逆变器的工作原理,学会搭建并优化其仿真模型,提高系统的稳定性和效率。 其他说明:提供了完整的Simulink仿真模型文件,支持不同MATLAB版本(含2018a),便于读者直接上手实践。同时给出了详细的参数配置建议,确保初学者也能顺利完成仿真任务。