Bug 51445 - Tomcat 7 SingleThreadModel Problem
Summary: Tomcat 7 SingleThreadModel Problem
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 7.0.12
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-28 10:33 UTC by Mali
Modified: 2011-06-30 20:07 UTC (History)
0 users



Attachments
init every servlet if it is a SingleThreadMode servlet (1.42 KB, patch)
2011-06-30 10:39 UTC, Felix Schumacher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mali 2011-06-28 10:33:26 UTC
I have noticed that in tomcat 7 if we implement SingleThreadModel and initialize some variables into init(ServletConfig config) method, in that case values initialized in init(ServletConfig config) not reflected into service block.

For Example : Following code will print "0".

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.SingleThreadModel;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class test extends HttpServlet implements SingleThreadModel
{

    int i = 0;

    @Override
    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
        i = 10;
    }
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try
        {
            out.println(i);
        }
        finally
        {
            out.close();
        }
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        processRequest(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        processRequest(request, response);
    }
    @Override
    public String getServletInfo()
    {
        return "Short description";
    }
}
Comment 1 Mark Thomas 2011-06-28 16:35:07 UTC
Reducing severity. SingleThreadModel has been deprecated for as long as I can remember so this is not critical.
Comment 2 Mark Thomas 2011-06-28 18:01:25 UTC
This works for me with the latest 7.0.x code.

I've added to test case that checks this just to be on the safe side.
Comment 3 Mali 2011-06-29 05:18:03 UTC
(In reply to comment #2)
> This works for me with the latest 7.0.x code.
> 
> I've added to test case that checks this just to be on the safe side.

(In reply to comment #2)
> This works for me with the latest 7.0.x code.
> 
> I've added to test case that checks this just to be on the safe side.


I think tomcat 7.0.16 has same problem. SingleThreadModel model is obviously deprecated but we have some old servlets in which it is used, and we can not change that code by some reasons.
Comment 4 Christopher Schultz 2011-06-29 14:04:44 UTC
Please provide a test case that fails on a current version of Tomcat downloaded directly from the Apache site.

Mark's analysis is that the test case you provided works in his environment. It's up to you to prove that it doesn't work by reproducing the circumstances.
Comment 5 Mali 2011-06-30 05:50:57 UTC
What I hava to provide exactly in test case (as I am new here). All I can provide is I have tested same in apache-tomcat-7.0.12, apache-tomcat-7.0.16 with JDK jdk1.6.0_13, jdk1.6.0_26 in PC Linux OS.

The servlet I have provided should print 10 rather than 0.
Comment 6 Felix Schumacher 2011-06-30 08:14:57 UTC
I think Mali is right and his test case is valid.

If you try the servlet in a freshly downloaded tomcat you will get "0" as result. If you spice up his testcase a little bit, you will see, that one instance of the servlet will get initialized and another one will be used for the request. That is what SingleThreadModel is for.

I think the logic changed from 6.0 to 7.0 that there is only one (StandardWrapper-wide) instance variable which tells tomcat whether the servlet is initialized or not. This initialization has moved to allocate. That means, that one servlet gets initialized and every other newly created instance for the pool (instancePool) will not be initialized.

In tomcat6.0 I believe the newly created servlets were initialized in loadServlet.

Marks testcase could be testing the wrong thing by providing an instance for a SingleThreadModel-servlet on its own.

Could that be?
Comment 7 Felix Schumacher 2011-06-30 10:39:50 UTC
Created attachment 27230 [details]
init every servlet if it is a SingleThreadMode servlet
Comment 8 Mark Thomas 2011-06-30 11:58:40 UTC
Further investigation shows that o.a.catalina.startup.Tomcat (that is the basis for most of the unit tests) didn't handle SingleThreadModel servlets. I have fixed that and improved the unit tests in that area.

Since the handling for SingleThreadModel servlets is slightly different, I need to put together a different unit test for this issue. Working on that now.
Comment 9 Mark Thomas 2011-06-30 12:17:16 UTC
Unit test now reproduce this.

The bug has been fixed in 7.0.x and the fix will be included in 7.0.17 onwards.
Comment 10 Mark Thomas 2011-06-30 12:17:35 UTC
As an aside, I used a variation of Felix's patch.
Comment 11 Mali 2011-06-30 12:59:43 UTC
May I know how to fix this bug in tomcat 7.0.16 or I have to wait for tomcat 7.0.17 ! May I know the tentative date for tomcat 7.0.17 release !
Comment 12 Christopher Schultz 2011-06-30 20:07:09 UTC
(In reply to comment #11)
> May I know how to fix this bug in tomcat 7.0.16 or I have to wait for tomcat
> 7.0.17 ! May I know the tentative date for tomcat 7.0.17 release !

If you are comfortable using svn to get diffs for the files involved, patching them, and re-building Tomcat, you can look at Mark's patch here: http://svn.apache.org/viewvc?view=revision&revision=1141502

If you'd rather not patch but don't mind building and living on the edge, you can get svn trunk and use that.

Otherwise, you'll have to wait for 7.0.17. Mark is the release manager for 7.0.x and has tried to keep to a roughly-monthly schedule for releasing patch levels for 7.0.x, so I would expect one in the next 20 days or so (if the release gets enough votes). If you have any further questions about releases, please ask on the users list.