Hi,

On Thu, Sep 8, 2016 at 2:40 PM, Martin Kouba <mkouba@redhat.com> wrote:
I think this is missing the key insight that CDI extensions are portable
and that it's "just" providing a 1 class extension that adds 3 orso
build-in beans.

Stuart has a good point about backward compatibility. Servlet impl would have to detect CDI version and skip registration if not 2.0+. I think SERVLET_SPEC-116 should be reopened and the discussion restarted.

Indeed, that is a good point, but that's basically part of the challenge of moving those build-in beans. If I'm not mistaken Antoine once mentioned in one of the other related issues something along the line that CDI 2.0 could provide something for that. So the "is 2.0+" check could be made easier or more straightforward.

Kind regards,
Arjan Tijms




 


Kind regards,
Arjan Tijms






    But it's more complicated then it sounds. For example,
    HttpServletRequest attibutes might be used as backing storage of the
    request context. So that it cannot simply change...

    Anyway, I think this problem deserves some attention from both the
    CDI and the Servlet EG.

    Martin

    Dne 8.9.2016 v 13:31 arjan tijms napsal(a):

        Hi,

        On Thu, Sep 8, 2016 at 1:09 PM, Romain Manni-Bucau
        <rmannibucau@gmail.com <mailto:rmannibucau@gmail.com>
        <mailto:rmannibucau@gmail.com <mailto:rmannibucau@gmail.com>>>

        wrote:

            Hit that issue as well several times.

            It is more vicious than it looks like IMO cause CDI will
        *never* get
            *the* right request for everybody, it is as simple as that.
        Any part
            of the app can rely on the wrapper level N (of course N being
            different for each mentionned parts of the app).


        What I was thinking, but maybe I'm wrong, is that the
        application never
        "just" wraps the request and uses it for itself. It always
        passes it to
        the container, which then passes it on to the next Filter,
        Servlet, or
        whatever. So at that point the container code has the opportunity to
        store the request as being the "current" one.

        E.g. if you do:

        RequestDispatcher dispatcher =
        servletContext().getRequestDispatcher(...);
        dispatcher.forward(wrap(request), response);

        Then the RequestDispatcher, which is a container class, receives the
        wrapped request and can make it available.

        The other way around, eventually every AuthModule, Filter or
        Servlet has
        to be called by the container at some point. E.g. the "protected
        void
        service(HttpServletRequest req, HttpServletResponse resp)" is
        called by
        the container.

        So just before the container invokes the HttpServlet#service
        method, the
        container can store the request, and CDI (via an SPI) can pick it up
        from there.

        That way in every context you can always have the *current*
        request (the
        request that's passed in to the last Servlet or Filter call on
        the stack).

        Kind regards,
        Arjan Tijms















            Best CDI can do is to provide the request it has (already
        the case
            and cost pretty much nothing) and enable the user to
        produces very
            easily its own request from its filter (or equivalent) for
        its usage
            IMO - which is IMO already doable but maybe there is another
            shortcut we can introduce I didnt think about. If you look
        one step
            further any web framework built on top of CDI does it and
        therefore
            runs in a well known context.


            Romain Manni-Bucau
            @rmannibucau <https://twitter.com/rmannibucau
        <https://twitter.com/rmannibucau>> |  Blog
            <https://blog-rmannibucau.rhcloud.com
        <https://blog-rmannibucau.rhcloud.com>> | Old Wordpress Blog
            <http://rmannibucau.wordpress.com
        <http://rmannibucau.wordpress.com>> | Github
            <https://github.com/rmannibucau
        <https://github.com/rmannibucau>> | LinkedIn
            <https://www.linkedin.com/in/rmannibucau
        <https://www.linkedin.com/in/rmannibucau>> | Tomitriber
            <http://www.tomitribe.com> | JavaEE Factory
            <https://javaeefactory-rmannibucau.rhcloud.com
        <https://javaeefactory-rmannibucau.rhcloud.com>>

            2016-09-08 13:03 GMT+02:00 arjan tijms
        <arjan.tijms@gmail.com <mailto:arjan.tijms@gmail.com>
            <mailto:arjan.tijms@gmail.com <mailto:arjan.tijms@gmail.com>>>:

                Hi,

                On Thu, Sep 8, 2016 at 12:40 PM, Martin Kouba
        <mkouba@redhat.com <mailto:mkouba@redhat.com>
                <mailto:mkouba@redhat.com <mailto:mkouba@redhat.com>>>

        wrote:

                    that's a good question. In Weld, the request object is
                    captured during request context activation, i.e. during
                    ServletRequestListener.requestInitialized()
        notification and
                    before any filter or servlet is invoked. So wrappers are
                    ignored and the original/first request is used.


                Indeed, although do note that some servers (Liberty and
        WebLogic
                I think) send the
        ServletRequestListener.requestInitialized()
                notification rather late, and do that after the application
                already has seen the request and has had a chance to
        wrap it.
                This by itself is a separate problem. So on these
        servers, Weld
                would receive an early request but not necessarily the
        earliest.


                    But TBH I don't think we can fix this easily as I'm not
                    aware of any portable way to listen for "wrapping
        actions".


                This would have to happen with Server specific code I guess,
                just as Weld now requires an SPI to obtain the current
        principal
                for injection.

                You could say that the Servlet container could store the
        request
                "somewhere" on a stack structure, just before it invokes the
                ServerAuthModule, Filter, Servlet and anything else I
        may have
                forgotten, and then when control flows back to each Servlet,
                Filter, etc unwind that stack.

                At the very least the spec for now should perhaps
        clarify this?

                Kind regards,
                Arjan Tijms





                    Martin

                    Dne 8.9.2016 v 11:02 arjan tijms napsal(a):

                        Hi,

                        The CDI spec defines a built-in bean for the type
                        HttpServletRequest. In
                        3.8 it says:

                        "A servlet container must provide the following
        built-in
                        beans, all of
                        which have qualifier @Default:

                        a bean with bean type
                        javax.servlet.http.HttpServletRequest, allowing
                        injection of a reference to the HttpServletRequest"

                        An HttpServletRequest however can be wrapped
        multiple
                        times and by
                        multiple artefacts. I.e. by a ServerAuthModule,
        Filter and a
                        RequestDispatcher.

                        The question now is; which version of the
                        HttpServletRequest is supposed
                        to be injected?

                        * The first one in the chain?
                        * The last one in the chain?
                        * The current one at a given point in the chain?

                        A little bit of experimenting seems to indicate
        it's now
                        often "one of
                        the first ones", e.g. the one that happened to be
                        current when e.g. a
                        ServletRequestListener that initialises a
        specific CDI
                        implementation is
                        called.

                        I think this is a little confusing, as working
        with an
                        injected request
                        can now totally ignore the request wrapping that has
                        been done and break
                        an application badly.

                        Thoughts?

                        Kind regards,
                        Arjan Tijms



                        _______________________________________________
                        cdi-dev mailing list
                        cdi-dev@lists.jboss.org
        <mailto:cdi-dev@lists.jboss.org> <mailto:cdi-dev@lists.jboss.org
        <mailto:cdi-dev@lists.jboss.org>>
                        https://lists.jboss.org/mailman/listinfo/cdi-dev
        <https://lists.jboss.org/mailman/listinfo/cdi-dev>

        <https://lists.jboss.org/mailman/listinfo/cdi-dev
        <https://lists.jboss.org/mailman/listinfo/cdi-dev>>

                        Note that for all code provided on this list, the
                        provider licenses the code under the Apache License,
                        Version 2
                        (http://www.apache.org/licenses/LICENSE-2.0.html
        <http://www.apache.org/licenses/LICENSE-2.0.html>
                        <http://www.apache.org/licenses/LICENSE-2.0.html
        <http://www.apache.org/licenses/LICENSE-2.0.html>>). For
                        all other ideas provided on this list, the provider
                        waives all patent and other intellectual
        property rights
                        inherent in such information.


                    --
                    Martin Kouba
                    Software Engineer
                    Red Hat, Czech Republic



                _______________________________________________
                cdi-dev mailing list
                cdi-dev@lists.jboss.org <mailto:cdi-dev@lists.jboss.org>
        <mailto:cdi-dev@lists.jboss.org <mailto:cdi-dev@lists.jboss.org>>
                https://lists.jboss.org/mailman/listinfo/cdi-dev
        <https://lists.jboss.org/mailman/listinfo/cdi-dev>
                <https://lists.jboss.org/mailman/listinfo/cdi-dev
        <https://lists.jboss.org/mailman/listinfo/cdi-dev>>

                Note that for all code provided on this list, the provider
                licenses the code under the Apache License, Version 2
                (http://www.apache.org/licenses/LICENSE-2.0.html
        <http://www.apache.org/licenses/LICENSE-2.0.html>
                <http://www.apache.org/licenses/LICENSE-2.0.html
        <http://www.apache.org/licenses/LICENSE-2.0.html>>). For all
                other ideas provided on this list, the provider waives all
                patent and other intellectual property rights inherent
        in such
                information.





--
Martin Kouba
Software Engineer
Red Hat, Czech Republic