Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-dev] Can aspects throw checked exceptions which are declared on the join point but not referenced on the point cut?

A similar question has been asked many times, but this one is a slightly more limited case which I think could and should be supported.

First, what is the use case? Function objects. My function object has a run() method which throws Exception declared on an API I don't control. I want to wrap it in around() advice. By the time any exception thrown from proceed() gets back to my advice, it is typed as a generic Exception. I can determine its type and compare it to the join point but I have no way to let AspectJ know that it is safe to throw.

Of course any checked exception thrown from within an aspect must be compatible with the checked exceptions declared for the current join point. However, AspectJ's limitation is currently more restrictive. It requires that any exception thrown from within an aspect must be compatible with the checked exceptions declared for the point cut.

If I want to know whether an exception is compatible with the throws clause of the join point, I can use the following code in my advice:

boolean isExceptionAllowed(Exception e) {
  CodeSignature cs = (CodeSignature) thisJoinPointStaticPart.getSignature();
  Class[] exceptionTypes = cs.getExceptionTypes();
  for (Class<?> exceptionType : exceptionTypes) {
    if (exceptionType.isInstance(e)) {
      return true;
    }
  }
  return false;
}

After getting true from that method, I know that I should be allowed to throw the exception. However I still can't throw it without casting it to a type which is declared on the point cut. I might not know this type. Or there might be a large number. Or they might be different for different join points (all specified by the same point cut).

On the other hand, I could imagine AspectJ providing a function like the following:

Exception throwIfAllowed(Exception e) {
  if (isExceptionAllowed(e)) {
    throw e;
  }
  else {
    return e;
  }
}

Of course this function would have to be declared to throw Exception (defeating the purpose) if I wrote it. But if both functions were declared by AspectJ (in bytecode where necessary) I could safely call them. I could have fallback handling for any exceptions which are not allowed to be thrown.

Thanks,
John

Back to the top