Stateful session beans vs Stateless session beans, Instance variable dilemma - java

I have a stateless session bean, but I want to add a reference to another bean in order to do some process. So if I add reference to another bean it shows up at instance level variable like this,
#Stateless
public class AccountFacade extends AbstractFacade<Account> implements AccountFacadeRemote {
#EJB
private BillerFacadeRemote billerFacade;
public AccountFacade() {
super(Account.class);
}
... all other methods...
}
Question
Now, by definition stateless bean should not have any instance level variables. So I am quite confuse about where to put this private BillerFacadeRemote billerFacade;?

Your code is fine.
The #EJB annotation is injecting the bean into your class, and the application server manages its lifetime.
I recommend reading, or skimming the pretty long Java EE tutorial.
"The EJB container typically creates and maintains a pool of stateless session beans, beginning the stateless session bean’s lifecycle. The container performs any dependency injection and then invokes the method annotated #PostConstruct, if it exists. The bean is now ready to have its business methods invoked by a client."

It's okay for a stateless beans to have instance variables that represent dependencies.
In fact, this is even encouraged. Without instance variables you could in many situations just use static method in a utility class instead.
What however is NOT encouraged, is have instance variables representing client observeable state. That is wrong, but dependencies like the entity manager, jms queues, JDBC connections, and thus other services that your stateless service delegates (part of) its work to, is absolutely okay.
Notice that the injections are true instance injections in instance variables. It are not class level (static) injections.

Related

Why do we need #Lookup, whats wrong with scope=prototype?

I'm studying spring beans and came across #Lookup, it says:
If we happen to decide to have a prototype Spring bean, then we are
almost immediately faced with the problem of how will our singleton
Spring beans access these prototype Spring beans?
hmm, I don't get it, because when I studied scope=prototype it says:
4.4.2 The prototype scope
The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every time a
request for that specific bean is made
so it seems i misinterpreted the words:
a request for that specific bean is made
actually programming in spring framework every line of the code is inside of some bean (i.e. #controller, #Service, etc), isn't it?
And almost all of them are singletons, isn't it?
So if I need prototype I just make scope=prototype and almost everytime it's injected to another bean (i.e. #controller, #Service, etc) isn't it?
So please give a real world scenarios, 1) when one should use #Lookup and 2) when it's not needed
Ok for the 1) the scenario:
#Component
#Scope("prototype")
public class SchoolNotification {
// ... prototype-scoped state
}
#Component
public class StudentServices {
// ... member variables, etc.
#Lookup
public SchoolNotification getNotification() {
return null;
}
// ... getters and setters
}
Please, show me scenario for the 2) case, and explain please the difference
Thank u
The implicit Bean scope in Spring is Singleton.
That means for a JVM instance, only a single instance of a Bean exists in memory (theoretically).
When you #Autowire a Prototype-scoped Bean inside a Singleton-scoped Bean, that Prototype one becomes a sort-of-singleton. Just think about it; a Singleton gets created, its injectable fields get Autowired, and that is it, the instance lives forever along with all its fields (keep in mind those Prototype-scoped fields are "pure" instances, they're not proxied).
#Lookup
is a proxy-driven annotation. What that means is Spring will extend your class using JDK proxies or CGLIB proxies, and it will override/implement the #Lookup-annotated method, providing its own version which uses a BeanFactory#getBean each time it is invoked.
The documentation is clear on this point
An annotation that indicates 'lookup' methods, to be overridden by the
container to redirect them back to the BeanFactory for a getBean call.
Thus, that means a fresh Bean instance is returned every time.
Just for your knowledge, another approach for working with Prototype-scoped Beans inside "other"-scoped Beans is using ProxyFactoryBean. The only difference is that the proxy is created at configuration-time, and then made available for direct #Autowireing, thus not requiring the definition of a #Lookup method, which sometimes is not wanted (usually by folks that are obsessed with clean code, like me).

How to change instance (target) under CDI (Weld) proxy without proxy recreation

