Hi all. This is probably hard to understand because I won't be able to describe it very effectively but please bear with me.
I'm debugging through a lot of code at the moment. An example is there's a figure been printed in a field and I have to back track through the code to see where this comes from. So I look on the JSP and it's been taken from a bean, I go further and see that the bean was taken from the session, I check to see when it was added to the session, then when the figure was added to the bean, then where that figure came from and so on.
Generally I find that as Java is all about reusing code and methods, trying to find which use of thisMethodThatsUsedAllOverTheWorkspace THIS time can be a very long and drawn out process and I keep forgetting where I am and the direction I'm going through the code etc.
I now write things down, but it doesn't seem like the clearest way and I'm kind of developing my own 'language' to describe only the parts of the code I'm interested in.
SO NOW TO THE POINT:
Can anyone please let me know if there's any such thing as a formal way of documenting a 'path' backwards through code - some method, standard, model - ANYTHING that would help make this clearer?
Is there an easier way than repeatedly running through the code and baby stepping a bit backwards through the code each time to find out where a figure's come from?
Apologies if this just sounds like nonsense but it would be REALLY helpful if this could be examined.
Before you criticize someone, try walking a mile in their shoes. That way you'll be a mile away from them. And you'll also have their shoes.
Unless you understand the architecture and conventions of the application you're working with you'll *always* have to work backwards, or at least be smarter about working forwards. Still--figuring out that a value is coming from the session or from a form field really shouldn't be too difficult; if you can't figure it out from the source code without having to actually step through something's gone wrong.
One debugger I tried once that did things rather differently than all the conventional debuggers was the Omniscient Debugger. It traced variable value changes, along with the call stack for each change. Don't know if this will help you - I'd used it for a desktop app - but nevertheless you can try it out, perhaps calling your code via a junittest case.
Joined: May 22, 2009
David, thanks for your reply. I'll need to look up a sequence diagram and see if that's the kind of thing I'm imagining.
You're right about being able to tell it's from a session - though even this can get tricky if it's been stored in a bean, which was in a hashmap, which is declared in a different JSP that only combines them at run time using tiles, but which is hard to tell which versions are going to be combined as the rules are calculated at run time etc. but I see your point.
The hard part is usually guessing when it's been added to the session because you usually have to search for a string (like Find-> "setAttribute("theString", object))and unless you know the exact wording the programmer used to add it to the session, then your search is bound to fail - and you might only be a whitespace character out. Plus if it shows up in numerous places (which it perhaps should as it's being reused) then you won't know which one was the culprit!
Karthik, I'll have to try that debugger. However, does it track the variable, or the variable value? For instance if you had:-
String someValue = "somethingOrOther";
session.setAttribute("theString", someValue) then I would want to know about "theString" from then on, and not the 'someValue' if that makes sense?
Again, architectural issues: if something is poorly-designed enough to be modifying the session in a JSP, then you're just going to have to deal with the horrible design.
Note that it's relatively easy to write a program that'll read in Struts and Tiles config files and spit out something suitable for GraphViz to display; that can at least help with dependencies and definitions (I think my relatively naive implementation was maybe a few hundred lines of Ruby). It could be extended to parse out specific things in JSPs to help pinpoint session modification.
Ideally, session attributes would be identified with a constant, removing one potential source of error. Instead of "theString" it'd be Attributes.THE_STRING, which then could be search by reference by any reasonable IDE/source exploration mechanism. Or if everything was stored in a type-safe session object, simply myCustomSession.getTheString().
Joined: May 22, 2009
David, thanks again, this is really useful stuff. It's highlighting the source of the pitfalls and making me rethink what's perhaps at fault here.
I'm not sure how much thought goes into either creating our applications from an architectural perspective, but think it can't be that much as I imagine that to extend or modify an application with this in mind, thorough documentation should be present to give the new developer a thorough grounding on not just how the application works, but how also it's supposed to work. There's only a few apps here that I can genuinely say that applies to, that there is anything near the information necessary to figure out what the code does, without painstakingly going through it line by line.
Ruby's something I have to learn, not sure what it can do but definitely sounds useful.
The "theString" was just an example however; we do use constants. Though when you use the IDE to search for references, often the figure returned is in triple figures and it's back to the problem of trying to figure out what reference refers to your particular situation.
Dave McQueen wrote:[...] thorough documentation should be present to give the new developer a thorough grounding on not just how the application works, but how also it's supposed to work.[...]
That'd be sweet, huh ;) It almost never, ever happens... but now you know what you can do for the next guy A good wiki with aggressive gardening can really be a valuable tool in creating documentation like this, and I'm always a fan of automating as much of the documentation process as possible.
Though when you use the IDE to search for references, often the figure returned is in triple figures and it's back to the problem of trying to figure out what reference refers to your particular situation.
Gotcha... that's true; it's often difficult to weed out the results for a specific usecase.
Not sure what IDE you're using, but if you're using something Eclipse-like, you might want to investigate Mylyn (I think IntelliJ has something similar but I haven't gotten that far yet), although it still requires you to at least open the files you know you're interested in.
I don't know if you use Eclipse, but Eclipse provides a way to see a stack of all methods that were called up to whatever breakpoint it stops at. It's in the "Debug" view, which defaults to the upper-left hand corner of the "Debug" perspective.
SCJP 6 || SCWCD 5
Joined: May 22, 2009
David, the wiki is something we keep trying to get off the ground here. Hopefully with Sharepoint it will finally take off.
I will look at the Mylyn product. We use RAD7 so since it's built on Eclipse so it should still work, hopefully.
Michael, thanks for that. You've hit on the exact method that I use: I check to see where the value is in the call stack, then put a break point there, run again then check where that variable came from, then repeat. This can however prove difficult with values in the session scope however e.g. there's a value being read of "0.00584" which I find in the session object. To find out where this is added to the session object, rather than check references in the workspace, I put breakpoints all over the place and each time the application stops to start debugging, I check to see if it's in the session or request etc yet. If it's not then I just move on to the next randomly-placed-I-should-add breakpoint, and check again and repeat this until I find it. When I do I place breakpoins in all the references to that particular variable and then start the process all over again.
The problems are that it's very time consuming, and it depends on me being sure I've found all the references to that particular variable again (which I might not have as the spelling might be different, or the programmer might have put the method over two lines or something).
The call stack is useful for telling me where the methods originate, and their variable, but not the variables values unfortunately. It's these elusive things that I've yet to find software or methods to track successfully.
I'm convinced there's an excellent opportunity to develop software that does just this, and make some money from it, or even just make my job easier! Unfortunately I severly lack the knowledge or experience. Feel free to take this idea and run with it. Just so long as you make my job easier!
This is kind of a hack, but I wonder if you could use a HttpSessionAttributeListener and a ServletRequestAttributeListener? These listeners are called every time a session or request attribute is added/removed/replaced. In each of the listeners' attributeAdded() methods, you could set a breakpoint to check the value of the new attribute. Like if you know the value is "0.00584", you could set a break point with a condition that only causes it to break when the new attribute's value is "0.00584". When it breaks, you could then keep stepping through until you reach the code that's calling setAttribute().
Joined: May 22, 2009
That's an excellent idea. Exactly along the lines of what should happen.
Wasn't even aware that there were such listeners. I should really be thinking more loosely.
It would potenially be possible then to track a value (not a variable) all through it's 'life'. That would mean something could be tracked from the back end, for instance, to the front end and treated this whole process could be treated almost like a single process.