Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 333102 - WebServlet annotations not working when using the "Serve modules without publishing" Tomcat 7 feature
Summary: WebServlet annotations not working when using the "Serve modules without publ...
Status: RESOLVED FIXED
Alias: None
Product: WTP ServerTools
Classification: WebTools
Component: wst.server (show other bugs)
Version: 3.2   Edit
Hardware: PC All
: P3 normal with 2 votes (vote)
Target Milestone: 3.2.3   Edit
Assignee: Larry Isaacs CLA
QA Contact: Angel Vera CLA
URL:
Whiteboard: PMC_approved
Keywords:
: 354068 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-12-22 11:07 EST by Klaus Reimer CLA
Modified: 2017-10-11 16:35 EDT (History)
9 users (show)

See Also:
arvera: pmc_approved? (david_williams)
arvera: pmc_approved? (raghunathan.srinivasan)
arvera: pmc_approved? (naci.dai)
arvera: pmc_approved? (deboer)
neil.hauge: pmc_approved+
arvera: pmc_approved? (kaloyan)
arvera: review+


Attachments
Patch to WTP tomcat.core code to fix Tomcat 7.0 "Serve modules without publishing" (19.00 KB, patch)
2011-01-19 10:52 EST, Larry Isaacs CLA
no flags Details | Diff
Updated Tomcat 7.0 loader.jar (6.05 KB, application/octet-stream)
2011-01-19 10:54 EST, Larry Isaacs CLA
no flags Details
Updated Tomcat 7.0 loader.jar source zip (5.55 KB, application/octet-stream)
2011-01-19 10:55 EST, Larry Isaacs CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Klaus Reimer CLA 2010-12-22 11:07:30 EST
Build Identifier: M20100909-0800

When the "Serve modules without publishing" feature for a Tomcat 7 Server is enabled then servlets annotated with the @WebServlet annotation are no longer working.

When the "Serve modules without publishing" feature is disabled then it works. 

I think Tomcat doesn't see the classes when scanning for annotations when this feature is enabled. A workaround is using WebContent/WEB-INF/classes as output folder. But that's not really a nice solution especially when a Maven project structure is used.

Reproducible: Always

Steps to Reproduce:
1. Create a new dynamic Web project.
2. Create a TestServlet and give it the @WebServlet("*.serve") annotation and a doGet method which does something.
3. Enable the "Serve modules without publishing" feature in the Tomcat 7 server settings.
4. Deploy the project and start tomcat
5. Call test.serve in the browser and you get a 404.
6. Disable the "Serve modules without publishing" feature or set the output folder to "WebContent/WEB-INF/classes" and restart tomcat. Now it works.
Comment 1 Carl Anderson CLA 2010-12-27 12:34:08 EST
Klaus, based off of the build id you provided, I am assuming that this was Eclipse 3.6 SR1, which corresponds to WTP 3.2.2.
Comment 2 Larry Isaacs CLA 2011-01-04 16:29:39 EST
Unfortunately, this appears to a Tomcat 7.0 regression due to the regression fix in Bug 318449 for WTP 3.2.1.  Also, some exception handling has changed since the last org.eclipse.jst.server.tomcat.runtime.70.loader.jar was implemented, so it needs an update too.  I'll double check my options, but it may be the best we can do is "re-regress" Bug 318499 for just Tomcat 7.0 in favor of annotations local to the web project working.
Comment 3 Larry Isaacs CLA 2011-01-06 11:07:02 EST
After some digging into how Tomcat 7 works, it appears the changes for Bug 318449 can be restored without harm provided the org.eclipse.jst.server.tomcat.runtime.70.loader.jar is updated such that WtpDirContext implements a suitable doGetRealPath() method.  This will allow 

    ServletContext.getResource("/WEB-INF/classes/<path to some resource>");
    ServletContext.getResourceAsStream("/WEB-INF/classes/<path to some resource>");

and with them enable annotation processing to succeed, while getClass().getResource() continues to work.

This fix is only possible in Tomcat 7, so ServletContext.getResource() and ServletContext.getResourceAsStream() will continue to not function correctly for earlier Tomcats when "Serve modules without publishing" is enabled.