I want to refresh bean (destroy, initialize) if some property is changed, for example db url connection. The problem is that this bean might be already injected in other beans in CDI container. I have 2 thoughts about this:
1. If bean is proxied - destroy target for this proxy, re-initialize target inside this proxy.
2. For #Singleton and #Dependent beans, because they are not proxied, I can wrap such beans in proxy and do the same as above.
The reason I want to wrap it in proxy is that when property changed and I want to recreate real object, I should also know all dependent beans that have dependency on my bean.
So my questions are:
1. How to replace real object inside proxy in CDI? or
2. If I dont want to keep proxy as I explained above, how to create proxy object for my bean and re-inject it to all dependent beans in CDI container?
This is my previous question:
Re-inject CDI bean if some injected property changed
Again, I use CDI (Weld), not Spring IoC, so I can not use #RefreshScope from Spring cloud config, but I think my expected functionality can be similar with using custom scope.
For #DependedSCoped beans you can use
class MyBean {
#Inject
private Instance<MYType> myTypeInst;
// This will ensure, that the bean is always fresh created.
// But the property value on the former instance will be lost
// So the changable value has to be provided another way to the created bean
public void do SomeThing(){
MyType bean = myTypeInst.get();
myTypeInst.destroy(bean);
}
}
If you use a #Depended scoped bean, then you must be aware that the injection target gets its instance which is exclusively for this bean, so who is changing the value? Is the #Dependend scope the right scope for your use case?
It should not be necessary to provide an own proxy or hack into an existing one, just find the proper scope for your use case and implement the bean properly. If a connection url can change then the bean managing the connection must be aware of a change and recreate the connection and the beans using this bean need to retrieve the connection each time the use it.
Maybe you could provide an description of your use case, then we maybe can you provide you with an better answer.
Conclusion
As the use case became clear (see comments below), it resulted in the intention to implement a custom scope, because CDI doesn't seem to provide a suitable scope for this use case. I recommend to try to find a provided CDI scope if possible and implement a custom scope only if necessary, because you will have to take care about the lifecycle of your beans, management of your scope and how the beans, managed by your scope, can and will be used by an application. If not implemented with care a custom scope could cause problems such as memory leaks, if for instance your beans are not properly discarded after usage.

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.

EJBObject shared among clients?

Head first EJB states that in the case of stateless session beans:
Clients don't share EJBObject, but the same bean can serve multiple
EJBObjects
I don't see any reason why a single EJBObject cannot serve multiple clients.
Furthermore, if what the book states is correct, what is the advantage we get from pooling beans if we have to create one EJBObject per client ?
First of all, one has to understand what an EJBObject is:
The EJBObject interface is extended by all enterprise beans' remote interfaces. An enterprise bean's remote interface provides the remote client view of an EJB object. An enterprise bean's remote interface defines the business methods callable by a remote client.
With that being cleared, consider the following local EJB example:
public class SomeClass {
#EJB
private SomeBean someBean;
...
}
Basically, our EJBObject is nothing more than an attribute of our class SomeClass which references the EJB SomeBean.
What's happening is that, on the container's point of view, he's not really creating and injecting a dedicated instance of the EJB SomeBean. Instead, he's instantiating the EJB SomeBean, storing it in his EJB pool, creating a proxy for this instance and injecting the proxy in on our class SomeClass.
Therefore, for each client, you have a single EJBObject or proxy but, under the hood, as the Head First states, the same bean can serve multiple EJBObjects.
...what is the advantage we get from pooling beans if we have to create one EJBObject per client?
Well, for instance, thread-safety: if you have several instances of SomeClass, calling concurrently the same method of someBean, it is guaranteed that those calls will never be delegated to the same instance since Stateless session instances are dedicated to an EJB object only for the duration of a single method call.
Other advantages of EJB pooling can be found on this answer by Will Hartung. :)

What is the difference between #ApplicationScoped and #Singleton scopes in CDI?

