Implementing the Null Object Pattern using AOP

Discussions

News: Implementing the Null Object Pattern using AOP

  1. Implementing the Null Object Pattern using AOP (28 messages)

    Everyone gets burned with the evil NullPointerExceptions. There is nothing more depressing than having you application die, and just having an NPE displayed to you. Dale Asberry has implemented the Null Object Pattern using AOP. Now when that exception comes up, you are told where!

    Example Output
    java.lang.NullPointerException
    at test.Main.main(Main.java:33)
    Caused by: java.lang.NullPointerException: Null return value from test.Main.nullStringTest(Main.java:32)
    at test.Main.main(Main.java:32)

    OR

    java.lang.NullPointerException
    at test.Main.main(Main.java:53)
    Caused by: java.lang.NullPointerException: Null value assigned to field test.Main.cList(Main.java:22)
    at test.Main.(Main.java:22)
    at test.Main.main(Main.java:28)
    java.lang.NullPointerException
    at test.Main.main(Main.java:63)
    Caused by: java.lang.NullPointerException: Null return value from test.Main.nullArrayListTest(Main.java:62)
    at test.Main.main(Main.java:62)
    Exception in thread "main"
    Read Implementing the Null Object Pattern using AOP

    Threaded Messages (28)

  2. OT: Grammar[ Go to top ]

    I know this is off-topic, but I noticed it in many articles I recently read on the web. An increasing number of people are using "that" instead of "than" with comparative adjectives. It's becoming as common as confusing "then" with "than" and "loose" with "lose".
  3. I want[ Go to top ]

    That's what i want just now.
    I will implement the Null partten in my project.
  4. Null Object Pattern[ Go to top ]

    I think the Null Object Pattern can be useful sometimes. But the performance must not suffer too much because of this pattern.

    I dislike the exception message style:
    java.lang.NullPointerException
    at test.Main.main(Main.java:53)
    Caused by: java.lang.NullPointerException: Null value assigned to field test.Main.cList(Main.java:22)
    at test.Main.(Main.java:22)
    at test.Main.main(Main.java:28)
    The NPE is not caused by another NPE! This is not true.

    So here my alternative:
    java.lang.NullPointerException
    at test.Main.main(Main.java:53)
    Because of: Null value assigned to field test.Main.cList(Main.java:22)
    This is more concise and doesn't include the misleading cascading NPEs.
  5. Null Object Pattern[ Go to top ]

    That would probably be clearer, however, you can't instantiate (or change) a StackTraceElement the way you suggest.
  6. Use ternary statements[ Go to top ]

    I could see the seriousness in the author's explanation for pattern to avoid NPEs but i think that NPEs should be handled by enforcing strict coding conventions and regular reviews.

    I would always say to use ternary statements like

    (someObject == null)?"":someObject;

    where ever possible particularly when interfacing with some external code.
    The bottom line is dont trust anyone and check for null objects urself.
  7. Could this be more useless? Isn't this what a debugger is for?

    And before you say "hey I can't use a debugger on our production application dummy", so what?

    #1: You have the line number from the stack trace, can it possibly be that hard to figure out? Even on a complicated line of code there's likely only two or three candidates.

    #2: Unless it's one of those "production only" bugs, you should be able to reproduce it somewhere that you can connect with a remote debugger

    #3: Also I can only imagine the overhead of keeping track of when variables are set to null so that you can report them when a NPE happens
  8. Could this be more useless? <
    Regarding #1:
    The problem I was having was nested several calls deep in previous method calls. I was getting the NPE thrown in a method that appeared to have nothing to do with where the null was being assigned. Easily took me more than 30 minutes to track it down using the debugger. Personally, I think having better JUnit tests might have uncovered it, but that's hard to say since the object in question was being passed around indirectly in the session.

    Regarding #3:
    If you look at the code, the overhead is pretty small. In my environment, the overhead that it contributes is negligible compared to database access and other remote system calls.
  9. >> Could this be more useless? <<Regarding #1:The problem I was having was nested several calls deep in previous method calls. I was getting the NPE thrown in a method that appeared to have nothing to do with where the null was being assigned. Easily took me more than 30 minutes to track it down using the debugger. Personally, I think having better JUnit tests might have uncovered it, but that's hard to say since the object in question was being passed around indirectly in the session.Regarding #3:If you look at the code, the overhead is pretty small. In my environment, the overhead that it contributes is negligible compared to database access and other remote system calls.</blockquote>Then again, I guess it is interesting as a debugging tool as long as you turn it off after you've discovered your problem. yet another usecase for dynamic aop.

    Bill
  10. Then again, I guess it is interesting as a debugging tool as long as you turn it off after you've discovered your problem. yet another usecase for dynamic aop.Bill
    In the meantime, there are idioms that can be applied at runtime to simulate dynamic aop. I'll be writing about them (and other useful idioms) in the coming weeks.
  11. Could this be more useless? Isn't this what a debugger is for?
    Agreed. This should be in the book of AOP Anti-patterns. Does the author realize the amount of overhead they've just introduced to their codebase? You've basically added a hash lookup for every single method call.
  12. It depends with who you work.

    I work with a few bad coders based in India. I can't simply go to their desk and bring up the point with them. Finding ways to work around their code and automatically expose weaknesses of it would be of great value to me.
  13. Get good developers[ Go to top ]

    It depends with who you work.I work with a few bad coders based in India. I can't simply go to their desk and bring up the point with them. Finding ways to work around their code and automatically expose weaknesses of it would be of great value to me.
    Get good developers, no tool or pattern is going to save you from bad coders. Furthermore, a great team will give you results no matter (sometimes, in spite of) the tools you use.
  14. There is no need to say "bad coders based in India". There are bad coders everywhere. Lets try and use some conciliatory language shall we, in order for the discussion to progress in an intelligent fashion. Thank you.
  15. This is useful for third party code[ Go to top ]

    Code that you dont have control over.....
  16. While this sounds interesting, wouldn't it be less complicated to just simply 1) have a good understanding of how to use a debugger and 2) remember good coding practices and put forethought on where you may encounter null values and check for them? #1 will lead to #2.

    - My $0.02, not to be an a$$.
  17. it's their choice[ Go to top ]

    This should be in the book of AOP Anti-patterns.

    If their performance is ok with them then it's not an anti-pattern.
    It's their choice.
  18. it's their choice[ Go to top ]

    >This should be in the book of AOP Anti-patterns. If their performance is ok with them then it's not an anti-pattern.It's their choice.
    I was just being antagonizing....Apologies.
  19. I don't get it[ Go to top ]

    Can't say I've ever had this problem. When I look at the NullPointerException stack trace, I see right where the exception occurred and in what context. From there, it's pretty easy to tell where the value came from. Do you do something differently?
  20. Useful in situations like[ Go to top ]

    If your code looks like:

    foo = someMethod(arg1.getIt(), arg2.doThat()).getBar();

    And you have a NPE, it would be nice to know if arg2 was null, arg1 was null or if the return from someMethod() was null.
  21. Useful in situations like[ Go to top ]

    If your code looks like:foo = someMethod(arg1.getIt(), arg2.doThat()).getBar();And you have a NPE, it would be nice to know if arg2 was null, arg1 was null or if the return from someMethod() was null.
    Ask Martin and this will get refactored in a minute ;-)
  22. I don't get it[ Go to top ]

    Can't say I've ever had this problem. When I look at the NullPointerException stack trace, I see right where the exception occurred and in what context. From there, it's pretty easy to tell where the value came from. Do you do something differently?
    The application that got me into this thinking populates the objects at a different point in time than when they are being executed. Another issue is that most code in the real world (especially in very large applications) is not exactly the cleanest, most solid, or most tested code you'll run into. That being said, the object causing the NPE was created and put into the session. Several interactions later it was being retrieved and accessed. The null pointer could have been assigned in several places and it took quite a bit of debugging to finally find it. When I applied my aspect code to the problem, I saw exactly when the null was being assigned. In another situation, the object was being accessed several lines away from when it was assigned. The problem was that an NPE was swallowed several calls deep and a null was propagated out. This same bit of aspect code found it right away.

    So...

    For all those people saying that good debugging skills would find the answer, they are right. But the cost of 30 minutes to track it down vs. seeing it immediately...

    For all those saying that good tests, yadda, yadda, well they are right too. But I don't own that code and creating tests around it would consume the rest of my life.
  23. This may (or may not) be useful, but it's not really an example of the Null Object Pattern. The point of the null object pattern is not to provide improved debuging traces for NPE's. Rather, the purpose to avoid the need for null checks by substituting a non-null object that has the appropriate default behavior, but that still allows explicit testing for null when required.
  24. This may (or may not) be useful, but it's not really an example of the Null Object Pattern. The point of the null object pattern is not to provide improved debuging traces for NPE's. Rather, the purpose to avoid the need for null checks by substituting a non-null object that has the appropriate default behavior, but that still allows explicit testing for null when required.
    Strictly speaking, you're correct. However, if you examine the code, it just happens that the "appropriate default behavior" that I wanted was a cleaner NPE. If you want different behavior you can swap your code in for where I was doing NPE processing. Either way, a real object that represents "null" is being returned from the advice. So the subject "This is unrelated to the Null Object Pattern" is misleading.

    Is anyone actually looking at the code I've posted?
  25. This may (or may not) be useful, but it's not really an example of the Null Object Pattern. The point of the null object pattern is not to provide improved debuging traces for NPE's. Rather, the purpose to avoid the need for null checks by substituting a non-null object that has the appropriate default behavior, but that still allows explicit testing for null when required.
    Strictly speaking, you're correct. However, if you examine the code, it just happens that the "appropriate default behavior" that I wanted was a cleaner NPE. If you want different behavior you can swap your code in for where I was doing NPE processing. Either way, a real object that represents "null" is being returned from the advice. So the subject "This is unrelated to the Null Object Pattern" is misleading.Is anyone actually looking at the code I've posted?
    I did. I must say that tracking down NPEs is one of the easiest parts of my job (I love these type of bugs :) ) - provided that exceptions handling is done right and people don't swallow Exceptions the stack trace tells you everything. Runtime code swapping in the Eclipse debugger makes life even easier. I feel it's not worth going through headaches of applying AOP post-processors to source base just to be told where the NULL allocation happened. In really hard scenarios NPEs don't result from the faulty code but from miss-configuration of a system (forgot to plug-in a filter, forgot to provide mandatory configuration parameter, etc.).
  26. Preconditions[ Go to top ]

    I do a quick and dirty pre-condition check where objects are passed in. Usually, this happens in constructors. If an argument that shoudl not be null is, I throw a *descriptive* NullPointerException right away rather than assigning it and having delayed effects later. There are places where doing this check can become a performance bottleneck, so I can't say I use it everywhere -- but certainly it covers teh majority of the cases.
  27. Hands Down Solution[ Go to top ]

    Don't return null references.

    John C. Dale
    MS MIS, December 2005
    The University of Arizona
    Tucson, Arizona
  28. Hands Down Solution[ Go to top ]

    Don't return null references.John C. DaleMS MIS, December 2005The University of ArizonaTucson, Arizona
    And the choir says, "Amen, Brother!"
  29. Thanks for the advice, John[ Go to top ]

    Oh yeah, and don't write software that is slow or has bugs.