问题
We have a bunch of pdf report classes which after a mass import of archived data have started occaisonally throwing null pointer exceptions when bits of data are missing e.g. thing.getOtherThing().getText();
will not have an OtherThing
and the report will fall over.
As I see it we have a few options
- Fix the data - not so clear what the data should be in every case and is a matter of human judgement in some cases
- Put try/catches everywhere and rethrow a useful exception to bubble up to the user - a lot of work and ugly code but usefull to the users
- Put null checks everywhere - no thanks
- Work on the DAO code to do coalesce/nvl in the queries and generate reports with N/A in the missing fields (or banks) - ok but no so usefull
Or ... can we do something with AOP here? Is it possible to intercept nullpointers thrown in certain classes/methods? What level of information is available when these are intercepted? Bear in mind that multiple places in a method could throw null pointers :(
Thanks.
回答1:
Uff.. It might be painful, but I sincerely would recommend you to go tgrough your code and put the checks for null wherever is sensible, build for yourself a utility class so you can do something like
MyUtilityHelper.checkNotNull (toCheck, elegantMessage)
And make that method throw something which you can have more information about.
AOP is really not applicable here IMHO, you don't want to do with AOP stuff that is supposed to be done with sequential logic, just because code is better for sequential processing... AOP is suitable when you want to add a horizontal layer of functionality, like security, logging...
回答2:
AOP could potentially help you reach a solution, but you need to take action before the exception is thrown because an exception will cause you to lose too much execution context. Firstly, when you write thing.getOtherThing.getText()
is getOtherThing
a field with an odd name or a method call that you accidentally omitted the parentheses from? If it is the latter, you can use Spring AOP to intercept the method (provided thing
is actually a bean). If not, you'll need full AspectJ as Spring AOP doesn't do field access interception (because of how it is implemented).
The idea is that you use @Around
to define the pointcut and have advice like this:
static final OtherThing THE_DEFAULT_VALUE = ...;
@Around("execution(* getOtherThing())")
public Object supplyDefault(ProceedingJoinPoint pjp) throws Throwable {
Object result = pjp.proceed();
if (result == null)
result = THE_DEFAULT_VALUE;
return result;
}
Or, with AspectJ (untested; I've not actually used AspectJ for anything):
aspect ADefaultOtherThing {
static final OtherThing THE_DEFAULT_VALUE = ...;
OtherThing around(): get(OtherThing getOtherThing) {
OtherThing result = proceed();
if (result == null)
result = THE_DEFAULT_VALUE;
return result;
}
}
Still, I'd question whether this is a particularly good use of AOP. Surely it would be better to put such business logic directly in the code? Guaranteeing that a field is never null
would seem like a fine invariant.
来源:https://stackoverflow.com/questions/9211268/can-i-intercept-null-pointer-exceptions-in-a-method-using-spring-aop