Correction to Comment #2: The second bug reference incorrectly specifies 3184_9_9 instead of 3184_4_9.
Comment 4 Larry Isaacs CLA 2011-01-19 10:52:49 EST
Created attachment 187120 [details]
Patch to WTP tomcat.core code to fix Tomcat 7.0 "Serve modules without publishing"
Comment 5 Larry Isaacs CLA 2011-01-19 10:54:30 EST
Created attachment 187121 [details]
Updated Tomcat 7.0 loader.jar
Comment 6 Larry Isaacs CLA 2011-01-19 10:55:59 EST
Created attachment 187123 [details]
Updated Tomcat 7.0 loader.jar source zip
Comment 7 Larry Isaacs CLA 2011-01-19 13:00:28 EST
Requesting approval for inclusion in WTP 3.2.3.

Here is the PMC Approval Info:

1. Explain why you believe this is a stop-ship defect.

Annotations is a major feature of Servlet 3.0, which is broken when the "Serve modules without publishing" feature is enabled.


2. Is there a work-around? If so, why do you believe the work-around is insufficient?

There is no work-around.
 

3. How has the fix been tested? Is there a test case attached to the bugzilla record? Has a JUnit Test been added?

I have tested these changes with a set of projects that implement various features from the servlet specs and numerous mappings in Deployment Assembly. For example, web content folder mappings include:

Source              Deploy Path
/WebContent         /
/WebContent2        /
/WebContent3        /
/WebSubContent      /sub
/WebSubContent2     /sub
/WebSubSubContent   /sub/sub
/WebSubSub2Content  /sub/sub2
/jsps               /jsps
/WebJSPContent/jsps /jsps
/WebInfContent      /WEB-INF
/src                /WEB-INF/classes
/src2               /WEB-INF/classes

Included in the testing is verification that a request for "/sub/sub/some_resource" will find the resource if it is in a "sub/sub" folder of WebContent, WebConten2, or WebContent3; or in a "sub" folder under "WebSubContent" or "WebSubContent2"; or directly in "WebSubSubContent".  These test projects continue to work as expected with "Server modules without publishing" enabled, now including annotations for Tomcat 7.0.


4. Give a brief technical overview. Who has reviewed this fix?

Tomcat uses an internally implemented JNDI and classloader to access the webapp's resources.  The "Serve modules without publishing" feature adds wrapper classes to Tomcat to "virtualize" this access.  However, making virtualized "WEB-INF/classes" resources visible to JNDI caused Bug 318449, and the fix meant they stopped being visible.  Unfortunately this JNDI visibility is required for annotations to work in Tomcat 7.0.  The problem with visibility of virtualized "WEB-INF/classes" resources is that on its own, Tomcat doesn't handle multiple locations for "WEB-INF/classes" resources.  Fortunately, Tomcat 7.0 has a method which can be overridden in one of the added wrapper classes which can find which of multiple virtual "WEB-INF/classes" directories contains a requested resource and provide a valid "real" path for that resource.


5. What is the risk associated with this fix? 

Minimal.  Only the "Serve modules without publishing" feature is affected and these changes should restore it to working order for annotations in Tomcat 7.0.
Comment 8 Angel Vera CLA 2011-01-19 16:53:41 EST
Looks good to me. Agreed with statement on comment #7 that 'Annotations is a major feature of Servlet 3.0, which is broken when the "Serve modules without publishing" feature is enabled.'
Comment 9 Larry Isaacs CLA 2011-01-20 13:05:22 EST
Changes released to WTP 3.2 maintenance and HEAD and are present in current WTP 3.2.3 and 3.3 builds.
Comment 10 Angel Vera CLA 2011-01-20 13:11:19 EST
Larry, did this made it into the smoke test?
Comment 11 Larry Isaacs CLA 2011-01-20 13:23:47 EST
Yes.
Comment 12 Larry Isaacs CLA 2011-08-08 11:23:32 EDT
*** Bug 354068 has been marked as a duplicate of this bug. ***
Comment 13 Steve Ash CLA 2011-08-08 11:52:15 EDT
(coming from bug 354068) Wow I see. This is a conundrum.  Is there any thought to at least making this configurable?  Or just removing the feature entirely? If we divide the space of webapps into the following sets:

1) Ones written without servlet 3.0 @annotations but potentially reading files from the classpath via concatenation (as cited in bug 354068)
2) Ones written with servlet 3.0 @annotations which do _not_ read files from the classpath via concatenation
3) written with servlet 3.0 annotations which _do_ read files from the classpath via concatenation

