Books
in black and white
Main menu
Share a book About us Home
Books
Biology Business Chemistry Computers Culture Economics Fiction Games Guide History Management Mathematical Medicine Mental Fitnes Physics Psychology Scince Sport Technics
Ads

More Java Pitfalls Share Reactor - Daconta M,C.

Daconta M,C. More Java Pitfalls Share Reactor - Wiley publishing, 2003. - 476 p.
ISBN: 0-471-23751-5
Download (direct link): morejavapitfallssharereactor2003.pdf
Previous << 1 .. 94 95 96 97 98 99 < 100 > 101 102 103 104 105 106 .. 166 >> Next

066 * and writes the data to the browser screen.
067 */
068 private void putInUserData() throws IOException
069 {
070
071 BufferedReader br = null;
072 String fn = m_useridparam + ".html";
073 String htmlfile =
074 getServletContext().getRealPath(fn);
075
076 System.out.println("debug: Trying to open "
077 + htmlfile);
078
079 File htmlSnippetFile = new File(htmlfile);
080 try
081 {
082 String line;
083
084 //Check to see if it exists first
085 if (!htmlSnippetFile.exists())
086 {
087 m_out.println("File " + fn + "not found!");
088 return;
089 }
090
091 br = new BufferedReader(new FileReader(htmlfile));
092
093 /*
094 * Now, let's read it..
095 * Since finding the bad behavior in this pitfall
096 * revolves around timing, we will only read 2
097 * characters at a time so that the bad behavior
098 * can be easily seen.
Listing 31.1 (continued)
272 Item 31
099 */
100
101 char[] buffer = new char[2];
102 int count = 0;
103 do
104 {
105 m_out.write(buffer, 0, count);
106 m_out.flush();
107 count = br.read(buffer, 0, buffer.length);
108 }
109 while (count != -1);
110 }
111 catch (Exception e)
112 {
113 m_out.println(
114 "Error in reading file!!"
115 );
116 e.printStackTrace(System.err);
117 }
118 finally
119 {
120 if (br != null)
121 br.close();
122 }
123
124 }
125 }
126
127
Listing 31.1 (continued)
Looking at the code in lines 17 and 18 of Listing 31.1, we have two instance variables. The PrintWriter m_out and the String m_useridparam are assigned in the doGet() method on lines 33 and 34. After the doGetO method initializes these variables, the putInUserData() method is called to read the user-specific HTML files and print these out to the browser screen. Tested alone, a screen capture of the browser window looks fine, as shown in Figure 31.1.
However, during load testing, multiple users log in and many see the screen shown in Figure 31.2. The result seems like a combination of many screens and looks like nonsense. What happened?
Because instance variables are set in the doGet() method in Listing 31.1 and are used later in the servlet in the putInUserData() method, the servlet is not thread-safe. Because many users access the servlet at the same time, and because the instance variables are written to and referenced by multiple areas of the servlet, the values of the m_out variable and the m_useridparams variables have the potential to be clobbered!
Instance Variables in Servlets 273
Figure 31.1 Our example with one concurrent user.
For example, when one user runs his servlet, the servlet could be setting the m_out variable for his session while another user's session is writing with the m_out variable.
Figure 31.3 shows us a time line of how this strange behavior occurred in our example from Listing 31.1. In the time line, we have two fictitious users of the system, Alice and Bob. At time t0, the servlet engine first instantiates the servlet, where the instance variables are declared in lines 17 and 18 of Listing 31.1. At time t1, the servlet engine calls the servlet's init() method. At time t2, Alice loads the servlet, which calls the servlet's doGet() method. At time t3, the instance variables m_out and m_useridparam are set just for Alice. At the same time, Bob loads the servlet, which calls the servlet's doGet() method. At time t4, Alice's servlet gets to the point where the putInUserData() method is called, which loads her information and begins printing to the PrintWriter variable, m_out. At the same time, Bob's servlet is in the execution of doGet(), where the instance variables m_out and m_useridparam are set.
Time t5 in Figure 31.3 is where everything seems to go nuts. Since Bob reset the servlet's instance variable m_out, Alice continues to print her information, but it goes to Bob's browser! When Bob also begins printing to m_out, he sees a combination of his information and Alice's information. The result is something like the screen shot that we showed in Figure 31.2.
274 Item 31
^ Online Technob.ibble Libi.ny Microsoft Internet Exploiei -IEQ Edit yiew Favorites loots Help J*-" J i il yPsMKh Fa*es Media .0 f i ' ^ ^ 'i
Address |(^j http://bcahost:80e0/reab/BadTchnobabbHjbraryServlet?userjd-ksrnith |3 Lin^
Online Technobiibble Library A
-TvrwOuThOPO Et^' we 2?err3>Trfl6t5grheor.20MO"TR-rfo;>mdoou&nrmnlc~gOb}b55/GEuty p.e:shPNE&n



Lb5p,p.3iLrp,4.//,4T?cAii.4ww4. ^L*i/AW.. 11 li w30_ ^ii*h Icp.lxtorCSOfo. l^iODIworol. liniL











>TrmR,4pabphe?-gi<tigxenfa66e-fodoonab66mwblerm00rafled s-: >S E) mPAerrc vaEvDE>mT3acnlmtIHli'd /AerTOtaat at< 0&n>&tr; , sp>fibibER tcspnbp:_Datsp&nOT\6bCOiobs:fibibbTOn/p;nbspM'R :xmsp:fifc&n ^*1 fifcpit



t&nnb Bspp-.OReKbssp-.&ftnt p:-.&DEnbbsR-{ nb&nspp: ?pb5DO:ft&nTTp::&FOnbb5ftnnbKFOMgpp:-Wb?:




C*one Local intranet
Figure 31.2 Chaos: Our example with concurrent users.
In fact, we chose the example so that this strange behavior could be shown easily. Each servlet client (or user Web browser) will need its own PrintWriter, and because each servlet is a thread in the server's virtual machine, m_out can be trampled on whenever a new user loads the servlet, producing scary output. In practice, these types of errors can be difficult to detect until load testing, because errors occur with timing when multiple clients hit the server at once. In fact, we couldn't see any tangible ramifications of assigning the variable m_useridparam, because the timing has to be right to actually see the effects. We have seen one situation where a customer's requirements were to provide sensitive and confidential data to its users. The software developers used instance variables in their servlets for printing information gathered from each user's database connection. When the developers were testing it alone, the system seemed to work fine. When the system went in for load testing with several different users, the testers saw the other users' confidential data.
Previous << 1 .. 94 95 96 97 98 99 < 100 > 101 102 103 104 105 106 .. 166 >> Next