Stateless session bean with instance variables - java

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 :)

Related

Spring Singleton means no data sharing at class level?

I am confused.
Spring's default bean scope is Singleton. That means that once you define a bean of your class, every time a new "message" comes in, it will be processed by the same instance of that class.
But that also means that you cannot have mutable instance variables in that singleton bean because the next call of a method of that class will see data from past calls..
Example:
Calculator is my bean (singleton)
public class Calculator {
private List<String> operations = new ArrayList<String>();
public void calculate(String op, double val) {
operations.add(op);
// do some calculations
}
public List<String> getAllOperations() {
return operations;
}
}
Here's the client (useCalc is invoked many times!):
public class CalculatorClient{
#Autowired
private Calculator calculator;
public void useCalc () {
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}
So let's say CalculatorClient useCalc gets called several times with different operations..
eventually operations in Calculator will contain all of the operations ever done on that calculator.
So the question is this:
Is this Spring's limitation - not being able to effectively share information between methods within a class? And if it is so, how to share that kind of information between methods?
I know there is the prototype bean scope. Is that the only solution in this case?
BTW, prototype is not a solution here because with prototype a new class will get instantiated with every call to calculator:
calculator.calculate("Add",100); // New
calculator.calculate("Div",100); // New
calculator.calculate("Diff",100); // New
And since Singleton is the default scope - aren't developers inadvertently introduce such bugs?
A common use case for singleton beans are to inject services into other objects.
Example, to provide an object a service to connect to the database, you "autowire" a database connection bean.
You don't want to create a new instance of the database every time, so singleton beans make sense.
Usually, the object itself that uses the autowire is a singleton as well (in a web app, the Controllers are also created just once, you don't want to create a controller for every request).
aren't developers inadvertently introduce such bugs?
Since the idea is to process several requests concurrently, all of those objects are usually already coded without having common state shared using instance variables.
This is not a "limitation", but rather a default for the most common use case.
I know there is the prototype bean scope. Is that the only solution in this case?
It sounds like a good "solution" to this, in that case a new bean will be created. Note that it would not make sense to autowire a prototype bean into a singleton since in that case there will only be once instance anyway.
Another possibility more commonly used is autowiring a singleton bean that acts like a factory, then ask that factory for a new object each time you need one.
The factory can be a singleton since you don't want more than one factory, but it would then return new objects in every call to its "create" method.
So in your example, you could do something like
#Autowired
private CalculatorFactory calcFactory;
public void useCalc () {
calculator = calcFactory.createCalculator();
calculator.calculate("Add",100);
calculator.calculate("Div",100);
calculator.calculate("Diff",100);
List<String> allOperations = calculator.getAllOperations();
// Do something..
}
}
There's a lot of conflation going on here. Let me try to unravel the premises.
The whole point of dependency injection is to make it so that you don't have multiple instances of a critical application service, which would lead to things getting out of sync or result in erratic behavior (e.g. multiple database connections, multiple access points to a JMS queue, multiple ways to query a database, etc).
It is not a mandate to make everything injectable.
If something is not inherently reusable, or you would not gain anything from registering it in the component scan, then there is no reason to make that thing either a bean or a component.
It is fairly reasonable to assume that beans shouldn't store state, but that doesn't mean that something else couldn't store that state on its behalf. For instance, you could put those operations into some other backing store as opposed to in-memory, and you'd still be able to keep the state of operations you've done.
The big thing that I'm seeing is that you've kind of implemented your Calculator class half-thinking that it was a bean, and half-thinking that it was newed up somewhere. By having that list in your class, you're subconsciously forcing yourself to hold onto the state in any instance created, which violated the inversion of control principle - you don't control the lifecycle of the object.
To get around this...you have a few options available.
Change how you're storing the state of your operations. Put it into a SQLite database or a file or somewhere that isn't dependent on an instance maintaining it.
Inject your own. You can create a bean that is of type List<String>, and require your Calculator to inject it when it's needed.
Don't create a bean. You can new this and Spring isn't really going to fuss at you. It'd make it harder to test, though.
The first two approaches abstract away the notion of storing the data from an operation and reading the data from the operations. You can either read from the injected operations bean or from the SQLite database or from the flat file to get the result of operations that you want.

How to make a state available to all beans in a "session"?

I have the following design. When a client makes a request to the server, the server creates a state that holds all sorts of info. There are various stateless and stateful beans which need to read and write to this state. Refer to this unprofessional diagram:
The ComputationCycle class is where the processing starts and works by phases. During each phase it calls upon other Manager classes (which behave like utility classes) to help in the computation (diagram shows only for 1 phase). The state is being read and written to both from the CC class and the managers, both are stateless.
State holds Employee, Department and Car classes (in some irrelevant data structure) which are stateful. These classes can also call the Manager classes. This is done by a simple #Inject Manager1. The same way CC uses managers.
My problem is how to access the stateful state (and its contained classes) from the stateless classes (and from the Car, Department and Employee classes too, although I think solving one will solve the other). I can't inject a stateful bean into a stateless bean. So after the client makes a request and the computation cycle starts, how do I access the state related to this request?
One solution is to pass the state to every method in the stateless classes, but this is really cumbersome and bloaty because all methods will have an "idiotic" State argument everywhere.
How can I make this design work the way I want it to?
I can't inject a stateful bean into a stateless bean.
You can absolutely inject dependencies this way.
If the stateful bean is #RequestScoped, any call into the stateless bean on that thread that hits a CDI injected contextual reference (iow proxy) will find its way to the right instance of the stateful bean.
As long as you use CDI, you don't need to trouble yourself with trying to stash things away in your own threadlocals.
Buyer beware, ThreadLocal will possibly do what you're wanting, along with a static accessor. However, this class is prone to causing memory leaks if you are not extremely careful to remove each entry at the end of the request. In addition, you seem to be using EJB; I assume they are all in the same JRE. I use ThreadLocal quite a bit in similar situations, and I've had no problems. I use SerletContextListener's to null the static reference to the ThreadLocal when the context shuts down, although that has been problematic on some older Web app servers, so I make sure the ThreadLocal exists before attempting to use it.
EJB can "talk" to each other across servers. It sounds local all your EJB are running in the same context.
Create a class that holds your state.
Extend ThreadLocal--you can do this anonymously--and override initialValue() to return a new instance of your class.
Create a utility class to hold the ThreadLocal as a static field. Don't make it final Create static fetch and remove methods that call ThreadLocal.get() and remove(). Create a static destroy() method that is called when your context shuts down--see ServletContextListener.

demystification required on chapter 1 of Spring in Practice book regarding singleton beans not maintaining state

I am learning Spring and have found the book Spring in Practice to be an awesome source. I don't understand Spring bean singleton scopes completely however. And what I read in the section of bean scopes has confused me a bit.
Here is a excerpt from that section:
As you request singleton beans from the container, Spring will create
instances and cache them if they haven’t been created; otherwise,
Spring will return already-existing instances from its cache.
Therefore, singleton beans in Spring often don’t maintain state
because they’re usually shared among multiple threads (such as in
servlet environments). For example, singleton services often have
references to singleton DAOs, and the DAOs might have references to
Hibernate SessionFactorys, which are threadsafe.
Now I don't know much about multithreading in Java so please pardon my ignorance. In the above excerpt where it says "Therefore, singleton beans in Spring often don’t maintain state because they’re usually shared among multiple threads"
1). What does this mean for domain objects? Can I have a domain object called User defined as a singleton scope in the spring context? What would happen?
2). I notice that mostly datasources and large configurations are usually in the spring xml file. I have a feeling my questions relating to state and beans defaulting to singletons is related to wiring only big parts of an application.
Can someone clarify this topic for me? An example would be really helpful.
Thank you in advance.
A Java class is a description of state and behavior. An instance of that class is a holder of state that can exhibit behavior. Therefore, this class
public class Foo {
private String bar;
public Foo(String bar) {this.bar = bar;}
public void print() {System.out.println(bar);}
public void setBar(String bar) {this.bar = bar;}
}
describes a data structure which has a String as state and print() and setBar(String) methods as behavior. If you create an instance
new Foo("the state");
You now have an actual data structure that holds the String data (or state) "the state" and that can display that data by invoking the print() method or change it with setBar(String).
The problem with the class above is that it is mutable, ie. its state can change. If multiple threads are operating on it, you might see unexpected behavior. For example, one thread changes bar's value before another thread has the chance to print() out its previous value.
What does this mean for domain objects? Can I have a domain object
called User defined as a singleton scope in the spring context? What
would happen?
This means the exact same thing for domain objects as it does for service or presentation objects. You can very much have a domain object of type User defined as singleton scope in the Spring context. If you want to is a different question. Do you want your application to only ever have access to that one User instance? No, then don't make it singleton. Yes, then make it singleton. This only applies if Spring is actually managing the instances for you.
More clarifications:
It's important to understand what a Singleton is. Wikipedia says
restricts the Instantiation of a class to one object
If we are taking about restricted in regards to a JVM, a Singleton could be implemented as described here. If we are talking about restricted in regards to a Spring ApplicationContext, then we are talking about a Spring managed singleton scope bean (read the chapter carefully). For example
<bean id="customBean" class="org.mine.CustomBean" />
which is retrieved like
(CustomBean) context.getBean("customBean");
// or
context.getBean(CustomBean.class);
If we are always retrieving the instance from Spring's ApplicationContext, we are effectively only ever instantiating the class once.
So if that variable is being accessed by different parts of the
application, the state of the object can be changed by that variable
by executing for instance the setter methods on that variable. But
that seems like a singleton to me.
A web application is multi-threaded. If each thread is accessing the singleton bean and mutating it, you might get lost updates. These are typically not desired since you cannot predict them and therefore are hard to test.
That variable can be used to keep changing the same data structure
throughout different parts of the application. So how is the Foo
object not a singleton?
As stated earlier, Singleton is a pattern that describes how an instance is unique in regards to some context. Simply doing
new Foo("the state");
doesn't make that object a singleton. It's how you use it that makes it a singleton.
Well, if multiple threads change the same object at the same time, they'll interfere with each other. Most spring applications harness the power of multiple threads.
A singleton scoped bean corresponds to a single object (hence the name). Everyone asking for that bean will get the same object.
Therefore, you should not change that shared object.
What does this mean for domain objects? Can I have a domain object called User defined as a singleton scope in the spring context? What would happen?
Sure you could declare a bean of type user, but - as we learned above - everyone asking for that bean will get the same user object. Is this really what you want? For instance, if the bean is intended to represent the logged in user, this design would imply that only a single user can log in ...
On the other hand, if the bean merely holds configuration data that equally applies to all users, it would be quite reasonable to for the threads to share the same object (of course, if they change it, synchronization is required to prevent interference).
I notice that mostly datasources and large configurations are usually in the spring xml file.
That is indeed the typical use. Data that should be different for each thread is typically kept in local variables (or objects reachable from there). Because local variables are different for each method invocation, interference by other threads is not possible.
You can also use spring to manage short lived objects by declaring beans with a short-lived scope (such as session or request scope in a servlet environment) - though in that case, you'll have to take care that different threads don't access the state of the same object at the same time. With request scope, that's usually easy because requests are usually processed by a single thread. With session scope, you'll actually have to synchronize access.

