I'm kind of a newbie in EJBs,but I've been given an EJB tier to improve.
This tier consists of an EJB wich exposes the operations available:
#Stateless(name = "myejb")
public class Facade implements FacadeRemote
{
#EJB
private EntityAHomeLocal entityAHome;
#EJB
private EntityBHomeLocal entityBHome;
// methods signatures and implementations
}
As you can see this EJB use other local EJBs that manage operations on entities.
#Stateless
public class EntityAHome implements EntityAHomeLocal
{
#PersistenceContext(name="myUnit")
private EntityManager manager;
// methods signatures and implementations
}
I'm having hard time to fully understand the architecture of this tier.
Is this kind of architrcture common ?
Are local stateless EJB managed throught a pool of instances just like remote stateless EJBs ?
Would it still work even if entityAHome and entityBHome were remote EJBs ?
Strictly speaking, the spec only says stateless beans are "typically" pooled (section 4.3.10.2), so the behaviour for local beans is vendor-specific, but in practice I believe all the major vendors do (for example).
Local and remote interfaces are almost entirely interchangeable, but with extra deployment restrictions (i.e. they must be deployed locally, of course), and some calls to local interfaces use pass-by-reference semantics, whereas remote interfaces always use pass-by-value (link).
I can't see anything that would stop that code working with remote interfaces, although I think some of the naming is confusing - a session bean (#Stateless) is different from an entity, and in EJB terminology "home" refers to a kind of factory class, which I don't think is your intention here (?). Also, be aware that switching to #Remote can add a performance overhead, as the second link notes.
Related
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.
I have the following classes:
public class ScoringService {
#Inject
public ServiceOne service1;
#Inject
public ServiceTwo service2;
#Inject
public DecisionHandler dh;
public void scoreData() {
Data d1 = service1.getData();
Data d2 = service2.getData();
Data newData = process(d1, d2)
dh.handle(newData);
}
}
public class DecisionHandler {
#Inject
public ServiceOne service1;
public void handle(Data newData) {
service.updateData(newData);
}
}
ServiceOne and ServiceTwo are #Stateless annotated EJBs.
I know that container makes pools for that Stateless EJB and also proxies for injections and stuff. So in my case is it possible that there will be two different instances of ServiceOne in both instances of ScoringService and DecisionHandler? And therefore there will be overgenerated ServiceOne instances? I mean the ScoringService with injected DecisionHandler in it will be called for one purpose and there is no need two hold two instances of ServiceOne.
I made the DecisionHandler a separate class to disassemble complex logic concentrated in one ServiceClass. Also I can make the DecisionHandler as a plain class with a method and instantiate it during call. How should I understand that I should make it an EJB?
I become to think that it some outdated stuff for only Client-Server model with thick cliend to help making calls to the servers EJBs through remote calls and it SHOULDN'T be used in projects with web or self-running computing programs. Is that true?
So in my case is it possible that there will be two different
instances of ServiceOne in both instances of ScoringService and
DecisionHandler?
if you are talking about #Stateless then it is up to the container (application server). You are not supposed to take any assumption on the number of EJBs serving clients. So you can have one or two, it is unpredictable.
I made the DecisionHandler a separate class to disassemble complex
logic concentrated in one ServiceClass. Also I can make the
DecisionHandler as a plain class with a method and instantiate it
during call. How should I understand that I should make it an EJB?
If your application server is JEE compliant (i.e. not Tomcat) and your application is middle/big sized and you need transaction, scalability, and you want a class to act as a stand alone component with specific business logic, then you probably need an EJB. Besides, have you tried to run your classes ? Because if they are not managed by the container, the #Inject is not working.
I become to think that it some outdated stuff for only Client-Server
model with thick cliend to help making calls to the servers EJBs
through remote calls and it SHOULDN'T be used in projects with web or
self-running computing programs. Is that true?
Unfortunately, most people think the current specification for EJB is still 2.x, while instead 3.x is out since 2009. EJB in their current specification are scalable, transactional...they have many benefits rather than disadvantages, and they fit perfectly in a web context.
However just because you have mentioned remote call: #Remote interface have a little overhead to think about and some design decision to be made (coarse grained vs fine grained interface).
[Update]
Regarding scalability, these are few fragments from the official EJB 3.1 specification, there are many more:
Just in the introduction
Applications written using the Enterprise JavaBeans architecture are
scalable, transactional, and multi-user secure.
Then...
A typical EJB container provides a scalable runtime environment to execute a large number of session objects concurrently.
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. :)
At work and online I keep hearing the term "proxy" with respect to enterprise Java development. For example, metrics-spring uses this phrase:
This module does the following things:
Creates metrics and proxies beans which contain methods annotated with
#Timed, #Metered, #ExceptionMetered, and #Counted [emphasis mine]
I'm unfamiliar with a lot of the language in the Java ecosystem of frameworks and libraries. I feel like I have a good understanding of what a bean is, but I'm still not clear about how one would proxy a bean.
What does it mean to proxy a bean?
Typically, you have a bean like
Bean bean = new Bean(); // actually created by the context
With this, you can do anything that the Bean class declares as behavior (invoke its methods).
There are times where it would be nice if you could, for example, track how long a method invocation takes.
You could do
long start = .. // get start time
bean.invoke();
long end = .. // get end time
// end - start
But doing this for each method invocation sucks. So, instead, patterns, architectures, and styles like Aspect Oriented Programming exist.
Instead of the Bean above, you'd have
Bean bean = new TimingBean(new Bean()); // again done by the context
where the TimingBean is a proxy type that extends and implements all the types that Bean extends and implements. For all intents and purposes it is a Bean, but it adds a bunch of additional behavior before delegating each invocation to the Bean object. In this case, it would track how long each of Bean's method's took to execute.
Basic Spring uses JDK proxies and CGLIB proxies. Here are some differences between them.
It uses this for its scheduling and asynchronous invocations. It uses it for transactional support with databases. It uses it for caching. It even uses it for its Java based container configuration.
Proxying means that your client code thinks it's talking to one bean, but a proxy is really doing the listening and responding.
This has been true since early distributed client/server computing models like CORBA. A client would interact with an interface type as if it existed in their memory space, but they were really talking to a proxy that would handle all the messy details around marshalling request data into a request, communicating over the network to the remote object running on a server, and unmarshalling the response back to the client.
Spring uses this model for remoting. It also forms the basis for its aspect oriented programming model. Your code thinks it's dealing with a particular interface; Spring can weave in advice before, after, or around that instance and perform cross cutting operations like logging, transaction management, etc. on your behalf.
Some frameworks rely on a mechanism called instrumentation, which in short means to build a proxy of a given compiled bytecode, adding some code to it in some places we judge useful. This would implement many kinds of tasks, between them for example, adding a kind of profiling to a spring bean, as this library claims to do.
The Spring engine returns heavily instrumented proxies of every managed bean it offers - this way, you can use Spring declarative transaction handling, for instance. You would write "naive" daos without an actual connection handling, and "naive" service classes using the daos without an actual transaction handling - the instrumented proxies will include the boilerplate code with the connection instantiation, commits, rollbacks...
I hope this is of any help
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