9

I want to learn the internals of tomcat operation and understand the flow.

For this I created a servlet -

public class TestServlet extends HttpServlet {
    //Breakpoint set on constructor
    public TestServlet() {
    }
}

I included the tomcat source code in source lookup directories and launched the server in debug mode. Following is the stack trace when debugger stops at my breakpoint -

Daemon Thread [localhost-startStop-1] (Suspended (entry into method <init> in TestServlet)) 
    owns: StandardWrapper  (id=39)  
    owns: StandardContext  (id=40)  
    TestServlet.<init>() line: 12   
    NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]   
    NativeConstructorAccessorImpl.newInstance(Object[]) line: 39    
    DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 27    
    Constructor<T>.newInstance(Object...) line: 513 
    Class<T>.newInstance0() line: 355   
    Class<T>.newInstance() line: 308    
    DefaultInstanceManager.newInstance(String) line: 138    
    StandardWrapper.loadServlet() line: 1144    
    StandardWrapper.load() line: 1088   
    StandardContext.loadOnStartup(Container[]) line: 5123   
    StandardContext.startInternal() line: 5407  
    StandardContext(LifecycleBase).start() line: 150    
    ContainerBase$StartChild.call() line: 1559  
    ContainerBase$StartChild.call() line: 1549  
    FutureTask$Sync.innerRun() line: 303    
    FutureTask<V>.run() line: 138   
    ThreadPoolExecutor$Worker.runTask(Runnable) line: 886   
    ThreadPoolExecutor$Worker.run() line: 908   
    Thread.run() line: 662

As you can see tomcat initiates a new daemon thread to handle initialization of TestServlet. If I step out from this position it would backtrace upto run and then stop. However I want to understand main server logic. What should I do to step into the org.apache.catalina.startup.Bootstrap class? (or some other class that is run on main startup thread)

Kshitiz Sharma
  • 17,947
  • 26
  • 98
  • 169
  • How do you launch the server in debug mode? Do you use eclipse's "Servers", or do you run it as a standalone application? – jmruc Jun 05 '13 at 07:02
  • See http://stackoverflow.com/questions/975271/remote-debugging-a-java-application . But as for your problem, have you tried just placing a breakpoint in the Bootstrap class, or wherever you want to debug? – jmruc Jun 05 '13 at 08:00
  • Ctrl+Shift+T in Eclipse, write the name of the class and open it, and place breakpoint as in your own code. – jmruc Jun 05 '13 at 08:32

3 Answers3

7

You can debug Tomcat as a remote Java application.

Here is the steps:

  1. Create a Java project and copy Tomcat source files into project's source folder. (You can ignore compile errors.)
  2. Open Bootstrap.java and set a breakpoint at main method.
  3. Create a CATALINA_BASE/bin/setenv.bat(or .sh) file and put following line into the file.

    set JPDA_OPTS=-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y

  4. Start the Tomcat in debug mode using catalina.bat (or .sh) from command line.

    catalina.bat jpda start

  5. From Eclipse, set up a Debug Configuration under Remote Java Application and connect to the Tomcat process. (Run -> Debug Configurations -> Remote Java Application.)

Screenshot: Tomcat debugging using JPDA_OPTS

Kshitiz Sharma
  • 17,947
  • 26
  • 98
  • 169
Shinichi Kai
  • 4,415
  • 2
  • 21
  • 25
  • 1
    This method works, however there is an easier way. There is no need to append JPDA_OPTS manually to catalina.sh or explicitly connect to it as Remote Java Application. Eclipse does both of these things automatically when you launch server in debug mode from Eclipse Server View. – Kshitiz Sharma Mar 04 '14 at 09:45
2

Don't go for any of the confusing solutions. Found this after lot of research.

  • Simply setup your tomcat using eclipse.
  • Later download tomcat source file and execute ant command.
  • Nw go to your JavaEE setup => select new project => ava Project from Existing Ant Buildfile => point to tomcat source code and select build.xml
  • Set your break-point accordingly, in my case, bootstrap.java's main() method.
  • Go to your serverand selectdebug`
  • This should open the class where you have set your breakPoint. If there is warning named Source not Found, click add source => java project => select the source project

There you go.

Jeet
  • 85
  • 3
  • 8
0

What I did was:

  1. Download the zip file of the Tomcat GitHub repository.

  2. Open Eclipse, and create a new Java project.

  3. Extract all the content from the zip file you downloaded from the Tomcat GitHub into your new Java project.

  4. Once all the folders are there, create a new source folder: Right-click on project > New > Source Folder

  5. Name that folder src

  6. Move all the content from the java folder to this "src" file (Reason: Eclipse will reorganize those folders to make them packages. Check inside source and you will only see packages. I had to do this otherwise my run configuration would not recognize the path I gave to the main class)

  7. Delete the java folder (which you have extracted your data from), and rename folder src to "java" (to keep the same paths)

  8. Right-click on project > Properties > Java Build Path. Make sure under the Order and Export tab the java folder is the first one on the list.

  9. Now go in Run > Run Configurations... Create a new "Java Application" configuration

  10. Set the project to be your Tomcat project and set the main class to be "org/apache/catalina/startup/Bootstrap"

  11. Add a breakpoint in the Bootstrap.java file (the file executes from init() I believe)

  12. Debug with the configuration you have just set by clicking the down arrow next to the bug icon (which stands for Debug) and choose the Run Configuration you have just set.

This should do the trick!

Worthwelle
  • 1,244
  • 1
  • 16
  • 19
alt440
  • 51
  • 1
  • 6