We observe the (3) can _never_ be supported by WTP "serve from workspace"

However, isn't it reasonable to assume that the class of (1) is much bigger than (2)?  Just the simple observation of the pervasiveness of log4j.properties files on the classpath for webapps is enough to convince me that (2) is a _very_ small class (probably only toy projects).

So If you have to choose (1) or (2), then I would expect (1) because
(a) it is a much larger class of web applications
(b) it is the "previously working" WTP functionality

The real question is how to come up with a clever (albeit probably complicated) solution to solve (3) because that is the "new" set of webapps coming, enabled by servlet 3.0.  Perhaps a custom builder that copies the resources so that you still only present one location to tomcat?  

In my opinion, publishing from the workspace is a huge feature -- not a hack.  Without it my developer productivity drops dramatically while waiting on constant container restarts.

So as bug 333102 is marked as resolved fixed, am I to assume that there is no plan to do anything else with this functionality and tomcat7?
Comment 14 Larry Isaacs CLA 2011-08-08 12:42:42 EDT
Regrettably, the amount of time my day job leaves me to work on the WTP Tomcat support is pretty limited.  It's been a while since I reviewed my bug list, but I doubt this one would be considered that urgent, especially since the simple workaround is to put a copy of the file where "Serve modules without publishing" expects to find it.

Also, it's possible for changes to Tomcat to break this feature at any time, both with respect to the custom classloader this feature uses and with how Tomcat itself works.  This has already occurred twice with Tomcat 7.0.x.  Hopefully this won't happen again, or will turn out to be fixable like the last two times.
Comment 15 Dominik Drzewiecki CLA 2011-08-12 08:15:39 EDT
I expect more and more similar reports coming in untill this issue gets resolved *properly*. Many people still stick to older API specs (as it takes some time for the frameworks/libraries they use to upgrade to the latest specs) while eagerly update the server major versions (tomcat 6.0.x hasn't been revised since April 2011 and is not given as much attention by the devs as tomcat 7 does). 

As "Serve modules without publishing" is a bliss for the devs, they won't easily give up using it. Especially those using multimodular maven projects (expect m2e to be on a rise!).

I'll elaborate more on this soon.
Comment 16 Larry Isaacs CLA 2011-08-12 09:16:01 EDT
Please be aware that resolving this "properly" means modifying _Tomcat_ to not assume that all webapp resources live under a single "docBase" folder.  Tomcat does provide some support for "aliasing", but if I remember correctly, it can only map to the root of the webapp.  It does't support "aliasing" the "build/classes" folder of the project to the "WEB-INF/classes" folder of the webapp.  The simplest way to workaround this issue is still to put a copy of the resource where Tomcat is expecting to find it.  I'll at least try to find time to update the Tomcat FAQ to document this issue.
Comment 17 Sylvain Laurent CLA 2011-08-29 17:39:41 EDT
I filed an issue for tomcat and will work on a patch : https://issues.apache.org/bugzilla/show_bug.cgi?id=51741


BTW : this issue is still marked as RESOLVED, shouldn't we re-open or create a new one ?
Comment 18 Sylvain Laurent CLA 2011-08-29 17:44:17 EDT
bug 354068 should not have been marked as DUPLICATE of this one, it is a consequence of the changes brought to fix the initial problem reported in this issue.
Comment 19 Sylvain Laurent CLA 2011-10-01 17:29:41 EDT
Tomcat 7.0.22 has now been released and contains the fix for this problem
Comment 20 Larry Isaacs CLA 2011-10-06 14:34:03 EDT
FYI: Use of Tomcat 7.0.22 is impacted by Eclipse Bug 360012 if you are using Servlet 3.0 Web applications with "Serve modules without publishing".  See the bug for details.
Comment 21 Sylvain Laurent CLA 2011-12-06 16:42:08 EST
Since this bug is still marked as RESOLVED and several things occurred since it was created, I preferred to file bug 365813 to ask to use the improved VirtualDirContext that is now provided with tomcat 7.0.24 (not released yet).
Thanks to Larry for allowing the use of WtpDirContext code in tomcat.
Comment 22 Eclipse Genie CLA 2017-10-11 16:35:34 EDT
New Gerrit change created: https://git.eclipse.org/r/109018