In CDI there is the #ApplicationScoped and the (javax.inject) #Singleton pseudo-scope. What is the difference between them? Besides the fact that #ApplicationScoped is proxied, and #Singleton is not.
Can I just change my #Singleton bean to #ApplicationScoped? Can #ApplicationScoped bean have two (or more) instances?
#Singleton is not part of the CDI specification. It is part of EJB and javax.inject (JSR-330). It is not mentioned in the spec what is its behaviour, so you can only rely on what's written in the Weld documentation.
in short: You can even mix it (#Singleton and #ApplicationScoped) and it makes sense in some scenarios.
(and works as expected in mine!)
Additionally to the other answers so far I'd like to add some more points for clarification in real world scenarios.
For me this question developed out of How do I force an application-scoped bean to instantiate at application startup?
In some discussion there I stated this and can't find a valid argument against it so far:
In a lot of real-life scenarios/setups I would say it's hard to
definitely say - from an abstract/modelling point of view - whether
something is (or will become/be treated like) an EJB or an application-scoped managed bean.
(debatable but not conclusive) arguments (from my point of view) against it so far:
(#BalusC and all others: I'd like to see them beeing conclusive, but if not, the above may hold true and nevertheless the arguments may still help the reader to get the differences/advantages/disadvantages/ bad/good practices)
EJB vs. Managed Bean
BalusC: That's an EJB not a managed bean, which is quite different. EJBs run in backend and managed beans in frontend. EJBs run in transactional context too.
[...] You just confused enterprise beans with managed beans and I just pointed out that.
but:
me: I think you are not quite correct and overstating the meaning/usage and it looks debatable to me. http://en.wikipedia.org/wiki/Enterprise_JavaBeans
Enterprise JavaBeans (EJB) is a managed, server software for modular construction of enterprise software, and one of several Java APIs. EJB is a server-side software component that encapsulates the business logic of an application.
Types of Enterprise Beans
Session Beans [3] that can be either "Stateful", "Stateless" or "Singleton" [...]
Message Driven Beans [...]
... which still holds true in my case.
Singleton EJB vs. Application Scoped Bean
Locking
BalusC: A singleton EJB isn't the same as an application scoped bean. A singleton EJB is read/write locked and thus potentially inefficient/overconvoluted for the task you had in mind. Long story short: Grab a good Java EE book and learn to use the right tool for the job. One way definitely isn't the other way. That it works doesn't mean that it's the right tool. A sledgehammer is capable of fastening a screw, but it isn't necessarily the right tool to that :)
but:
(I can't see the sledgehammer here - sorry ...)
It's good to know the locking defaults (I was not aware of it), but this seems to be incorrect again: Oracle Java EE 6 Tutorial on Managing Concurrent Access in a Singleton Session Bean
When creating a singleton session bean, concurrent access to the singleton’s business methods can be controlled in two ways: container-managed concurrency and bean-managed concurrency.
[...]
Although by default, singletons use container-managed concurrency, the #ConcurrencyManagement(CONTAINER) annotation may be added at the class level of the singleton to explicitly set the concurrency management type
Usually when you want to have only one instance of some object you probably should use #ApplicationScoped annotation - such object is proxied and thus can even be properly serialized out-of-the-box.
On the other hand, there are also many cases, where you want only one instance of the class, but such class cannot be proxied (e.g. because of being final) - then #Singleton is a rescue. Because Singleton is a pseudo-scope and is not being proxied like any "normal" scope.
#Singleton in JSR-299 refers to Singleton session beans (javax.ejb.Singleton, not javax.inject.Singleton), not JSR-299 managed beans in a built-in scope called Singleton.
You might find in your server that #ApplicationScoped is one-per EAR or one-per WAR/EJB-JAR as it is not clear in the specification, but you should definitely not expect it to be one per JVM.
There is one more difference:
#Singleton is not bean defining annotations, as the Singleton scope is not a normal scope.
Then #ApplicationScoped is bean defining annotations.
With CDI 1.1 spec: When application in discovery-mode = annotated, Weld does not identify beans with #Singleton and not loaded this
One of the major differences that you can write your class with default constructor has private access modifier when using javax.inject.Singleton, but your class should have default constructor with at least default access modifier when using javax.enterprise.context.ApplicationScoped and this is JBOSS 6.1 GA Final implementation

Categories

Resources