servlet-spec
  1. servlet-spec
  2. SERVLET_SPEC-81

Clarify to users that the container will ensure work done in Servlet#init(ServletConfig) will be visible to threads which later invoke service methods.

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Labels:
      None

      Description

      As a longtime user of the Servlet specification, I have recently become more aware of thread-safety concerns, and when making my last servlet, I realised that if doGet() and friends are invoked from a thread pool, they are only guaranteed to see assignments I make in init(ServletConfig) if someone else has taken adequate care that the work done by that thread is visible to others.

      Presumably, containers have in fact done this for nearly two decades. But it would be nice to have it spelled out somewhere, so that I can rely on this behaviour, and don't need to second-guess the environment and perform my own locking/synchronization.

        Activity

        Hide
        markt_asf added a comment -

        This looks like an application concern rather than a container concern to me.

        The container will guarantee that init(ServletConfig) completes successfully before processing any requests (as per the Javadoc for init) but makes no other guarantees.

        How do you propose that the container ensures that "work" completed in init() is visible to all the request processing threads?

        Show
        markt_asf added a comment - This looks like an application concern rather than a container concern to me. The container will guarantee that init(ServletConfig) completes successfully before processing any requests (as per the Javadoc for init) but makes no other guarantees. How do you propose that the container ensures that "work" completed in init() is visible to all the request processing threads?
        Hide
        dtbullock added a comment - - edited

        That's just the point - the spec needs to provide a slightly stronger guarantee, and say that the end of init(ServletConfig) 'happens before' invocations of doGet() and friends, in the sense that it is defined in section 17.4.5 of the JLS

        Without this guarantee, javax.servlet.GenericServlet by definition has a threading bug, because it does not synchronize access to the 'config' field.

        I'm not a container-author nor an expert in the Java Memory Model, and I'm not asking for the spec to proscribe a particular mechanism. I just need the spec to relieve me of the responsibility. The beauty of the Servlet spec is that I don't have to think about concurrency matters and can basically pretend I'm in a single-threaded environment for most use-cases. However, when I do think about it, I want to be sure I'm thinking about it right.

        However, I believe that the requirement could be satisfied by ensuring that worker-threads are forced to lock the same object-monitor which a given Servlet's initializer-thread unlocked, before they become eligible to handle requests for that Servlet. They need not lock it every time they need to invoke a service-method - just when they are first given a reference to the properly-initialized Servlet. This is a pretty natural way to arrange for thread co-operation, and probably happens de-facto all the time anyway. Hence this amendment would likely not put any further obligations on container-authors.

        Show
        dtbullock added a comment - - edited That's just the point - the spec needs to provide a slightly stronger guarantee, and say that the end of init(ServletConfig) 'happens before' invocations of doGet() and friends, in the sense that it is defined in section 17.4.5 of the JLS Without this guarantee, javax.servlet.GenericServlet by definition has a threading bug, because it does not synchronize access to the 'config' field. I'm not a container-author nor an expert in the Java Memory Model, and I'm not asking for the spec to proscribe a particular mechanism. I just need the spec to relieve me of the responsibility. The beauty of the Servlet spec is that I don't have to think about concurrency matters and can basically pretend I'm in a single-threaded environment for most use-cases. However, when I do think about it, I want to be sure I'm thinking about it right. However, I believe that the requirement could be satisfied by ensuring that worker-threads are forced to lock the same object-monitor which a given Servlet's initializer-thread unlocked, before they become eligible to handle requests for that Servlet. They need not lock it every time they need to invoke a service-method - just when they are first given a reference to the properly-initialized Servlet. This is a pretty natural way to arrange for thread co-operation, and probably happens de-facto all the time anyway. Hence this amendment would likely not put any further obligations on container-authors.
        Hide
        Shing Wai Chan added a comment -

        In javadoc of Servlet#init(ServletConfig), we have
        "The servlet container calls the init method exactly once after instantiating the servlet. The init method must complete successfully before the servlet can receive any requests."

        This guarantees that the #init is invoked before #doGet.

        Show
        Shing Wai Chan added a comment - In javadoc of Servlet#init(ServletConfig), we have "The servlet container calls the init method exactly once after instantiating the servlet. The init method must complete successfully before the servlet can receive any requests." This guarantees that the #init is invoked before #doGet.
        Hide
        dtbullock added a comment -

        That would be entirely adequate if the servlet container calls init() and services requests using the same thread. However, containers do not necessarily do this. Therefore, the spec needs to specify whether the container-implementer or the servlet-author is responsible for handling the resultant thread-safety issue.

        Show
        dtbullock added a comment - That would be entirely adequate if the servlet container calls init() and services requests using the same thread . However, containers do not necessarily do this. Therefore, the spec needs to specify whether the container-implementer or the servlet-author is responsible for handling the resultant thread-safety issue.

          People

          • Assignee:
            Unassigned
            Reporter:
            dtbullock
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: