[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 414
  • Last Modified:

Concurrent session problem in servlets

Hi Experts,

I have a simple servlet called UserServlet. This servlet takes some parameters like username, firstname, lastname etc from the session and persists these values in the DB by calling the DAO.

Everything works fine when a single instance is running, but when 4-5 users are using the servlet simultaneously Java.Lang.NulPointerException is thrown intermittently. The relevant code is

/**      
*      Class: UserServlet
*      Description: Servlet to handle the user registration step two.
*      @author: MSYED
*
*/

package com.blueprintny.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;

import org.apache.log4j.Logger;
 
import com.blueprintny.PortalFunctions;
import com.blueprintny.vo.*;
import com.blueprintny.dao.*;
import com.blueprintny.dao.jdbc.*;
 


/**      
*      Class: UserServlet
*      Description: Servlet to handle the user registration step two.
*      @author: MSYED
*
*/
public class UserServlet extends HttpServlet
{

      private static Logger log = Logger.getLogger(UserServlet.class);

      public static final String FormPassword = "_form_password_";
      public static final String FormConfirmPassword = "_form_confirm_password_";

      private DataSource RoCDs;
      private DaoFactory daoFactory;      
            
      public void init(ServletConfig conf) throws ServletException
      {
            super.init(conf);
            
            // Grab a reference to the data source so we can keep using it.
            try
            {
                  Context ctx = new InitialContext();
                  this.RoCDs = (DataSource) ctx.lookup("RoCDS");
                  this.daoFactory = new JdbcDaoFactory(RoCDs);
            }
            catch (NamingException e)
            {
                  throw new ServletException(e);
            }
      }


      /**
      * doPost()
      * @param HttpServletRequest
      * @param HttpServletResponse
      *
      */
      public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
      {
            log.debug("LoginServlet");
            log.info("Inside do post of user servlet");
            

            try
            {
                  log.info("Inside try of user servlet");
                  // Is it required. String action = request.getParameter(FormAction);
                  String fname = request.getSession().getAttribute("userfirstname").toString();
                  String lname = request.getSession().getAttribute("userlastname").toString();
                  String birthMonth = request.getSession().getAttribute("userbirthmonth").toString();
                  String birthDay = request.getSession().getAttribute("userbirthday").toString();
                  String birthYear = request.getSession().getAttribute("userbirthyear").toString();
                  //String email = request.getParameter(FormEmail);
                  String email = request.getSession().getAttribute("useremail").toString();
                  String password = request.getParameter(FormPassword);
                  String birthDate = birthMonth.trim()+"/"+birthDay.trim()+"/"+birthYear.trim();
                  long userpklong = 0;
                  // Call the Value Object
                  // Set the users data in the user value object and then persist in the database by calling the dao
                  
                  //Get the VO instance
                  UserValueObject userVO = new UserValueObject( );
                  
                  // Set the parameters in the value object
                  userVO.setUserName(email);
                  userVO.setFirstName(fname);
                  userVO.setLastName(lname);
                  userVO.setPassword(password);
                  userVO.setBirthDate(birthDate);
                  
                  log.info("Before calling the DAO");
                  // Send the user VO to the dao for insertion
                  UserDao userDAO = daoFactory.getUserDao();
                  userpklong = userDAO.create(userVO);

                  // Converting userPK from long to String
                  Long userpklongObj = new Long(userpklong);  
                  String userpk = userpklongObj.toString();
                  request.getSession().setAttribute("userpk",userpk);

                  // Code to Populate the events table.
                  String event = new String("none");
                  
                  if(request.getSession().getAttribute("event") != null)
                  {
                        log.info("Got the event");
                        event = request.getSession().getAttribute("event").toString();  
                  }
                    
                  
                  // Call the DAO method to execute the stored procedure if event is not none.
                  if (!(event == "none"))
                  {
                        userDAO.registrationEvent( userpklong, event );
                  }
                  // End of registration event code

                  

            }
            catch (Exception e)
            {
                  log.debug("Exception");
                  log.error ( e.getMessage ( ) ) ;
                  e.printStackTrace();
            }
            finally
            {
                  // Clean the session
                  request.getSession().removeAttribute("event");
                  request.getSession().removeAttribute("userfirstname");
                  request.getSession().removeAttribute("userlastname");
                  request.getSession().removeAttribute("userbirthmonth");
                  request.getSession().removeAttribute("userbirthday");
                  request.getSession().removeAttribute("userbirthyear");
                  request.getSession().removeAttribute("useremail");
            }
            
            // Once registered send the user to home page. If error then send back with error message
            // Ex: Error cold be like Email exists
            RequestDispatcher dispatcher = getServletContext().getRequestDispatcher ( "/couponRegistration.jsp" ) ;
          dispatcher.forward(request, response);
    }
      
}

The specific line where the exception is thrown is : String fname = request.getSession().getAttribute("userfirstname").toString();

Going forward we will have many concurernt users for this application so is there something significantly wrong in this code.

Looking forward to your comments.

Best Regards
0
M_SYED
Asked:
M_SYED
  • 5
  • 2
1 Solution
 
Mayank SAssociate Director - Product EngineeringCommented:
>> String fname = request.getSession().getAttribute("userfirstname").toString();

Where do you store this in the session? There should be a setAttribute () for this. Is it done in a JSP or some other servlet?
0
 
Mayank SAssociate Director - Product EngineeringCommented:
getSession () will check if there is an existing session. If not, it will create a new session. I guess the case when it throws the exception is when there is no session. So it has to create a new session, and in that session, the "userfirstname" attribute will not be there. So getAttribute ( "userfirstname" ) on that new session will return a null and toString () on it will throw a NullPointerException. So when you use getAttribute (), you must ensure the session has been created first and the attribute has been set. Better to do null-value checks too.
0
 
M_SYEDAuthor Commented:
Hi All,

Thanks for the quick comments.

mayankeagle: The attributes are set uin another servlet which is invoking this servlet.

I understand the part the fact that NullPointer will be thrown when the required attribute does not exist but the problem only comes when multiple concurrent users are using the system, that is the point that concerns me most.

Best Regards
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Mayank SAssociate Director - Product EngineeringCommented:
Add some debug statements before: >> String fname = request.getSession().getAttribute("userfirstname").toString();

Session session = request.getSession ( false ) ;
log.debug ( "SESSION: " + session ) ;

If it prints null then it means the session was not set in the other servlet due to some reason (maybe it was in a block of code which did not run due to some conditional branching or exception).
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> but the problem only comes when multiple concurrent users are using the system

What is the order in which the servlets are invoked? Also, can you show some part of the code where the attributes are set in the other servlet?
0
 
M_SYEDAuthor Commented:
Sure I can show you the code.

Here is the servlet code where I am setting the session attributes.

      public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
      {
            // Is it required. String action = request.getParameter(FormAction);
            String fname = request.getParameter(FormFirstName);
          String lname = request.getParameter(FormLastName);
            String birthMonth = request.getParameter(FormBirthMonth);
            String birthDay = request.getParameter(FormBirthDay);
            String birthYear = request.getParameter(FormBirthYear);
            String email = request.getParameter(FormEmail);
            String event = new String("none");
 
            if ((request.getParameter("CheckRoC")!= null) && (request.getParameter("CheckJJ")!= null) )
            {
                  event = "BOTH";
            }
            else if(request.getParameter("CheckRoC")!= null)
            {
                  event = "ROC";
            }
            else if(request.getParameter("CheckJJ")!= null)
            {
                  event = "JJ";
            }
            
            request.getSession().setAttribute("event",event);
             
            //String password = request.getParameter(FormPass1);
            //int primaryKey = 0;
            boolean emailExists = false ;

            try
            {
                  
                  // Need to check if the email is in the sstem db, if so need to redirect the user to
                  // the reg step one .jsp so that user can enter a different email.  
                  UserDao userDAO = daoFactory.getUserDao();
                  int i = userDAO.checkEmailExists(email);
                  
                  if(i==0)
                  {
                        emailExists = false;
                  }
                  else
                  {
                        emailExists = true;
                  }
            }
            catch (Exception e)
            {
                  log.debug("Exception");
                  log.error ( e.getMessage ( ) ) ;
                  e.printStackTrace();
            }  
            String url = null;
            if(emailExists)
            {
                  // Return user to RegStepOne.jsp
                  url = "/registerOne.jsp" ;
                  request.setAttribute("emailError","Email exists in system, please select a different email");
            }
            else
            {
                  // Send user to reg step two
                  url = "/registerTwo.jsp" ;
                  request.getSession().setAttribute("useremail",email);
                  request.getSession().setAttribute("userfirstname",fname);
                  request.getSession().setAttribute("userlastname",lname);
                  request.getSession().setAttribute("userbirthmonth",birthMonth);
                  request.getSession().setAttribute("userbirthday",birthDay);
                  request.getSession().setAttribute("userbirthyear",birthYear);
            }
            //Once registered send the user to home page. If error then send back with error message Ex: Error cold be like Email exists
            RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( url );
          dispatcher.forward(request, response);
    }

Please provide your valuable inputs because we foresee 100's of concurrent users for this application.

Best Regards
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> request.getSession().setAttribute("userfirstname",fname);

Add debug statements there to see if that line is executed or not. Also add the debug statements which I proposed earlier in the other servlet. Then see whether this setAttribute () is actually getting executed everytime or not.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now