servlet-spec
  1. servlet-spec
  2. SERVLET_SPEC-36

Clarify relationship of metadata-complete and ServletContainerInitializers

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None

      Description

      Servlet Spec 3.0 does not make clear what relationship exists between metadata-complete setting in web.xml and the discovering and invocation of ServletContainerInitializers.

      The stated purpose of ServletContainerInitializers is to allow for pluggable framework initialization, and the given example is initializing the JSP container. This implies that a setting of metadata-complete=true is irrelevant to the finding and calling of ServletContainerInitializers.

      If so, even if metata-complete==true for a given webapp, then we are forced to scan every class available to the webapp in the case that a discovered ServletContainerInitializer has a @HandlesTypes annotation - if the HandlesTypes specifies an annotation, then we will scan every class for that annotation, or if HandlesTypes specifies a class, then we need to scan for that class and its descendants. This can take a significant amount of time for a webapp with a large number of jars in WEB-INF/lib.

      Please clarify if this is correct, or if metatadata-complete==true means that all ServletContainerInitializers are ignored.

        Activity

        Hide
        Mark Struberg added a comment -

        I'm not sure what your point with the manifest is?

        > The included jars, hence excluded jars, specify in <absolute-ordering> is independent of the value of metadata-complete.

        8.2.1: "... As before, if the metadata-complete element is set to true in the web.xml descriptor, annotations in the class files and web-fragments bundled in jars will not be processed."

        or a bit paraphrased: "... if the metadata-complete element is set to true ... web-fragments bundled in jars will not be processed.".

        Which I read as: No annotations, no web-fragments, which mean jars of web-fragments not listed in the web.xml are excluded from processing if metadata-complete="true". Is this interpretation correct? Yes/No?

        And now please combine this with the rules specified in 8.2.2:
        "Excluded jars are not scanned for annotated servlets, filters or listeners. However, if a servlet, filter or listener from an excluded jar is listed in web.xml or a non-excluded web-fragment.xml, then it's annotations will apply unless otherwise excluded by metadata-complete. ServletContextListeners discovered in TLD files of excluded jars are not able to configure filters and servlets using the programmatic APIs. Any attempt to do so will result in an IllegalStateException. If a discovered ServletContainerInitializer is loaded from an excluded jar, it will be ignored. Excluded jars are not scanned for classes to be handled by any ServletContainerInitializer."

        I just mentioned 8.2.4, because it does not mention any exclusions to the general rules defined in 8.2.1.

        Show
        Mark Struberg added a comment - I'm not sure what your point with the manifest is? > The included jars, hence excluded jars, specify in <absolute-ordering> is independent of the value of metadata-complete. 8.2.1: "... As before, if the metadata-complete element is set to true in the web.xml descriptor, annotations in the class files and web-fragments bundled in jars will not be processed." or a bit paraphrased: "... if the metadata-complete element is set to true ... web-fragments bundled in jars will not be processed.". Which I read as: No annotations, no web-fragments, which mean jars of web-fragments not listed in the web.xml are excluded from processing if metadata-complete="true". Is this interpretation correct? Yes/No? And now please combine this with the rules specified in 8.2.2: "Excluded jars are not scanned for annotated servlets, filters or listeners. However, if a servlet, filter or listener from an excluded jar is listed in web.xml or a non-excluded web-fragment.xml, then it's annotations will apply unless otherwise excluded by metadata-complete. ServletContextListeners discovered in TLD files of excluded jars are not able to configure filters and servlets using the programmatic APIs. Any attempt to do so will result in an IllegalStateException. If a discovered ServletContainerInitializer is loaded from an excluded jar, it will be ignored. Excluded jars are not scanned for classes to be handled by any ServletContainerInitializer." I just mentioned 8.2.4, because it does not mention any exclusions to the general rules defined in 8.2.1.
        Hide
        Shing Wai Chan added a comment -

        I mention MANIFEST.MF as another example of metadata.

        We may like to clarify the wording of 8.2.1 to be more specific to deployment descriptor related annotations.
        If we interpret 8.2.1 as no processing for "all" annotation, then does it means that CDI annotations should not be processed. Of course, this is "not" the case. (And this is also contradict the documents in web.xml schema.)

        Also, in our case, we have the annotation, @HandlesTypes. And if we do not process @HandlesTypes (when metadata-complete=true) and still look up the META-INF/services, in this case, ServletContainerInitializer, then the ServletContainerInitializer will not be working properly.

        As I mentioned before, we would have a clarification on 8.2.4. And we would like to be more specific about the deployment descriptor related annotations.

        Show
        Shing Wai Chan added a comment - I mention MANIFEST.MF as another example of metadata. We may like to clarify the wording of 8.2.1 to be more specific to deployment descriptor related annotations. If we interpret 8.2.1 as no processing for "all" annotation, then does it means that CDI annotations should not be processed. Of course, this is "not" the case. (And this is also contradict the documents in web.xml schema.) Also, in our case, we have the annotation, @HandlesTypes. And if we do not process @HandlesTypes (when metadata-complete=true) and still look up the META-INF/services, in this case, ServletContainerInitializer, then the ServletContainerInitializer will not be working properly. As I mentioned before, we would have a clarification on 8.2.4. And we would like to be more specific about the deployment descriptor related annotations.
        Hide
        Shing Wai Chan added a comment -

        This issue is discussed in expert group and the email archive can be found in http://java.net/projects/servlet-spec/lists/users/archive with subject "About SERVLET_SPEC-36".

        Show
        Shing Wai Chan added a comment - This issue is discussed in expert group and the email archive can be found in http://java.net/projects/servlet-spec/lists/users/archive with subject "About SERVLET_SPEC-36 ".
        Hide
        Mark Struberg added a comment -

        > If we interpret 8.2.1 as no processing for "all" annotation, then does it means that CDI annotations should not be processed.
        You are mixing apples with eggs. What does the CDI annotations have to do with servlet specific annotations?

        The main point here is: if you don't allow a user to disable the SCI somehow, then this might be a major pain in some situations!

        In our case it IS already a major pain that SCI automatically start if there is no web.xml. Not only the vastly higher scan times, but e.g. JSF defines that a SCI must be present for automatically starting JSF. In our case this did lead to starting JSF for our resources webapp which contains no JSF at all! It just blew up on servlet-3.0 containers and we had to do crazy things to get rid of it.

        I'm perfectly fine if an empty <absolute-ordering/> finally will disable SCI pickup!

        Please allow me to ask for another clarification:
        What is the lifecycle of the SCI? It's name "Serlvet CONTAINER Initializer" indicates that this only gets scanned 1 time when the container boots. Completely independent of any web application deployed therein.
        8.2.4 "An instance of the ServletContainerInitializer is looked up via the jar services API by the container at container / application startup time"

        It also defines when the onStartup method gets called, but I have not yet understood if there is 1 SCI instance per webapp and SCI-Class or if the container startup creates a singleton for the whole container and all webapps invoke the onStartup to the same instance? Is this mentioned somewhere? This has a major impact about how to write the SCIs. Please also think about having 2 webapps containing jsf-impl.jar in their WEB-INF/lib (so the same JsfSCI but in 2 different isolated classloaders) vs having the jsf-impl.jar in a container lib dir.

        Show
        Mark Struberg added a comment - > If we interpret 8.2.1 as no processing for "all" annotation, then does it means that CDI annotations should not be processed. You are mixing apples with eggs. What does the CDI annotations have to do with servlet specific annotations? The main point here is: if you don't allow a user to disable the SCI somehow, then this might be a major pain in some situations! In our case it IS already a major pain that SCI automatically start if there is no web.xml. Not only the vastly higher scan times, but e.g. JSF defines that a SCI must be present for automatically starting JSF. In our case this did lead to starting JSF for our resources webapp which contains no JSF at all! It just blew up on servlet-3.0 containers and we had to do crazy things to get rid of it. I'm perfectly fine if an empty <absolute-ordering/> finally will disable SCI pickup! Please allow me to ask for another clarification: What is the lifecycle of the SCI? It's name "Serlvet CONTAINER Initializer" indicates that this only gets scanned 1 time when the container boots. Completely independent of any web application deployed therein. 8.2.4 "An instance of the ServletContainerInitializer is looked up via the jar services API by the container at container / application startup time" It also defines when the onStartup method gets called, but I have not yet understood if there is 1 SCI instance per webapp and SCI-Class or if the container startup creates a singleton for the whole container and all webapps invoke the onStartup to the same instance? Is this mentioned somewhere? This has a major impact about how to write the SCIs. Please also think about having 2 webapps containing jsf-impl.jar in their WEB-INF/lib (so the same JsfSCI but in 2 different isolated classloaders) vs having the jsf-impl.jar in a container lib dir.
        Hide
        Shing Wai Chan added a comment -

        The metadata-completed is clarified as mentioned above. For ServletContainerInitializer, an instance will be created at each application startup time.

        Sending eod-pluggability.fm
        Sending overview.fm
        Sending status.fm
        Transmitting file data ...
        Committed revision 41.

        Show
        Shing Wai Chan added a comment - The metadata-completed is clarified as mentioned above. For ServletContainerInitializer, an instance will be created at each application startup time. Sending eod-pluggability.fm Sending overview.fm Sending status.fm Transmitting file data ... Committed revision 41.

          People

          • Assignee:
            Shing Wai Chan
            Reporter:
            janbartel
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: