14

I'm working with a legacy Java app that is new to me so one way to figure out how it works and find things easier, I have thought would be to be able to get the full stack trace after I perform actions, so as to be able to see which classes are being used based on a particular UI action. I had thought this was possible in the debugger but it seems that it only works if I insert a breakpoint and in this case part of the purpose of this is so that I don't have to know what's being called to be able to insert the breakpoint first (as this would help tell me that).

I apologize if this is a basic question, I have searched on this but I'm not finding the correct answer.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
Rick
  • 16,612
  • 34
  • 110
  • 163
  • Wouldn't going through the log files be easier as a starting point – Basanth Roy Jul 15 '11 at 20:05
  • 1
    which log files? the app uses tomcat server and I don't think it would be logging each method call it makes, is this auto-logged somewhere else that I am missing (some sort of eclipse log?) thanks – Rick Jul 15 '11 at 20:08
  • no, I was referring to the app logs only (I am not aware of any auto logging by eclipse or tomcat). So, if you are lucky, the legacy code would have had some level of logging. Set the log level to lowest and run the UI. – Basanth Roy Jul 15 '11 at 20:22
  • yeah I feared thats what you meant as unfortunately I'm not nearly that lucky and it doesn't have that sort of logging ability :) – Rick Jul 15 '11 at 20:24

6 Answers6

3

A few suggestions:

Some profilers will allow you to walk from any particular method up (and sometimes down) to see what's calling and being called. I've found this surprising informative about flow, even in apps I thought I knew well.

For understanding the mainline flow, I don't think there's a better substitute for working interactively with a debugger. It will lead you into learning other important things. Not what you wanted to hear, I know. This presumes that you can rapidly restart the app when you miss a key off-ramp.

Reverse-designing large legacy apps is the one place where I use UML fairly regularly. There's too much to keep in my head to form a good big picture. If you have a UML tool that will do reverse-engineering, load it up with the app, then probably prune down hard on the classes you don't care about, because they are trivial or obvious. Arrange the diagrams in a way that helps you understand. I've used Together, Magic Draw, and Visual Paradigm in this way. Together worked the best - but it was a decade ago.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91
  • Looked into things more and now I'm using the profiling tool: VirtualVM which looks pretty good for my needs, basically I just want to get a run-time look at what classes are being used, etc so that I can place breakpoints based off that, anyways VirtualVM is something I recommend for anyone with a similar issue – Rick Jul 18 '11 at 17:12
  • @Ed Staub Can you pls explain with more details how to understand new code base using your mentioned technique (UML & debug)? – Hacke Jul 28 '21 at 09:33
  • @Hacke It's been 10 years, and I've moved on. – Ed Staub Jul 31 '21 at 01:33
3

This doesn't directly answer your question, but maybe it will solve your problem better. Take a look at BTrace. It lets you instrument a running Java app and insert some basic code of your own. You could, for instance, have it write out entire method call chains to help you find your way through the app. It's somewhat similar to AspectJ, but with an entirely different purpose and requiring no change in the project source:

"BTrace is a safe, dynamic tracing tool for Java. BTrace works by dynamically (bytecode) instrumenting classes of a running Java program. BTrace inserts tracing actions into the classes of a running Java program and hotswaps the traced program classes."

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • Thanks for the info, yeah I figured something like this would be ideal, I actually came across a web app monitoring application through a task assigned to me at my job that I think does something somewhat similar (using a Java Agent) but thats not its primary purpose so BTrace is probably better for the need in this case – Rick Jul 18 '11 at 15:22
  • it does look like you need to make some modifications by annotating some methods and also making them static void which conflicts with the web-nature of the project, I think, but this is definitely interesting for future reference – Rick Jul 18 '11 at 15:31
  • @Rick: No, you don't change the project source. The annotations and static methods are in your trace code which is completely outside of the target project. BTrace attaches to a running JVM and injects its tracing routines into it at runtime. – Ryan Stewart Jul 18 '11 at 15:40
  • 1
    the 'BTrace' link is broken; it opens the http://www.oracle.com/splash/kenai.com/decommissioning/index.html site, which is closed – Newton fan 01 May 24 '18 at 16:13
2

When you are in the debugger perspective, you will see a view showing the launched processes. In that view you can tell it to pause all threads of a process. Once stopped, you will be able to browse through threads to see what they are all doing. To try to catch what a particular action is doing, you would have to start the action and then quickly pause all threads.

Konstantin Komissarchik
  • 28,879
  • 6
  • 61
  • 61
  • Do you know what this view is called in Eclipse? I can't seem to find it, thanks – Rick Jul 15 '11 at 19:59
  • I think I know what you men now, just the regular "Debug" tab, I tried pausing it during an operation and it looks like I got some of the stack trace but not sure if its all of it – Rick Jul 15 '11 at 20:06
  • This solution is definitely for developers with good reflexes. ;) Could be helpful though if the action is involved with a long running process. – Neil H Jul 15 '11 at 20:13
  • I see, yeah its not a long running process, its a web app so its just quick calls to load pages, etc – Rick Jul 15 '11 at 20:16
  • Most frequently used for debugging hanged processes. – Konstantin Komissarchik Jul 15 '11 at 22:49
1

You could always run the application with the VM arg of -verbose:class. You could then watch the console output and see what classes the VM is loading when you perform a particular action. This could possibly give you a starting place for where to place breakpoints. This won't always work depending on the scenario, but may be helpful.

Neil H
  • 356
  • 1
  • 6
  • I'm running a tomcat web app so I figure maybe I can set an env variable or something to do this in tomcat, will have to look into it more – Rick Jul 15 '11 at 20:19
1

Another trick you can use is to figure what classes you know that have to be involved in the code path you are trying to trap. For instance, you mentioned that it's a Java EE web app and therefore the action is likely some kind of a servlet interaction (at some level). I don't have the API in front of me, but you can place a breakpoint on the method in the response object where the output stream is retrieved. Once that breaks, you will know the code that's trying to service the request.

Konstantin Komissarchik
  • 28,879
  • 6
  • 61
  • 61
-1

You can always see where a method is called by clicking "Open Call Hierarchy" from eclipse (left click on the selected method or CTRL+ALT+H ). Also, you always can inspect where a method/class is defined by clicking "Open Declaration" (left click on the selected method/class or F3).

Sam
  • 2,398
  • 4
  • 25
  • 37
  • Yes I am aware of all this, this isn't what my question is asking. I want to get the full run-time calls based on a specific action, the way you are saying I should do it requires manually going through each method call, etc and tracing it back which is less efficient – Rick Jul 15 '11 at 19:14