How do you handle Java Singletons when a network connection fails?

I have created a Singleton for my class which contains an instance of MemcachedClient (this could be any object that requires making a connection to a server but I am providing a concrete example). I initialize the MemcachedClient in a static init block. If the MemcachedClient cannot create an instance due to a connection error, this now means my class is worthless because it has a null MemcachedClient instance.
My question: What is the best solution for this type of situation? How are other people handling this situation?
The question (as stated in the title) is too broad, it depends of what the singleton is for.
In your case, the obvious question: if the initialization fails, can you expect that the issue will be solved in the near future? What is the cost of keep trying (redesign so your app does not crashes downward in weird ways) instead of just rebooting your app?
If you do not expect the error to be solved easily, just crash your application (with the proper logs/alerts/notifications). If you want it to keep running until the issue resolves, then the steps would be:
1) Pass the initialization to the constructor of the singleton (why put it in a static block if you can control access to the constructor).
2a) While the constructor fails, calls to getInstance will return null. Modify your application to be able to handle it.
2b) If the issue is present, create a singleton without the proper initialization. Calls to the methods of this objects will do nothing until the initialization issue has been solved / the object has been initialized. Modify your application to be able to handle these dummy methods. This method is swifter but way more complicated.
3) When a new instance is requested (if 2a) or a method is called (if 2b), check again if the object can be initialized.
Compare the cost of all the previous with the cost of just restarting your app after the issue has been solved.

