Java servlet and class with static initializer - java

I have a class which my servlet instantiates on each page request. That class has a static initializer, a static variable and the rest contains non-static public or private members, a constructor, etc.
Is this safe? I don't want the static initializer to be called but only once throughout the lifecycle of my servlet.
Using Tomcat. I understand that each time the class is loaded by a Class Loader, the static initializer will be called. Should this be a concern for me (using tomcat) based on my requirement?

There are no problems, except if you modify the static variable since it'll be shared by all the requests. You will have concurrency issues if you do any decisions based on that variable.
Static initialization happens at class loading time, so that'll only happen once.

unless you maintain state in this second class you should not be worried about number of instantiations. A static initializer would serve just fine. There is no hard way to enforce "only once throughout the lifetime" behavior.
There are easy and plenty of hacks to turn your singleton to a multiton so I wouldnt worry about it. If you are a die hard fanatic for it use Spring or Pico else just dont maintain state in the second class only do stateless conversations with your servlet and all will be well.

Related

Handling static variables in Application class in android

I have an application with 100+ static variables and methods in its Application class will it affect the performance of the app? if so how to handle it?
As I see, your only question is if using static methods and variables inside your application class is wrong or not. As far as I know, it will not affect your application performance or anything else, but putting them inside application class is a wrong design. It's like you put all your code inside one single method and it will not be good.
So, I suggest you to put your static methods inside a Helper class and since they don't need to be instantiated, they need to be static, not a singleton. Also for your variables, for example for your Strings, I suggest to create another class and put them into it so your application maintenance be possible.

Static, Singleton or instance?

I'm a bit confused about my new class type I've written.
My class would be used to serve question and options pulled from database for about four thousands concurrent users. (Because exam will start at the same time for all)
Now what class type should I use for making it work faster.
Would it be good if I make it static?
public static List<Questions> getQuestions(String qType){
List<Questions> objListExamsExt = new ArrayList<Questions>();
....
....
....
while (cursor.next()) {
Questions objExamQuestion = new Questions();
objExamQuestion.setQuestion_id(cursor.getString("question_id"));
....
....
....
objListExamsExt.add(objExamQuestion);
}
return objListExamsExt;
}
A case where a static class might be a good idea is when you want to collect related pieces of functionality, but you don't need to have any internal state in any object.
Normally you can create a static Utils class containing a whole bunch of related functions that are accessed outside the context of any specific object instance
A singleton allows a class for which there is just one, persistent instance across the lifetime of an application.A singleton class might be useful if you have some kind of shared resource, such as a database, an in-memory cache, or maybe some specialized piece of hardware like a robotic arm. Many parts of your program might want to use this resource and you might want to have all access to the resource go through a single point. A singleton isn't always the only way to handle these situations, but it's one of the few places I think a singleton might be a good choice.
In your case if getQuestions() is used in multiple places in your application then you can group it together inside a static Utils Class.

Create a class that is accessible to the whole application

In android there is a mechanism of ensuring that only one instance of a class is available to the whole application. This can be done by deriving that class from Application.
Can some thing similar be done in servlets? I want to initialize a class when the application is deployed. This class should have only one instance. So that what all the servlets can access it.
I came to know that you can store your data in the servlet context's hashmap. But I don't want to do that. I want to write my own class with its functions. How should this be done?
I think what you're after is simply a singleton.
This is best implemented by defining an enum with a single instance. (Note that enums allow you to have member functions just as classes.)
public enum YourSingleton {
INSTANCE;
// Your methods...
}
and then you access it as
YourSingleton.INSTANCE
So, create whatever class you want with its own functions or whatever you like, and put that in the ServletContext at startup. You can use a ServletContextListener to initialize and remove it. What's limiting about that?
Use singleton pattern so the first call to instance method (say YourClass.getInstance()) will create the instance and it will be reused across the application.

Loading constants at program launch

When I define static or constant members, for example:
public static final Font BIG_FONT = new Font("", Font.BOLD, 18);
I noticed that they only load when I first use them, which either results in freezes during the runtime or forces me to somehow preload them by forcefully 'using' the constant at the program launch.
Aren't static members of such type supposed to be loaded at program launch rather than wait to be loaded on first use? How can I make sure they are preloaded?
Thanks in advance.
In Java, statics are initialized when the class is first used, not when the static member itself is first used. You can force "pre-loading" by using any other member of that class, not necessarily the static field itself.
No.
Static initializers are executed when the class is first loaded.
The Java Runtime does not go out of its way to initialize every class as soon as you start the program; that would be a very bad idea.
what you can do is create a static loader method and include it in during your initialization method.
As others have mentioned statics are initialized when the class is first loaded.
One way to force this would be to either create an instance of the class in question or create (program) a distinct (new) class containing the statics and instantiate it as soon as the program starts. However, I'm not sure I would recommend either practice as they tie up memory that might be better used elsewhere.

Stateless session bean with instance variables

