JBoss.org Community Documentation
As shown in Table 4.1, “Annotated Parameters Table”, the presence of a @Thrown
annotated parameter
can be mandatory depending on the advice type and its parameters.
This annotation is available only for after-throwing and finally advices. For after-throwing advices this parameter is always mandatory:
public class Aspect { public void throwing1(@Thrown RuntimeException thrownException) { ... } public void throwing2() { ... } } <aop> <aspect class="Aspect"/> <bind pointcut="..."> <throwing aspect="Aspect" name="throwing1"/> <throwing aspect="Aspect" name="throwing2"/> </bind> </aop>
The advice throwing1
follows this rule; advice throwing2
,
on the other hand, is invalid, because it does not contain the mandatory @Thrown
annotated parameter.
For finally advices, the @Thrown
annotation is compulsory only if a
@Return
annotated parameter is present. This way, a finally advice can identify
whether the return value is valid or not. If the @Thrown
parameter is
null
, it means that the joinpoint returned normally and that the value contained in
the @Return
annotated-parameter is valid. Otherwise, the value contained in
@Return
annotated parameter must be ignored (it will be null
if
the return type is not primitive, 0
if it is a primitive number or false
if it is boolean). If the finally advice does not receive the joinpoint return value, the use of the
@Thrown
annotated parameter is optional and, as expected, its value will be
null
if the joinpoint being intercepted did not throw an exception. Take a look at the
next example:
public class Aspect { public void finally1(@Thrown Throwable thrownException) { ... } public void finally2() { ... } public void finally3(@Return int returnedValue, @Thrown Throwable thrownException) { if (thrownException == null) { //We returned normally, the @Return parameter is valid int i = returnedValue; } else { //An exception happened while invoking the target joinpoint //The return value is invalid } } public void finally4(@Return int returnedValue) { ... } } <aop> <aspect class="Aspect"/> <bind pointcut="execution(public int *->*(..))"> <finally aspect="Aspect" name="finally1"/> <finally aspect="Aspect" name="finally2"/> <finally aspect="Aspect" name="finally3"/> <finally aspect="Aspect" name="finally4"/> </bind> </aop>
This example binds four finally advices to the execution of all public methods that return an int value. Take note on the
type of the @Thrown
-annotated parameters, which must be Throwable
for this type of
advice.
The presence of @Thrown
is not mandatory in advices finally1()
and finally2()
, because they do not have a @Return
annotated parameter.
Hence, both advices are valid. Besides, finally1()
will receive a non-null exception only
when the joinpoint being intercepted throws an exception.
For advice method finally3()
the presence of a @Thrown
annotated parameter
is mandatory because this advice also has a @Return
annotated parameter. If an exception
happens when invoking the target joinpoint, this advice will receive a non-null @Thrown
parameter,
meaning that the @Return
annotated parameter is invalid. If the joinpoint completes normally,
the @Thrown
annotated parameter will be null
and the @Return
annotated parameter will contain the return value of the target joinpoint.
The finally4()
advice is invalid, it contains a @Return
parameter, but has no
@Thrown
annotated parameter. Finally advices require a @Thrown
parameter if a
@Return
annotated parameter is present.