Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
{float:side=right}{panel:title=Contents|borderStyle=solid|borderColor=black}{toc:minLevel=1|maxLevel=3}{panel}{float}

The Exception sensorSensor is used to gather information about exceptionsExceptions in an application. The Exception TracerSensor is able to trace _created_, _thrown_, and _handled_ exceptionsExceptions within a target application. The Exception TracerSensor gathers information about *methods* and *constructors* that can cause an Exception. It must be specified You have to specify in the configuration file which classes should be instrumented. There can be as many Exception TracerSensor configurations defined as you like.

h2. Description

The lifecycle of an Exception consists of the following three events. These events are traversed by the JVM when an exceptionException is _created_, _thrown_, and _handled_. To get the whole exceptionException lifecycle, all events are needed.
# Object creation \-> _Exception ex = new Exception()_;
# Throwing of Exception \-> _throw ex_;
# Exception Handling \-> _catch(Exception ex)_

These three events are of interest for the Exception sensorSensor. They show the easiest case of an Exception Lifecycle. To gather information about exceptionsExceptions, these events are instrumented at different points in the target application. For the first event all constructors of a Throwable class are instrumented at load-time. For the second event, a method is instrumented using the Javassist method addCatch() (addCatch() makes it possible to handle exceptions internally \-> better: to gather information when an exception is thrown by the Java API or by the developer). To gather information when an exception is handled, a handler is instrumented with an insertBefore().
To be able to instrument methods and constructors (which can cause an exception) with the Exception Tracer, these methods/constructors must first be instrumented f.e. with the timer sensor, otherwise you will get only information when an exception object is created, but there will be no information about the last two events.

h2. Configuration


To enable the Exception Tracer, the name together with the fully-qualified-name of the class to instrument must be defined. As an optional parameter it is possible to enable superclass or interface matching support. The Exception sensor name must always be defined as *exception-sensor{*}in the configuration file, so there is no need to write down the fully-qualified name of this sensor type. There is no limit in how many{_}exception-sensor_ configurations can be defined. When defining multiple _exception-sensor_ lines, there is always only one Exception Tracer created, which has one or more configurations.

{code}exception-sensor [Exception Class] [options]
{code}

{tip} In contrast to method sensor types where the definition will provide the name of the class/method on which the sensor is to be applied, the exception sensor needs the name of the Exception class that should be traced. {tip}
The exception sensor is able to use Wildcards (see [ARCHIVE:Agent configuration]) for the definition of the class name. The options can be used to define that the provided exception class should be treated as interface or superclass (see the superclasses and interfaces chapter in [ARCHIVE:Agent configuration]).

h4. Examples

The next table provides samples of how the exception tracer can be used. Bear in mind, that you can define multiple exception-sensors.
|| Configuration \\ || Description ||
| exception-sensor java.lang.Throwable superclass=true | Classes are instrumented that directly or indirectly extend _java.lang.Throwable_. The class _java.lang.Throwable_ itself is *not* instrumented. |
| exception-sensor my.package.exception.MyException | Only the class _my.package.exception.MyException_ is instrumented. |
| exception-sensor my.package.ex*.*Exception | All classes are instrumented that match the pattern (like _my.package.exception.ParserException_ and _my.package.extension.ExtensionException_). |
| exception-sensor my.package.exception.IException interface=true | All classes are instrumented that are implementing the interface _my.package.exception.IException_. |
| exception-sensor my.package.exception.My*Exception | Classes like _my.package.exception.MyException_ and _my.package.exception.MyTestException_ are instrumented. |
| exception-sensor * | Every class of type _Throwable_ is instrumented. |
| exception-sensor my.pack*.ex*.\* superclass=true | Classes are instrumented which are extending the class that matches the pattern my.pack*.ex*.\* |

h2. Visualization

