views:

24

answers:

1

Summary

When using IntelliJ IDEA to debug a JSP, I'm seeing the JSP get triggered twice before the actual request from the browser. Does anyone know why?

Updated with servlet test below.

Overview

I'm using (evaluating) IntelliJ IDEA for (effectively) the first time. When doing web application debugging, I'm seeing an odd behavior that suggests to me I have something misconfigured somewhere: If I have a breakpoint set in code that will run in response to the startup page, the code runs twice before the browser is launched, and then a third time in response to the browser request. I'd like to know whether I may have gone wrong somewhere (or if I haven't gone wrong, what's going on).

The Setup

A) Created a new web application project

  1. Created a new project from scratch
  2. Gave it a name and identified it as a Java module
  3. Accepted the default src directory
  4. Chose "Web Application" from the Desired Technologies list

That gave me a standard structure (src, WEB-INF, etc.) with a default index.jsp in it.

B) Added some simple code to the JSP to output the date.

C) Put a breakpoint in the code.

D) Configured my web browser in File | Settings | Web Browsers

E) Went to Run | Edit Configurations... and:

  1. Clicked [+] | Tomcat Server | Local
  2. Gave it name
  3. Clicked the Configure... button next to the drop-down list of application servers (since I didn't have any yet) and pointed it at my standalone Tomcat6 server (see below), accepting all the defaults
  4. Back in the debug configuration, told it to deploy the "war exploded" artifact for this configuration
  5. Added a "?foo=bar" query string to the default startup URL, so: http://localhost:8080/?foo=bar (you'll see why below)
  6. Left everything else at defaults
  7. Clicked OK

The Run

  1. Choose Run | Debug. It happily starts up the Tomcat server.
  2. It hits the breakpoint. Examining the request shows that this is a GET from user-agent "Java/1.6.0_20". It has the query string configured above. No attributes, no parameters other than the query string one.
  3. Click Resume Program button (F9).
  4. It hits the breakpoint again. This is also a GET from user-agent "Java/1.6.0_20", but it does not have the query string. No attributes, no parameters.
  5. Click Resume Program button (F9).
  6. It launches the browser and hits the breakpoint again. This is a GET from the browser (with the query string) and looks perfectly normal.

I see the behavior both with and without the query string, I just added it to see when/whether it showed up.

If I create a class and use that class from the code in the JSP and move my breakpoint into the class's code, that breakpoint does get hit all three times, so if it were doing real work (looking something up in a database, for instance), it would really do the work. I wondered if this was some phantom pre-compile call or something, but A) it shouldn't be, and B) it doesn't seem to be.

Run with Servlet

I wanted to tease out the behavior a bit more, so I added a servlet to the project, mapped it to the path /foo, and changed my debug configuration to trigger http://localhost:8080/foo?foo=bar rather than the index page. I also added another JSP to the project, at the root, called another.jsp. This revealed very interesting behavior:

  1. Choose Run | Debug. It happily starts up the Tomcat server.
  2. It hits the breakpoint in the servlet code. Examining the request shows that this is a GET from user-agent "Java/1.6.0_20". It has the query string. No attributes, no parameters other than the query string one.
  3. Click Resume Program button (F9).
  4. It hits the breakpoint in the index.jsp(?!). This is also a GET from user-agent "Java/1.6.0_20", but it does not have the query string. No attributes, no parameters. Note that index.jsp has nothing to do with the startup path /foo.
  5. Click Resume Program button (F9).
  6. It launches the browser and hits the breakpoint in the servlet again. This is a GET from the browser (with the query string) and looks perfectly normal.

The breakpoint in the another.jsp file is never hit. So I suspected the triggering of the index.jsp (with no query string) relates to it being the default "welcome file." So I added a welcome-file-list to my web.xml and set up another.jsp as the only welcome-file. Sure enough, now the breakpoint in another.jsp gets hit, and not the one in index.jsp.

More Details

  • Fairly generic Ubuntu 10.04 LTS desktop install
  • Freshly downloaded and unpacked IntelliJ IDEA Ultimate installation (30-day trial)
  • Freshly downloaded and unpacked standalone Tomcat6 install (IDEA didn't like the central install I'd done via Synaptic, the split directory structure confused it, so I stopped that server and just used a simple download-and-unpack version)
  • Sun's Java 6 JDK

Thanks in advance!

+1  A: 

Examining the request shows that this is a GET from user-agent "Java/1.6.0_20".

That happens when you deploy the webapp on ROOT of Tomcat. The Tomcat server plugin will do a self-test on / during startup (which indirectly loads the welcome-file as definied in web.xml).

What can you do? Either live with it or deploy on a context other than ROOT.

BalusC
Thanks for that! Good to know. That explains the second request of the three, and of course the third one is the normal one. Any ideas about the first one?
T.J. Crowder
The first forwards to the second since it's apparently the `welcome-file`. It's actually the *same* request.
BalusC
@BalusC: That doesn't make sense to me, and doesn't fit with the servlet stuff I added to the question a while back. If I set my startup URL to be `/foo` rather than `/` in my configuration, **first** the servlet at `/foo` gets triggered (with the query string, with the "Java/1.6.0_20" user agent), then the welcome file gets triggered (without the query string, with the Java user-agent). `/foo` isn't forwarding to `/`. Separately, I'm not having much luck finding this self-test information on Tomcat, do you have a link?
T.J. Crowder
Does this also occur when you deploy on a context other than ROOT? As to the self-test, I've previously been looking for documentation about this as well, but I couldn't find one, sorry. I can at least confirm this based on my own experience with Eclipse and after digging the Tomcat source code.
BalusC
@BalusC: Yes, it still happens. The second one (triggering the welcome page without the query string) stops happening, though, so I think that's the self-test one you're familiar with. But the first and last calls both happen, the first from that Java user-agent, and the second from the actual browser.
T.J. Crowder
Well, I don't recognize this. My *guess* would be that the IDEA Tomcat server plugin is doing that first one. Since I don't have IDEA at my hands I can't tell more, sorry.
BalusC
@BalusC: *"That happens when you deploy the webapp on ROOT of Tomcat. Tomcat will do a self-test on / during startup."* As far as I can tell, Tomcat *itself* does not do that. Using the central Tomcat server I installed from Synaptic, I put a welcome file in that had a side-effect I could look at externally (obviously I would never do that normally) and proved that Tomcat wasn't calling it either when deploying a war to ROOT or when starting up, but only calling it in response to a request from the browser. (cont'd)
T.J. Crowder
(continuing) The Eclipse plug-in may do that, and IDEA's may (and appears to do something else as well!), but that's another thing. Thanks for your thoughts on this, much appreciated.
T.J. Crowder
Interesting. It'll after all indeed be the Tomcat server plugin.
BalusC