Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 315423 - Changes to WebAppMerger causes regression in meger behavior.
Summary: Changes to WebAppMerger causes regression in meger behavior.
Status: RESOLVED FIXED
Alias: None
Product: WTP Java EE Tools
Classification: WebTools
Component: jst.j2ee (show other bugs)
Version: 3.2   Edit
Hardware: All All
: P3 major (vote)
Target Milestone: 3.2.1   Edit
Assignee: Dimitar Giormov CLA
QA Contact: Chuck Bridgham CLA
URL:
Whiteboard: PMC_approved
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-02 12:43 EDT by Larry Isaacs CLA
Modified: 2010-07-08 15:35 EDT (History)
3 users (show)

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


Attachments
JUnit patch to add tests for this use case (13.68 KB, patch)
2010-06-02 17:11 EDT, Larry Isaacs CLA
no flags Details | Diff
Possible patch to address merge behavior for servlet and filter mappings (5.63 KB, patch)
2010-06-02 20:01 EDT, Larry Isaacs CLA
dimitar.giormov: iplog+
Details | Diff
Improved patch to add JUnit tests to check serlvet and filter mapping merge behavior (26.10 KB, patch)
2010-06-02 20:06 EDT, Larry Isaacs CLA
dimitar.giormov: iplog+
Details | Diff
patch addresses mapping merging problem in web 2.5 and 3.0 (12.37 KB, patch)
2010-06-04 08:20 EDT, Dimitar Giormov CLA
no flags Details | Diff
almost the same test patch min corrections (25.56 KB, patch)
2010-06-04 08:21 EDT, Dimitar Giormov CLA
no flags Details | Diff
Updated JUnit patch so WebApp3MergerTest tests WebApp3Merger (26.11 KB, patch)
2010-06-04 10:01 EDT, Larry Isaacs CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Larry Isaacs CLA 2010-06-02 12:43:19 EDT
The changes for Bug 305849 included changes to WebAppMerger.getArtifactFromList() which causes a regression in the merger behavior.  As an example, the following is a valid web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
  <filter>
    <filter-name>TestFilter</filter-name>
    <filter-class>test.TestFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/bar/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/foo/*</url-pattern>
  </filter-mapping>
</web-app>

When merging the "/foo/*" mapping, the getArtifactFromList() will report that it exists because it only checks the filter-name to determine a match.  As a result, the merged model will not include the "/foo/*" filter-mapping since it follows another mapping for the same servlet.  This can be seen in the Project Explorer where the Deployment Descriptor Filter Mappings only displays the "/bar/*" mapping.  I haven't looked in detail yet but I suppect the behavior of other elements have been affected as well, for example servlet mappings.  I'll try to look deeper but wanted to go ahead and report the bug.
Comment 1 Larry Isaacs CLA 2010-06-02 13:01:08 EDT
Actually, WebAppMerger.mergeFilters() changed from using copyAllContentInBase() to using copyMissingContentInBase() when merging the filter mappings. WebAppMerger.mergeServlets() made the same change, so perhaps these are the only elements whose behavior has been affected.
Comment 2 Larry Isaacs CLA 2010-06-02 17:11:45 EDT
Created attachment 170884 [details]
JUnit patch to add tests for this use case

The patch adds a couple of tests to WebAppMergerTest and WebApp3MergerTest that exercises this use case.

The issue appears to be that merging behavior needs to differ between when the web.xml model is merged into the merged model and when annotations model are merged into the merged model.  I think merging the web.xml model needs to behave like a "copy" and while merging the annotation model needs to behave like the currently implemented "add missing".  The JUnit tests in the patch fail because they are testing for "copy" behavior when the merge is performing the "add missing".  I think the merger will need to add support for "copy" so the Web25MergedModelProvider can use it for merging the web.xml model and continue to use the "add missing" support for merging the annotation model.  I'll see if I can come up with a patch to the code that takes this approach and update the JUnit tests to test both "copy" and "add missing" modes of merging.
Comment 3 Larry Isaacs CLA 2010-06-02 20:01:14 EDT
Created attachment 170897 [details]
Possible patch to address merge behavior for servlet and filter mappings

There may be a more appropriate way to fix this, but I believe this patch will address the issue while being minimally intrusive.  It defines a new COPY type for merging.  This new type is only used to alter merging of filter mappings and servlet mappings, which I believe will restore prior behavior with respect to merging the web.xml model into the merged model.  Web25MergedModelProvider is updated to use the appropriate type of merge when merging the web.xml and annotations models.
Comment 4 Larry Isaacs CLA 2010-06-02 20:06:46 EDT
Created attachment 170898 [details]
Improved patch to add JUnit tests to check serlvet and filter mapping merge behavior

This version of JUnit tests patch includes servlet and filter mapping tests that covers both "copy" and "add" merging.
Comment 5 Carl Anderson CLA 2010-06-02 22:05:31 EDT
Kaloyan, can your team handle this?  Please retarget as appropriate.
Comment 6 Dimitar Giormov CLA 2010-06-04 07:48:06 EDT
Just start digging into this.

From first impressions the problem is obvious, the model utilizes the list of url-patterns and considers as duplicated all other filter/servlet mappings that it finds. This causes problems when the filter/servlet mapping is written in web 2.4 style in DD, where the filter mapping had for value an objet instead of list.

The problem worsens with Java EE 6 where annotations are involved. And on top of it the annotation model for Web 3.0 does not process correctly the value annotations of servlets and filters.

So I think I will start with Isaacs patch and work on the issue.
Comment 7 Dimitar Giormov CLA 2010-06-04 08:20:22 EDT
Created attachment 171093 [details]
patch addresses mapping merging problem in web 2.5 and 3.0

https://bugs.eclipse.org/bugs/show_bug.cgi?id=315755
was found during processing this bug report.

for web 2.5 I used Isaacs solution and fixed a little bit web 3.0 processing.

But there should be some careful testing of this.
Comment 8 Dimitar Giormov CLA 2010-06-04 08:21:31 EDT
Created attachment 171094 [details]
almost the same test patch min corrections
Comment 9 Larry Isaacs CLA 2010-06-04 10:01:04 EDT
Created attachment 171102 [details]
Updated JUnit patch so WebApp3MergerTest tests WebApp3Merger

Thanks Dimitar,

Unfortunately, I copy and pasted the tests from WebAppMergerTest to WebApp3MergerTests and forgot to update the WebAppMerger to WebApp3Merger.  This patch corrects that oversight.  I also updated the method name testServletMappingsCaseSame() to testServletMappingsCaseSameAdd() to be consistent with the others.  This patch is derived from your test patch, but I didn't notice any changes from the original patch, so maybe some of these changes were intented to be fixed by your patch.

With this update, the testFilterMappingsCaseSameAdd() now fails for the WebApp3MergetTests because the two URL patterns are being merged into the one filter mapping.  My understanding is that web.xml overrides annotations, so I wouldn't think the url-patterns would be additive.  I'm not well connected to the Servlet spec process, so I could be out of date about that.  There was a discussion about url-patterns between web.xml and web-fragment.xml on a Tomcat private list where the EG response was that these are not additive, web.xml wins. So I would think this would be true of annotations as well.  Though I don't think it matters for servlet mappings, this merging the url-patterns would also alter the order of filters in a web.xml if it contained something like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
  <filter>
    <filter-name>TestFilter</filter-name>
    <filter-class>test.TestFilter</filter-class>
  </filter>
  <filter>
    <filter-name>TestFilter2</filter-name>
    <filter-class>test.TestFilter2</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/bar/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>TestFilter2</filter-name>
    <url-pattern>/foo/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/foo/*</url-pattern>
  </filter-mapping>
</web-app>

I would expect the merged model to accurately reflect this organization from the web.xml for both Servlet 2.5 and 3.0.
Comment 10 Dimitar Giormov CLA 2010-06-04 10:15:51 EDT
About the additive merging, I actually spoke with a colleague from our runtime department, but did not check the spec, I will do so before proceeding.

About web 3.0 merging into single object. servlet/filter mapping was altered in 2.5 to support list, in my opinion this gives us the opportunity to simplify the presentation of this relation. Going to web 2.4 approach does not seem right to me. And another reason for combining them is that it becomes scientifically harder to merge them correctly.
Comment 11 Larry Isaacs CLA 2010-06-04 10:34:03 EDT
Okay, I'm fine with the merged model differing in structure from the original web.xml.  When the structure is important, the model for web.xml can be obtained.  However, examining the implementation of Web25MergedModelProvider, you will have to ask for the merged model first before asking for the web.xml model, otherwise you will keep getting null for the web.xml model.  I don't think the API makes this clear.  Maybe this aspect of Web25MergedModelProvider should be improved at some point.
Comment 12 Dimitar Giormov CLA 2010-06-23 06:22:21 EDT
Larry I am not sure if I understood you correctly, but basically you can get the xml model by using getModelObject(IPath).
Is this what you are asking for?
Comment 13 Larry Isaacs CLA 2010-06-24 08:55:43 EDT
Yes.  An adopter would use getModelObject(IPath) to get the web.xml model when seeing the actual web.xml structure is important.  But adopters will need to be aware that WTP 3.2 in its current form requires that you call getModelObject() first, otherwise getModelObject(IPath) will keep returning null.  Given that WTP 3.2 has already shipped this way, changing this in 3.2.x may not be worth it since the adopter would have to depend on 3.2.1 or later to avoid calling getModelObject() first.  Adopters will also need to be aware that if their web project contains no annotations, the merged model may still differ from the web.xml model.  It complicates usage, but is manageable.
Comment 14 Dimitar Giormov CLA 2010-06-29 09:54:58 EDT
So as I understand basically you are ok with the current, but it will require a better one for the next version right?
So I can proceed with commit?

Maybe it will be best if we open another bug for this.
Going back on what you said. You are right that the adopter should be aware that the merged model might be slightly different, than the xml model if there are no annotations. (maybe we can work on this and make it return untouched xml model)

This I do not understand completely:
"But adopters will need to be
aware that WTP 3.2 in its current form requires that you call getModelObject()
first, otherwise getModelObject(IPath) will keep returning null."

Calling getModelObject(IPath) should return in all cases the xml or annotation model. getModelObject() is not requiired to be called before that. There are special cases where getModelObject() will return only xml model within modify call, since we have no support for editing and adding entries to the annotation model.
Comment 15 Larry Isaacs CLA 2010-06-29 10:33:41 EDT
SAS as an adopter routinely requires a specific version of Eclipse when using our product.  Thus, our plug-ins can adapt to whatever behavior is implemented in Eclipse and WTP.  Having the merged model not preserve the structure of the web.xml contribution complicates our implementation but is something we can deal with.  So your changes are fine for committing from our point of view.  I don't know about other adopters though.

With respect to the calling getModelObject() before getModelObject(IPath), I'm refering to the use case where the model is being inspected and not necessarily modified, i.e. validateEdit() hasn't be called.  For web.xml, getModelObject(IPath) will return null if ddProvider is null and will not force ddProvider to be set if it isn't already.  Calling getModelObject() will force ddProvider to be set.  I've seen this issue in our JUnit tests, so it might be a dispose() that's causing ddProvider to be null and calling getModelObject() helps ensure it is restored since getModelObject(IPath) won't do it.
Comment 16 Dimitar Giormov CLA 2010-06-30 04:23:51 EDT
@Larry Thanks now I understand.
So I will create a separate bug for this and try to fix it for SR1 if this is ok for you?

@Chuck can you review the fix?
Comment 17 Chuck Bridgham CLA 2010-07-02 10:38:26 EDT
approved
Comment 18 Dimitar Giormov CLA 2010-07-06 04:32:02 EDT
This bug is caused by adapting web merged model to work for Web 3.0 and changes the behavior of the MergedModel in Web 2.5 
Current behavior will ignore certain servlet mappings declarations if they are defined in Web 1.4 style. where it is possible to have many declarations of servlet mapping with one and the same servlet name and different url pattern.

The fix considers this behavior by adding copy mechanism from xml to the merged model where copy is used where no merge is necessary. Additionally to cover the Web 3.0 scenario the Mappings are merged in name > list structure.

To test the issue additional junit tests were created.

The patch is reviewed by Chuck

I think this has a low risk.
Comment 19 Dimitar Giormov CLA 2010-07-07 05:48:39 EDT
committed and released