In the below picture you can see how the Exception Tracer is represented in the main menu of the User Interface. Currently there are two elements which can be selected. The element _Exception Tree{_}shows all Exceptions and allows a tree-like analysis of this Exception. It is also possible to get access to the stack trace of this specific Exception. In the _Exception Overview_ you can see an overview over different Exception classes and f.e. how often a specific Exception class was handled.

The following means of visualization are provided by the exception sensor.

|| Visualization \\ || Screenshot (click to enlarge) \\ || Description \\ ||
| *Exception overview* \\ | !Exception_Overview.png|thumbnail!\\ | * Provides an overview of all exceptions that were thrown by the system.
* Provides the count of all events of these exceptions |
| *Exception tree* \\ | !ExceptionTreeDetails.png|thumbnail!\\ | * Illustrates where exceptions are thrown, were they are catched and where they are handled
* This is very time-consuming as for each and every exception a trace is created |
| *Exception stacktrace* \\ | !ExceptionTreeStackTrace.png|thumbnail!\\ | * Provides the stacktrace of an exception |
When the JVM traverses the different points in the lifecycle of an exception, a data object is created at each event. Depending on the event this data object is marked with an event type. The below list gives an overview.
* *CREATED*: describes the creation of the exception object.
* *PASSED*: describes the implicit passing of the exception object by the JVM (the JVM passes the exception object when it searches for an appropriate handler). This event type also describes the first explicit _throw_ of an exception.
* *UNREGISTERED-PASSED*: describes the passing of an exception object which was not registered before and has no parent.
* *RETHROWN*: describes an explicit rethrowing of an exception by reusing the object => f.e.: catch(Exception e) \{ throw e; \}
* *HANDLED*: describes the handling of an exception object.

h2. Dealing with not instrumented paths


h3. Standard process



{float:side=right}
{code:title=Rethrowing exceptions}try {
    bar();   // method throws a MyException
} catch(MyException e) {
    // do some stuff
    throw e;
}
{code}
{float}

{float:side=right}
{code:title=Throw a new exception}
try {
    bar();   // method throws a MyException
} catch(MyException e) {
    // do some stuff
    throw new MyException();
}
{code}
{float}

The below picture shows the simplest case in a lifecycle of an Exception. The exception is created and thrown in an instrumented method (method read()), and afterwards handled at another position in the call tree (method create()). After catching the exception object, this object is not needed anymore and made eligible for the GC. But an exception can also be handled rethrown by reusing the exception object. This case is shown in the code snippet below. The lifecycle of the object doesn't end after the object was handled. The object is rethrown and the lifecycle continues until the next handler is found. An exception object can also be handled and rethrown by creating a new exception object of the same type. This case is shown in the code snippet below. The lifecycle of the handled exception is finished and a new exception lifecycle is started (by creating a new exception object).

 !exception_flow.png|width=419,height=375!

h3. Not instrumented paths

On the above examples all methods within a target application where instrumented. But with inspectIT we only want to instrumented specific parts (f.e. only methods that are within a specified starting point). Due to this fact, it is possible that events of throwing/handling an exception cannot be gained. The event of an exception object creation is always obtained, because all constructors of a Throwable class are instrumented at load-time (the event is also obtained when the exception object is created on a not instrumented path). The below description shows some possibilities, where not all events of an exception can be obtained.

!exception_flow_notInstrumented.png|thumbnail!

In the below picture the methods read() and getInput() can throw an exception of the same type. In this example an exception is created/thrown in the method getInput(), which is not instrumented. The exception object is then passed along the call stack and the JVM searches for a suitable handler. We are getting events of the creation and the handling of the exception object, but not the throwing. This is because the throwing event is on a not instrumented path (the object creation is also on a not instrumented path, but this event is gained due to the fact that all Throwable constructors are instrumented at load-time).

!exception_flow_handlerNotInstrumented.png|thumbnail!

It is also possible that an exception is created, thrown, and handled on a path which is not instrumented. This example is shown in the below picture. Due to not instrumented paths, we are getting only the creation event, but not the throwing/handling event.

!exception_flow_notInstrumentedPath.png|thumbnail!