I have a stateless session bean that contains one public method, several private methods, and some instance level variables. Below is a pseudo code example.
private int instanceLevelVar
public void methodA(int x) {
this.instanceLevelVar = x;
methodB();
}
private void methodB() {
System.out.println(instanceLevelVar);
}
What I'm seeing is that methodB is printing values that weren't passed into MethodA. As best I can tell it's printing values from other instances of the same bean. What would cause this?
I should point out the code works as expected 99.9% of the time. However, the .01% is causing some serious issues / concerns for me.
I understand that if I had different public methods then I might not get the same bean back between calls, which would result in this behavior. However, in this case the only call is to the single public method. Will the container (Glassfish in this case) still swap the beans out between private method calls?
(edit) I renamed "class level" to "instance level" as this was causing some confusion.
When I read What is a Session Bean? section of the J2EE 1.4 tutorial:
Stateless Session Beans
A stateless session bean does not maintain a conversational state for a particular client. When a client invokes the method of a stateless bean, the bean's instance variables may contain a state, but only for the duration of the invocation. When the method is finished, the state is no longer retained. Except during method invocation, all instances of a stateless bean are equivalent, allowing the EJB container to assign an instance to any client.
In your case, the call to methodB() from methodA() will be on the same instance and is equivalent to this.methodB(). I'm thus tend to say that methodB() can't output something else that the value that what was passed to methodA().
This is confirmed by the first sentence in section 7.11.8 in the EJB 2.0 spec: "The container must ensure that only one thread can be executing an instance at any time". This means you cannot come to a situation where data (in your instance variables) from different clients (threads) will be mixed. You are ensured unique access to the instance variables until methodA() has returned!
That said, I'm not saying that you don't have a problem somewhere. But I don't think that your pseudo code is equivalent.
(EDIT: Having read some comments to the OP's question, there is now clearly a doubt about the pseudo code and semantic used. I'm clarifying possible consequences below.)
As underlined by Rocket Surgeon, what do you mean exactly by class variable? Do you really mean class variable as opposed to instance variable? If yes, the pseudo code doesn't reflect it but this will clearly lead to unpredictable behavior. Actually, from section 24.1.2 (and first point) in the EJB 2.0 spec, it is clear that you are not allowed to write data to a class variable (although you can do it). There must be a good reason for this :)
I would just not bother using instance variable in stateless session bean at all. Regardless of what the cause of the issue you have encountered, it's probably not something you would want to do anyway. Just try using local variables throughout or define instance variables in helper classes you are calling from the stateless session bean business methods.
The likely cause of the issue is that the container is using the same object in two requests (therefore two threads) at the same time. So the first thread gets to line that calls methodB and then the next thread gets to the code which calls methodB and then the first thread executes the call to methodB, causing the issue. That would explain the behavior, at any rate. It doesn't seem to fit the spec, but that could just be a bug.
In general, even if permitted, keeping state in the bean is not a great idea. It leads to confusion code and can easily lead to bugs where you forget to start over with your all your state on every method call.
It would be much better to just pass those objects around between methods, and that would avoid all issues.
Probably your are not properly reinitializing the instance variable.
Instance variables
In general we should not keep state in our stateless session bean. Objects referenced by instance variables, if not nulled after their use, are kept alive until the end of the request and even longer if our EJB container pools the session beans to reused. In the latter case we need to make sure that instance variable get properly reinitialized during a subsequent request. Therefore the use of instance variables may lead to the following issues:
during the same request, instance variable shared between different methods can easily lead to bugs where we forget to start over with the correct state on every method call
in case EJB container pools session beans and we may our code fails to properly reinitialize the instance variables we may reuse stale state set in a previous request
instance variables have instance scope which could introduce memory leak problems where space in the Heap is used to keep objects that are not (or should be not) used anymore.
Class variables
As for instance variables, class variables should not be used to keep shared state in Stateless session bean. This does not mean we should not use the static keyword but that we should use it with caution (e.g. define immutable constants, some static factory class, etc.)
Because this is very strange I performed a quick test with Netbeans and my local Glassfish 2.1.
Create a new project using Samples->Java EE->Servlet Stateless. This creates an enterprise project with a simple stateless bean and a servlet that uses it.
I modified the stateless bean to look like this, as close to your example as possible I think.
#Stateless
public class StatelessSessionBean implements StatelessSession {
String clName;
private void testNa() {
System.out.println(clName);
}
public String sayHello(String name) {
this.clName = name;
testNa();
return "Testcase";
}
}
This works as it should. I don't know what editor you're using, but if it's Netbeans it may be interesting to run it yourself.
It all hinges on what you mean by "class level variable". A class variable must have the static modifier. If clName doesn't, then each instance of your stateless session bean has its own copy of clName. Your Java EE server probably created a pool of two or more instances of the stateless session bean, and each of your calls to testNa() and sayHello() gets sent to an arbitrary instance.
I stumbled upon this question when I experienced the same problem. In my case, the private method actually sets the instance variable. What I have noticed is that sometimes the instance variable was already set, obviously from a previous request.
#Stateless
public class MyBean {
String someString;
public void doSomething() {
internalDoSomething();
}
private void internalDoSomething() {
if (someString != null) {
System.out.println("oops, someString already contained old data");
}
this.someString = "foo";
}
}
I guess it makes sense. When the container re-uses a cached instance, how should it know how to clear the variables...
To me, this is inline with and confirms both Pascal's reference to the EJB spec ("instance variables are supported") and Rocket Surgeon's recommendation ("don't do it, use local variables instead").
The problem with using Instance variables in stateless Beans.
According to the JEE specification that same stateless EJB instance might be shared with another client as well. The thumb rule is not to create instance variables in Stateless EJBs.
It might be possible the two clients accessing the application simultaneously are provided same EJB instance which would create problems since there is data inconsistency.
So it is not a good idea to use instance variables in stateless EJB beans .
I had similar issue because I used global static class variable in my ejb class and when I had concurrent stateless EJB running, variable was overwritten by other instances.
Static class fields are shared among all instances of a particular class, but only within a single Java Virtual Machine (JVM). Updating a static class field implies an intent to share the field's value among all instances of the class.
Hope help someone else :)

Categories

Resources