views:

80

answers:

1

Hi,

I was debugging an error I was getting with a java servlet. I was assigning a value to a Double in the class, however occasionally when I ran the servlet I was getting a random number as the value. Not sure if this has to do with using the wrapper versus primitive?

Here is a snippet of code:


public class MyClass extends HttpServlet {

      private Double MinCost = 10000000.0;

      public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException { 

// rest of code here ----


When I run the servlet, I sometimes get the value of MinCost to be some other number, and sometimes it is correct.

I have changed the code to just declare the variable MinCost but not assign it a value, and assign it a value later on in my doPost method.

Any explanation as to why this happens?

Thanks

+1  A: 

My guess is that this is happening because of previous requests. Don't forget that the same servlet instance is used for multiple requests - are you expecting the value to be 10000000.0 at the start of each request? That's not how servlets work. If you want state within an object - and new state at the start of each request - you'll have to put that state into a separate class, and create an instance of the class in doGet/doPost/service etc.

Jon Skeet
Yes, you are right - I am getting the 10000000.0 value at the start of each request. Didn't realize that it is the same servlet instance. Thanks!
Upvoting and accepting the answer is a better way to say thanks. He doesn't really need that, though, after looking at his rep ;).
Adeel Ansari
The fix isn't to set the value at the start of each request, btw - it's to move the state out of the servlet. Otherwise if you have two concurrent requests they'll stomp on each other's state.
Jon Skeet
Very good point. That was my initial reaction however I see what you mean about concurrent requests...
So, this may be a dumb question, but what if I have multiple methods in the servlet, aside from doPost, and I want to have a global variable that all methods can access? Or do I just have to pass the variable as an argument to all the various methods?
or, I guess what you are suggesting is to create a new class that holds these variables, create an instance and then pass that object to the specific methods?
What are you trying to achieve. May be using application context is a better idea. But again not sure. Tell us the story.
Adeel Ansari
Creating a web application to do route optimization and using Google Appengine. The servlet receives the IDs for a set of locations, the servlet pulls up the locations from the datastore and then runs an optimization. The doPost method calls other methods that I have defined in the servlet class to do the various tasks required in the optimization however all of the methods require access to some global info (e.g. number of total locations to optimize). I originally declared "Double MinCost = 10000000.0" where I did because I wanted it to be global. But, skeet pointed out the issues.
That global info should be immutable, I suppose. Otherwise, if you need to share that then everyone can change it, and thats unacceptable in your case, I believe.
Adeel Ansari
Mutable "global variables" are generally a bad idea in web applications. What happens if the web app is restarted? Do you really want it to be global across *all* users? There's a big difference between information which doesn't change (or which changes only on the basis of time, or other external factors) and information which is changed by user requests. If you want to actually *store* information it should be in a database, or files etc.
Jon Skeet
I probably misused the term "global variable". The main issue was I was thinking of the servlet in the paradigm of a unique instance for each request, which is wrong as Skeet pointed out. My plan is to create an external class, instantiate it within the doPost request (and use setters to set variables sent in the request) and pass that object between methods in the servlet class. Does that make sense?
@unknown: Yes, that's fine.
Jon Skeet