Scope of Static Class Variables in Java

I have a static object defined in my logging class, along the lines of:
class myLoggingClass {
static java.util.Properties properties;
...
...
}
According to my reference book, this means that the properties object is shared by all instances of my class.
I find this definition insufficient. I'm writing a class that is being invoked more than once in each application on our project.
Further, our project uses several web services running in the same tomcat container. Each web service may have multiple threads.
The Java Virtual Machine running on the host may also run one or more web service client applications, which run external to tomcat.
So by this definition, I may have tomcat running multiple web services with threads, each having several objects, which may contain an instance of my class.
There may also be one or two web clients running outside of tomcat, but within the same JVM. Would all of these instances of my class share the same properties object? That would make it JVM-wide.
If the static object is not JVM-wide, does anyone know at what level each one would exist? One per tomcat container? One per web service, and one per standalone web service client application?
The reason: When I update my properties, I'm getting a java.lang.ConcurrentUpdateException from java.util.Properties.
I'm using a static boolean variable to "lock" the properties object when my class updates it, but this is not keeping the exception from occurring.
This leads me to believe that the static object used in my class may not be at the same scoping level as the one used in java.util.Properties... But that's just a guess.
Thanks for any help.
Statics aren't "shared by all instances of a class" - they're unrelated to instances; they belong to the type itself. In particular, static variables are perfectly usable without any instances being created.
That gives a clue as to the scope of statics: they're scoped by the Class object representing the containing class, which is in turn scoped by the ClassLoader that loaded it.
Depending on where the library is placed, the static variable may be JVM-wide or web-application wide - or possibly something in between, if Tomcat supports multiple hosting (I can't remember offhand).
Look at the Tomcat documentation for how the libraries are laid out and how they relate to class loaders. For example, here's the Tomcat 6.0 ClassLoader how-to guide, and the equivalent for 5.5.
How does your Boolean "lock" work? You should really use a proper lock (synchronized) to make sure that every use of the properties object (both read and write, including locking for the whole period during which you iterate through it) is appropriately locked.
Instead of changing the "live" Properties object, have you considered treating that as immutable - so when you want to update the properties, you take a copy, change that, and then make the copy the "live" version? You'd still need to prevent two different threads from making changes at the same time (or you'd lose some) but it's likely to make the reading side a lot easier and more efficient.
You may find that the scope of such a static variable is limited to one per ClassLoader that has loaded your class. I'm not sure how Tomcat arranges its ClassLoaders, so it's hard to say what the extent of the scope will be in that environment.
The likely cause of your ConcurrentModificationException is that you are iterating thru the values/entries of the Properties object in one thread while another modifies it at the same time. You cannot do this.
Can you elaborate on the locking mechanism that you mention here:
I'm using a static boolean variable to "lock" the properties object when my class updates it, but this is not keeping the exception from occurring.
?
Because it doesn't sound as if you are using the built-in locking and synchronization methods in Java.
Something like this should prevent threads from reading the Properties object while another thread updates it:
static Object lockObject = new Object();
...
synchronized(lockObject) {
// access the Properties object
}
Note that you will need to do this every time you access the Properties object, either to read it or modify it.
Also I would never recommend static objects to share data among all instances or static lockObjects - global data is evil - but it sounds as if you need this for some reason.
Could it be a classloader problem where the jar that contains your class is duplicated in each WEB-INF/lib of your different applications?
If so, I would try to add this jar to Tomcat libs and not to the application.

Categories

Resources