Re: Thread-safety of javax.servlet.Servlet#getServletConfig()
On 12/5/2016 7:40 AM, Péter Gergely Horváth wrote: Hi Chris, Thanks your four input: this question is somewhere in-between... :) We have *definitely* seen cases, where a piece of code like the one below sometimes (a couple of times from tens of thousands of successfully serviced requests) found the stored field to be null - with a NullPointerException being thrown on the first access of the fooBarService field. @WebServlet("/open") public class FooBarServlet extends HttpServlet { private FooBarService fooBarService; @Override public void init() throws ServletException { try { ApplicationContext applicationContext = (ApplicationContext) getServletContext().getAttribute("springContext"); fooBarService = applicationContext.getBean("fooBarService", FooBarService.class); } catch (Exception ex) { // wrap any exceptions to ServletException so as to comply with Servlet contract throw new ServletException("Initialization failed with exception", ex); Does this exception ever occur? -Terence Bandoian } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } private void processRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { List = fooBarService.getFooBars(); /// we have seen NPEs thrown from here /// ... } For the first glance, it seemed to be obvious that it must have been a threading issue, which could easily be solved by adding volatile to the stored fooBarService field. However, I was more than confused seeing that javax.servlet.GenericServlet#config uses the same approach by simply storing the ServletConfig into a field and reading it later on without any locking etc. I quickly scanned through the Servlet specs and Catalina codes, but cannot really locate any explicit reference to thread-safety of javax.servlet.GenericServlet#getServletConfig, that is where the question originates. I would by much obliged if you had any inputs, ideas regarding this, or on the approach one could take to confirm it on his/her own. Thanks, Peter On Mon, Nov 28, 2016 at 6:45 PM, Christopher Schultz < ch...@christopherschultz.net> wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Péter, On 11/28/16 11:01 AM, Péter Gergely Horváth wrote: Thank you very much for your feedback, but I think there is a slight misunderstanding here: I know the order in which a servlet is initialized and put into service, and this question is not related to that. It's related to the _visibility_ of the field. The question is about the thread safety of the field access: if you carefully check the details of javax.servlet.GenericServlet#config and compare the implementation to the sample "NoVisibility" from the book Java Concurrency in Practice, then it is seems to follow the same pattern, which is "not thread-safe because the value field is accessed from both get and set without synchronization. Among other hazards, it is susceptible to stale values: if one thread calls set, other threads calling get may or may not see that update." [1]. Personally, I would like to understand why this implementation is not (if not) susceptible to the stale values phenomenon [2]; there might be someone, who can point me to the right direction. I think you are correct that there is a theoretical multi-threaded race-condition, here. The container may initialize the servlet in one thread and service e.g. the first request in another thread, and the ServletContext reference might not be written to main memory and then read-back by the request-processing thread. Potential fixes for this would be either to define the ServletContext member to be volatile or to use synchronized methods.' Adding synchronization to the init() method would not be a problem at all: there is very little monitor contention at that stage and the container would only expect to call that method a single time. Adding synchronization to the getServletContext method, though, might represent a reduction in performance, since getServletContext gets called many times during the lifetime of a Servlet, and from many thread s. Likewise, marking the ServletContext member as "volatile" would necessarily require a slow main-memory read every time getServletContext is called. I suspect simple analysis above is the reason for no multithreaded protection being placed on the ServletContext member in question. Péter, is this an academic discussion, or have you in fact seen a case where a servlet has been initialized and yet the first thread to process a request receives a null
Re: Thread-safety of javax.servlet.Servlet#getServletConfig()
On 05/12/2016 13:40, Péter Gergely Horváth wrote: > Hi Chris, > > Thanks your four input: this question is somewhere in-between... :) > > We have *definitely* seen cases, where a piece of code like the one below > sometimes (a couple of times from tens of thousands of successfully > serviced requests) found the stored field to be null - with a > NullPointerException being thrown on the first access of the fooBarService > field. > > @WebServlet("/open") > public class FooBarServlet extends HttpServlet { > > private FooBarService fooBarService; > @Override > public void init() throws ServletException { > try { > ApplicationContext applicationContext = > (ApplicationContext) > getServletContext().getAttribute("springContext"); > fooBarService = > applicationContext.getBean("fooBarService", > FooBarService.class); > > } catch (Exception ex) { > // wrap any exceptions to ServletException so as to comply with > Servlet contract > throw new ServletException("Initialization failed with > exception", ex); > } > } > > protected void doGet(HttpServletRequest request, HttpServletResponse > response) throws ServletException, IOException { > processRequest(request, response); > } > > protected void doPost(HttpServletRequest request, HttpServletResponse > response) throws ServletException, IOException { > processRequest(request, response); > } > > private void processRequest(HttpServletRequest request, > HttpServletResponse response) throws IOException, ServletException { > > List = fooBarService.getFooBars(); /// we have seen NPEs > thrown from here > /// ... > } > > > For the first glance, it seemed to be obvious that it must have been a > threading issue, which could easily be solved by adding volatile to the > stored fooBarService field. > > However, I was more than confused seeing > that javax.servlet.GenericServlet#config uses the same approach by simply > storing the ServletConfig into a field and reading it later on without any > locking etc. > > I quickly scanned through the Servlet specs and Catalina codes, but cannot > really locate any explicit reference to thread-safety of > javax.servlet.GenericServlet#getServletConfig, that is where the question > originates. > > I would by much obliged if you had any inputs, ideas regarding this, or on > the approach one could take to confirm it on his/her own. In theory, it is a problem. In practise, I'd be surprised if anyone was ever troubled by it. Since it appears you did hit this issue, open a bug report and we'll get Tomcat's implementation fixed. Mark > > Thanks, > Peter > > > On Mon, Nov 28, 2016 at 6:45 PM, Christopher Schultz < > ch...@christopherschultz.net> wrote: > > Péter, > > On 11/28/16 11:01 AM, Péter Gergely Horváth wrote: Thank you very much for your feedback, but I think there is a slight misunderstanding here: I know the order in which a servlet is initialized and put into service, and this question is not related to that. It's related to the _visibility_ of the field. The question is about the thread safety of the field access: if you carefully check the details of javax.servlet.GenericServlet#config and compare the implementation to the sample "NoVisibility" from the book Java Concurrency in Practice, then it is seems to follow the same pattern, which is "not thread-safe because the value field is accessed from both get and set without synchronization. Among other hazards, it is susceptible to stale values: if one thread calls set, other threads calling get may or may not see that update." [1]. Personally, I would like to understand why this implementation is not (if not) susceptible to the stale values phenomenon [2]; there might be someone, who can point me to the right direction. > > I think you are correct that there is a theoretical multi-threaded > race-condition, here. The container may initialize the servlet in one > thread and service e.g. the first request in another thread, and the > ServletContext reference might not be written to main memory and then > read-back by the request-processing thread. > > Potential fixes for this would be either to define the ServletContext > member to be volatile or to use synchronized methods.' > > Adding synchronization to the init() method would not be a problem at > all: there is very little monitor contention at that stage and the > container would only expect to call that method a single time. Adding > synchronization to the getServletContext method, though, might > represent a reduction in performance, since getServletContext gets > called many times during the lifetime of a Servlet, and from many thread > s. > > Likewise, marking the ServletContext member as "volatile" would > necessarily require a slow
Re: Thread-safety of javax.servlet.Servlet#getServletConfig()
Hi Chris, Thanks your four input: this question is somewhere in-between... :) We have *definitely* seen cases, where a piece of code like the one below sometimes (a couple of times from tens of thousands of successfully serviced requests) found the stored field to be null - with a NullPointerException being thrown on the first access of the fooBarService field. @WebServlet("/open") public class FooBarServlet extends HttpServlet { private FooBarService fooBarService; @Override public void init() throws ServletException { try { ApplicationContext applicationContext = (ApplicationContext) getServletContext().getAttribute("springContext"); fooBarService = applicationContext.getBean("fooBarService", FooBarService.class); } catch (Exception ex) { // wrap any exceptions to ServletException so as to comply with Servlet contract throw new ServletException("Initialization failed with exception", ex); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } private void processRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { List = fooBarService.getFooBars(); /// we have seen NPEs thrown from here /// ... } For the first glance, it seemed to be obvious that it must have been a threading issue, which could easily be solved by adding volatile to the stored fooBarService field. However, I was more than confused seeing that javax.servlet.GenericServlet#config uses the same approach by simply storing the ServletConfig into a field and reading it later on without any locking etc. I quickly scanned through the Servlet specs and Catalina codes, but cannot really locate any explicit reference to thread-safety of javax.servlet.GenericServlet#getServletConfig, that is where the question originates. I would by much obliged if you had any inputs, ideas regarding this, or on the approach one could take to confirm it on his/her own. Thanks, Peter On Mon, Nov 28, 2016 at 6:45 PM, Christopher Schultz < ch...@christopherschultz.net> wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA256 > > Péter, > > On 11/28/16 11:01 AM, Péter Gergely Horváth wrote: > > Thank you very much for your feedback, but I think there is a > > slight misunderstanding here: I know the order in which a servlet > > is initialized and put into service, and this question is not > > related to that. It's related to the _visibility_ of the field. > > > > The question is about the thread safety of the field access: if > > you carefully check the details of > > javax.servlet.GenericServlet#config and compare the implementation > > to the sample "NoVisibility" from the book Java Concurrency in > > Practice, then it is seems to follow the same pattern, which is > > "not thread-safe because the value field is accessed from both get > > and set without synchronization. Among other hazards, it is > > susceptible to stale values: if one thread calls set, other threads > > calling get may or may not see that update." [1]. > > > > Personally, I would like to understand why this implementation is > > not (if not) susceptible to the stale values phenomenon [2]; there > > might be someone, who can point me to the right direction. > > I think you are correct that there is a theoretical multi-threaded > race-condition, here. The container may initialize the servlet in one > thread and service e.g. the first request in another thread, and the > ServletContext reference might not be written to main memory and then > read-back by the request-processing thread. > > Potential fixes for this would be either to define the ServletContext > member to be volatile or to use synchronized methods.' > > Adding synchronization to the init() method would not be a problem at > all: there is very little monitor contention at that stage and the > container would only expect to call that method a single time. Adding > synchronization to the getServletContext method, though, might > represent a reduction in performance, since getServletContext gets > called many times during the lifetime of a Servlet, and from many thread > s. > > Likewise, marking the ServletContext member as "volatile" would > necessarily require a slow main-memory read every time > getServletContext is called. > > I suspect simple analysis above is the reason for no multithreaded > protection being placed on the ServletContext member in question. > > Péter, is this an academic discussion, or have you in fact seen a case > where a servlet has been initialized and yet the first thread to > process a request receives a null value
Re: Thread-safety of javax.servlet.Servlet#getServletConfig()
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Péter, On 11/28/16 11:01 AM, Péter Gergely Horváth wrote: > Thank you very much for your feedback, but I think there is a > slight misunderstanding here: I know the order in which a servlet > is initialized and put into service, and this question is not > related to that. It's related to the _visibility_ of the field. > > The question is about the thread safety of the field access: if > you carefully check the details of > javax.servlet.GenericServlet#config and compare the implementation > to the sample "NoVisibility" from the book Java Concurrency in > Practice, then it is seems to follow the same pattern, which is > "not thread-safe because the value field is accessed from both get > and set without synchronization. Among other hazards, it is > susceptible to stale values: if one thread calls set, other threads > calling get may or may not see that update." [1]. > > Personally, I would like to understand why this implementation is > not (if not) susceptible to the stale values phenomenon [2]; there > might be someone, who can point me to the right direction. I think you are correct that there is a theoretical multi-threaded race-condition, here. The container may initialize the servlet in one thread and service e.g. the first request in another thread, and the ServletContext reference might not be written to main memory and then read-back by the request-processing thread. Potential fixes for this would be either to define the ServletContext member to be volatile or to use synchronized methods.' Adding synchronization to the init() method would not be a problem at all: there is very little monitor contention at that stage and the container would only expect to call that method a single time. Adding synchronization to the getServletContext method, though, might represent a reduction in performance, since getServletContext gets called many times during the lifetime of a Servlet, and from many thread s. Likewise, marking the ServletContext member as "volatile" would necessarily require a slow main-memory read every time getServletContext is called. I suspect simple analysis above is the reason for no multithreaded protection being placed on the ServletContext member in question. Péter, is this an academic discussion, or have you in fact seen a case where a servlet has been initialized and yet the first thread to process a request receives a null value when calling getServletContext? - -chris > On Mon, Nov 28, 2016 at 6:08 AM, andreas> wrote: > >> On Fri, 25 Nov 2016 23:02:00 +0930 Péter Gergely Horváth >> wrote >>> Hi All, >>> >>> I am wondering why calling >>> javax.servlet.Servlet#getServletConfig() is thread safe: if you >>> check the implementation in javax.servlet.GenericServlet from >>> servlet API 3.0.1, you see the >> following: >>> >>> package javax.servlet; >>> >>> // lines omitted >>> >>> public abstract class GenericServlet implements Servlet, >>> ServletConfig, java.io.Serializable { // lines omitted >>> >>> private transient ServletConfig config; >>> >>> // lines omitted >>> >>> public void init(ServletConfig config) throws ServletException >>> { this.config = config; this.init(); } >>> >>> // lines omitted >>> >>> public ServletConfig getServletConfig() { return config; } // >>> lines omitted } >>> >>> >>> The field config is written in init(ServletConfig) without any >>> synchronization, locking or config being volatile, while >> getServletConfig() >>> could be called anytime from any later worker thread of the >>> servlet container. I took a quick look into Tomcat/Catalina >>> code base, however I see no indication of the servlet container >>> performing any magic, which would guarantee thread safe access >>> to field config through getServletConfig() from e.g. >>> javax.servlet.GenericServlet#service(ServletRequest, >>> ServletResponse) and the corresponding methods in >>> javax.servlet.http.HttpServlet. >>> >>> Am I missing something here? What will guarantee that if Thread >>> A is used to init(ServletConfig) then Thread B calling >>> getServletConfig() will see the correct state of the field >>> config (Java "happens-before"), and not >> e.g. >>> null? >>> >>> I am asking this because I have seen some legacy code, where a >>> servlet stored something into a field inside the init() method, >>> which was then >> used >>> from within a javax.servlet.http.HttpServlet#doGet or >>> javax.servlet.http.HttpServlet#doPost method, without >>> synchronization of any kind like this: >>> >>> public class FoobarServlet extends HttpServlet { >>> >>> private FoobarService foobarService; >>> >>> @Override public void init() throws ServletException { >>> this.foobarService = // ... acquire foobarService } protected >>> void doGet(HttpServletRequest request, HttpServletResponse >>> response) throws ServletException, IOException { List >>> foobars = this.foobarService.getFoobars(); // read
Re: Thread-safety of javax.servlet.Servlet#getServletConfig()
Hi Andy, Thank you very much for your feedback, but I think there is a slight misunderstanding here: I know the order in which a servlet is initialized and put into service, and this question is not related to that. It's related to the _visibility_ of the field. The question is about the thread safety of the field access: if you carefully check the details of javax.servlet.GenericServlet#config and compare the implementation to the sample "NoVisibility" from the book Java Concurrency in Practice, then it is seems to follow the same pattern, which is "not thread-safe because the value field is accessed from both get and set without synchronization. Among other hazards, it is susceptible to stale values: if one thread calls set, other threads calling get may or may not see that update." [1]. Personally, I would like to understand why this implementation is not (if not) susceptible to the stale values phenomenon [2]; there might be someone, who can point me to the right direction. Thanks, Peter [1] Java Concurrency in Practice: Chapter 3. Sharing Objects 3.1 Visibility [2] https://www.javacodegeeks.com/2014/08/java-concurrency-tutorial-visibility-between-threads.html On Mon, Nov 28, 2016 at 6:08 AM, andreaswrote: > On Fri, 25 Nov 2016 23:02:00 +0930 Péter Gergely Horváth wrote > >Hi All, > > > >I am wondering why calling javax.servlet.Servlet#getServletConfig() is > >thread safe: if you check the implementation in > > javax.servlet.GenericServlet from servlet API 3.0.1, you see the > following: > > > >package javax.servlet; > > > >// lines omitted > > > >public abstract class GenericServlet > > implements Servlet, ServletConfig, java.io.Serializable > >{ > > // lines omitted > > > > private transient ServletConfig config; > > > > // lines omitted > > > > public void init(ServletConfig config) throws ServletException { > > this.config = config; > > this.init(); > > } > > > > // lines omitted > > > > public ServletConfig getServletConfig() { > > return config; > > } > > // lines omitted > >} > > > > > >The field config is written in init(ServletConfig) without any > >synchronization, locking or config being volatile, while > getServletConfig() > >could be called anytime from any later worker thread of the servlet > >container. I took a quick look into Tomcat/Catalina code base, however I > >see no indication of the servlet container performing any magic, which > >would guarantee thread safe access to field config through > >getServletConfig() from e.g. > >javax.servlet.GenericServlet#service(ServletRequest, ServletResponse) and > >the corresponding methods in javax.servlet.http.HttpServlet. > > > >Am I missing something here? What will guarantee that if Thread A is used > >to init(ServletConfig) then Thread B calling getServletConfig() will see > >the correct state of the field config (Java "happens-before"), and not > e.g. > >null? > > > >I am asking this because I have seen some legacy code, where a servlet > >stored something into a field inside the init() method, which was then > used > >from within a javax.servlet.http.HttpServlet#doGet or > >javax.servlet.http.HttpServlet#doPost method, without synchronization of > >any kind like this: > > > >public class FoobarServlet extends HttpServlet { > > > > private FoobarService foobarService; > > > > @Override > > public void init() throws ServletException { > >this.foobarService = // ... acquire foobarService > > } > > protected void doGet(HttpServletRequest request, HttpServletResponse > >response) throws ServletException, IOException { > > List foobars = this.foobarService.getFoobars(); // read the > >field WITHOUT synchronization > > // ... > > } > > // ... > >Is this approach (having no synchronization, locking or the field being > >volatile) correct? I assumed it is not, seeing something like that in the > >servlet API is quite confusing. > > > > > >What do you think? > > > >Thanks, > >Peter > > > A Servlet will process requests only if it is fully initialized, i.e. init > has been executed. The init method gets called only once and the servlet > config won't change afterwards. I don't think there is need for > synchronization. The same is probably valid for your own objects. Problems > arise when individual requests change the state of these objects. > > Andy > > > > > > > > > > > - > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >
Re: Thread-safety of javax.servlet.Servlet#getServletConfig()
On Fri, 25 Nov 2016 23:02:00 +0930 Péter Gergely Horváth wrote >Hi All, > >I am wondering why calling javax.servlet.Servlet#getServletConfig() is >thread safe: if you check the implementation in > javax.servlet.GenericServlet from servlet API 3.0.1, you see the following: > >package javax.servlet; > >// lines omitted > >public abstract class GenericServlet > implements Servlet, ServletConfig, java.io.Serializable >{ > // lines omitted > > private transient ServletConfig config; > > // lines omitted > > public void init(ServletConfig config) throws ServletException { > this.config = config; > this.init(); > } > > // lines omitted > > public ServletConfig getServletConfig() { > return config; > } > // lines omitted >} > > >The field config is written in init(ServletConfig) without any >synchronization, locking or config being volatile, while getServletConfig() >could be called anytime from any later worker thread of the servlet >container. I took a quick look into Tomcat/Catalina code base, however I >see no indication of the servlet container performing any magic, which >would guarantee thread safe access to field config through >getServletConfig() from e.g. >javax.servlet.GenericServlet#service(ServletRequest, ServletResponse) and >the corresponding methods in javax.servlet.http.HttpServlet. > >Am I missing something here? What will guarantee that if Thread A is used >to init(ServletConfig) then Thread B calling getServletConfig() will see >the correct state of the field config (Java "happens-before"), and not e.g. >null? > >I am asking this because I have seen some legacy code, where a servlet >stored something into a field inside the init() method, which was then used >from within a javax.servlet.http.HttpServlet#doGet or >javax.servlet.http.HttpServlet#doPost method, without synchronization of >any kind like this: > >public class FoobarServlet extends HttpServlet { > > private FoobarService foobarService; > > @Override > public void init() throws ServletException { >this.foobarService = // ... acquire foobarService > } > protected void doGet(HttpServletRequest request, HttpServletResponse >response) throws ServletException, IOException { > List foobars = this.foobarService.getFoobars(); // read the >field WITHOUT synchronization > // ... > } > // ... >Is this approach (having no synchronization, locking or the field being >volatile) correct? I assumed it is not, seeing something like that in the >servlet API is quite confusing. > > >What do you think? > >Thanks, >Peter A Servlet will process requests only if it is fully initialized, i.e. init has been executed. The init method gets called only once and the servlet config won't change afterwards. I don't think there is need for synchronization. The same is probably valid for your own objects. Problems arise when individual requests change the state of these objects. Andy - To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org
Thread-safety of javax.servlet.Servlet#getServletConfig()
Hi All, I am wondering why calling javax.servlet.Servlet#getServletConfig() is thread safe: if you check the implementation in javax.servlet.GenericServlet from servlet API 3.0.1, you see the following: package javax.servlet; // lines omitted public abstract class GenericServlet implements Servlet, ServletConfig, java.io.Serializable { // lines omitted private transient ServletConfig config; // lines omitted public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } // lines omitted public ServletConfig getServletConfig() { return config; } // lines omitted } The field config is written in init(ServletConfig) without any synchronization, locking or config being volatile, while getServletConfig() could be called anytime from any later worker thread of the servlet container. I took a quick look into Tomcat/Catalina code base, however I see no indication of the servlet container performing any magic, which would guarantee thread safe access to field config through getServletConfig() from e.g. javax.servlet.GenericServlet#service(ServletRequest, ServletResponse) and the corresponding methods in javax.servlet.http.HttpServlet. Am I missing something here? What will guarantee that if Thread A is used to init(ServletConfig) then Thread B calling getServletConfig() will see the correct state of the field config (Java "happens-before"), and not e.g. null? I am asking this because I have seen some legacy code, where a servlet stored something into a field inside the init() method, which was then used from within a javax.servlet.http.HttpServlet#doGet or javax.servlet.http.HttpServlet#doPost method, without synchronization of any kind like this: public class FoobarServlet extends HttpServlet { private FoobarService foobarService; @Override public void init() throws ServletException { this.foobarService = // ... acquire foobarService } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List foobars = this.foobarService.getFoobars(); // read the field WITHOUT synchronization // ... } // ... Is this approach (having no synchronization, locking or the field being volatile) correct? I assumed it is not, seeing something like that in the servlet API is quite confusing. What do you think? Thanks, Peter