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

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.

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.

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.

Is it wrong to pass EJBs as parameters to helper classes?

I'm in the situation where I need to create a cache to store certains values which need to be updated from the database. Since this cache needs to be singular, some sort of singleton implementation seems appropriate.
The problem is that this cache also needs access to the database via an EJB, which can't be injected since the cache exists outside of context (and yes, I'm looking forward to the #singleton annotation in EJB3.1).
The obvious solution is to pass the EJB into the cache as a parameter, but passing EJBs outside of context feels wrong, though I can't say why. Is it accepted practice?
Do note that you are normally not passing the EJB itself "outside of context". What you are typically passing around is a 'stub'. This stub can be passed around as any other normal object reference. Any calls on it will redirect back to an actual bean instance in the EJB container.
So if you have a cache in say the web module, have a backing bean injected with an EJB (or do a JNDI lookup) and pass that reference to a (static) cache, then I don't see a fundamental problem with that.
For all intends and purposes, the #Singleton annotation was indeed made for something like this. Hope you'll able to use it soon ;)
The main advantage of EJB is inside container. If you pass it outside you loose all the advantages which a container provide. Why don't you create a method in EJB that return the data you need. And the you can do, for example, JNDI lookup and call that method. In this way EJB will stay in the container and you will get your data.

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

Custom spring scopes?

Anyone know of any other custom spring scopes than Servlet Context Scope and ThreadScope ?
If you've made some closed-source custom scope I'd really also be interested in hearing what it does and how it worked out for you. (I'd imagine someone would make a WindowScope in a desktop app ?)
I'm open to all use cases, I'm looking to expand my horizon here.
We implemented our own custom Spring scope. A lot of our code works at a relatively low level, close to the database, and we maintain a conceptual level on top of that with its own object model of data sources, links, attributes etc.
Anyway, a lot of beans require a so-called StorageDictionary (an encapsulation of this object graph) to do their work. When we make non-trivial changes to the object graph, the dictionary sometimes needs to be blown away and recreated. Consequently, we implemented a custom scope for objects that were dictionary scoped, and part of the invalidation of a given dictionary involves clearing this custom scope. This lets Spring handle a nice form of automatic caching for these objects. You get the same object back every time up until the dictionary is invalidated, at which point you get a new object.
This helps not only with consistency but also allows the objects themselves to cache references to entities within the dictionary, safe within the knowledge that the cache will be valid for as long as they themselves are retrievable by Spring. This in turn lets us build these as immutable objects (so long as they can be wired via constructor injection), which is a very good thing to do anyway wherever possible.
This technique won't work everywhere and does depend heavily on the characteristics of the software (e.g. if the dictionary was modified regularly this would be horribly inefficient, and if it was updated never this would be unnecessary and slightly less efficient than direct access). However, it has definitely helped us pass off this management of lifecycle to Spring in a way that is conceptually straightforward and in my opinion quite elegant.
In my company we've created two custom scopes, one that will use Thread or Request and another that will use either Thread or Session. The idea is that a single scope can be used for scoped beans without having to change configuration based on the execution environment (JUnit or Servlet container). This also really comes in handy for when you run items in Quartz and no longer have a Request or Session scope available.
Background:
I work on a single web app that runs 4 different web sites under the same servlet context. Each site has its own domain name, e.g. www.examplesite1.com, www.examplesite2.com, etc.
Problem:
Sites sometimes require their own customised instance of a bean from the app context (usually for customised display of messages or formatting of objects).
For example, say sites 1 and 2 both use the "standardDateFormatter" bean, site 3 uses the "usDateFormatter" bean and site 4 uses the "ukDateFormatter" bean.
Solution:
I'm planning on using a "site" scope.
We have a Site enum like this:
enum Site {
SITE1, SITE2, SITE3, SITE4;
}
Then we have a filter that stores one of these Site values in the request's thread using a ThreadLocal. This is the site scope's "conversation id".
Then in the app context there'd be a bean named "dateFormatter", with 'scope="site"'. Then, wherever we want to use a date formatter, the correct one for the user's current site will be used.
Added later:
Sample code here:
http://github.com/eliotsykes/spring-site-scope
Oracle Coherence has implemented a datagrid scope for Spring beans. To sum it up:
A Data Grid Bean is a proxy to a
java.io.Serializable Bean instance
that is stored in a non-expiring
Coherence Distributed Cache (called
near-datagridbeans).
Never used them myself but they seem cool.
Apache Orchestra provides SpringConversationScope.
In a Spring Batch application, we have implemented an item scope.
Background
We have lots of #Service components which compute something based on the current batch item. Many of them need the same workflow:
Determine relevant item parts.
Init stuff based on the item.
For each item part, compute something (using stuff).
We moved the workflow into a base class template method, so the subclasses implement only findItemParts(Item) (doing 1 and 2) and computeSomething(ItemPart) (doing 3). So they became stateful (stuff initialized in findItemParts is needed in computeSomething), and that state must be cleared before the next item.
Some of those services also involve injected Spring beans which are also derived from the current item and must be removed afterwards.
Design
We implemented an AbstractScopeRegisteringItemProcessor which registers the item and allows subclasses to register derived beans. At the end of its process method, it removes the item from its scope context, and the derived beans using DefaultSingletonBeanRegistry.destroySingleton.
How it worked out
It works, but has the following problems:
We did not manage to get the derived beans cleaned up without registration (just based on their #Scope). The concrete processor must create and register them.
AbstractScopeRegisteringItemProcessor would have been nicer using composition and dynamically implementing all interfaces of the underlying processor. But then the resulting #StepScope bean is a proxy for the declared return type (i.e. AbstractScopeRegisteringItemProcessor or ItemProcessor) without the required callback interfaces.
EDIT
With the aid of #Eliot Sykes's solution and shared code plus #Cheetah's BeanDefinition registration, I was able to get rid of the registration as singleton beans. Instead, ItemScopeContext (the storage used by both the processor and the Scope implementation; Java-configured via a static #Bean method) implements BeanDefinitionRegistryPostProcessor. It registers a FactoryBean whose getObject() returns the current item or throws an exception if there is none. Now, a #Component annotated with #Scope(scopeName = "Item", proxyMode = ScopedProxyMode.TARGET_CLASS) can simply inject the item and need not be registered for end-of-scope cleanup.
So in the end, it did work out well.
A spring locale scope based on the users locale wihtin a web application
See related wiki page
In my company, we have also implemented spring custom scope. We have a multi tenant system where every customer can customize settings. Instance based scope of ours, caches the beans which are customer specific. So each time user of a customer logs in, these settings are cached and reused again when other users of the same customers sign in.
I once used a kind of conversation scope to store some objects in the session scope, in order to keep them when re-entering the same page, but limited to a single page to avoid to leave useless objects in the session. The implementation just stored the page URL and cleaned the conversation scope on each page change.

Categories

Resources