Revising some past exam papers for an exam mainly focus on component-oriented design and J2EE, I have come across the following question:
A preliminary investigation of scenario 3: “Exchange Request” suggests that two EJBs will provide a suitable solution: a session bean called EnterExchangeRequest to control the processing and an entity bean called ExchangeRequest to represent the persistent properties of the request. Discuss the role of the following interfaces:
Home
Remote
LocalHome
Local
and how they would provide access to the services of the EJBs described above.
I could try to explain how Home and Remote interfaces would fit into the picture. I have also heard the lecturer say one could replace Home by LocalHome, and Remote by Local (why?), but why are they asking me to discuss the role of all four at the same time?
Do I get it right when I say, the EJB container (the application server) would see that an interface is Home or Remote and then decide that the bean can 'live' on any machine in the cluster, while in the case the interfaces are LocalHome and Local the container will know that the beans can't be distributed across multiple machines and will therefore keep them 'alive' in one machine only?
I am totally lost in this enterprise Java jungle. I am experiencing a BeanOverflow. Could you please tell me which of my assumptions are wrong, point out my misconceptions and blunders.
Thank you all who are willing to help me with these EJB interfaces.
P.S. Note that I am not asking you to answer the question from the past exam paper. Just curious if you have any thoughts as to what could they be after when asking this.
As pointed out by Yishay, Home/Remote and LocalHome/Local are tied together and the Home interface functions as a constructor.
Local beans are tied to the JVM they live in, you can not access them from the outside. Remote beans can be accessed from other JVMs.
I use a similar approach: I always deploy ears. Beans for the ear I make local beans, Beans meant for use by other ears I make remote. But it is possible to use the local beans in other ears, as long as the are deployed in the same JVM
Home is responsible for the creation of the Remote (kind of like its constructor) and LocalHome and Local have the same relationship.
In each case the container is giving you a proxy that references the real EJB class that you write.
If I had to guess, what the question was looking for was the use of remote for the session bean and local for the entity bean.
Anyway, although these concepts can still exists, things have been much better simplified in EJB3.
EDIT: In response to the comment, with EJB3, the bean class itself can implement the remote and the home interfaces directly (for the session beans). They are made EJB's with a single annotation. Stateful beans have a couple more annotations to deal with state issues. Entity beans do not have a Home interface, and do not need a local interface, you can interact with the java object directly. There is an EntityManager that retrieves the right entity beans based on a query, and that EntityManager is injected via an annotation.
That kind of sums it up in a paragraph. There are great tutorials on the web for this stuff, but EJBs in general solve a class of problem that is hard to appreciate unless you deal with the problem. They aren't the only way to solve it, but unless you deal with this type of programming, just reading about it won't really help you relate to it.
Related
I'm a Java EE nooby developer, According to many resources on the internet which claim that service locator design pattern is an anti-pattern because it hides classes dependecies and more things and should be avoided as many as possbile and using Dependecy Injection instead, as we know JNDI is an implemantation of service locator pattern.
I googled to check that JNDI is an implementation of service locator and i found this response which claims this : Understanding JNDI
Althought i see that JNDI is used in Java EE application for many purposes (Datasources, EJB lookup ...), So should i use it or should i avoid it as more as possible?, if JNDI isn't bad then service locator isn't?
I think that the one part of your question, whether service locator is good or not or whether JNDI is about this pattern is a bit esoteric. I can give a general advice here as being a software architect for some years now, that a pattern by itself is not good and not bad, it is just a piece of solution that was successfully used before in many cases and thus be declared a pattern in order to be used for future cases which are similar. And another thing is, as opposed to many years ago, when one had to know the GoF book by heart in order to survive an interview, nowadays it is much more important to understand the underlying concepts of a framework like Java EE than to implement all those patterns, because what you have to implement is very often very simple and straightforward, but using them relies on those concepts.
Concerning the second part of your question, you are almost never in need of directly using JNDI, but to use concepts built on top of it, as injection - that is what you should use in your application.
It's a horrible pattern IMHO since it is a massive security flaw. If dependencies are known at compile time and do not change, then its much easier to audit, gate and control possible vulenrabilities. Even within an organization JDNI is a Trojan horse waiting to be put to nefarious use, if a bad actor ca compromise some other area and your network, then get load whatever they want via a poorly/unwittingly implemented app. This log4j debacle is proof of that: don't allow apps to look-up and load whatever, whenever. It's a stupid idea. It's unsafe.
In a business environment we end up needing different kinds of data across applications so that it makes sense to store them in a shared location. For instance you may have a set of applications that share the same set of users, and we need authorization information for each of them listing what roles they have so we can know what they need to access. That kind of thing goes into an LDAP data store, you can think of it as a hierarchical database optimized for fast read access.
All sorts of things can go in these datastores, it's normal for an application server to stash connection pools in them, for instance. A lot of these, like users, roles, and connection pools, are vital things you need to do your job.
JNDI is the standard Java API for accessing these LDAP datastores.
The nasty thing about the service locator design pattern is that the client code doing the lookup has to know too much about the thing it is querying (mainly, where to get it from), and having that lookup hard-coded in the client makes the code inflexible and hard to test. But if we use dependency injection (whether it's CDI, Spring, whatever) we can have the framework inject the value we want into the code, while the JNDI lookups are handled within the framework code and not in the application. That means you can use JNDI without your application code having to use the service locator pattern.
I have a question.
Currently, I'm in the project of online shopping and we will deliver the products via email.
For the scenario where there will be more than one order request from different customer at the same time, may I know how can we handle for that?
I don't have any knowledge on that and still don't have an idea.
Please kindly help me.
Thanks & Regards
If you use a Java EE application server, you don't have to care about multiple threads, or you are even not allowed to control them (at least before Java EE 7).
I would propose to read some basic manuals on how to use CDI. CDI beans are managed components living in a defined scope. With the help of them you can define your business logic on handling one request and the container will care about handling and separating multiple of them.
Alternatively, you can use (stateless) EJBs which would provide you an automatic transaction handling. In both cases, you won't have to care about creating and maintaining instances of the request handlers yourself.
When should an object (i.e. an application-wide properties file) be kept in the session, as opposed to creating a singleton to keep it? When should each of these approaches be used?
Note: I am working on a clustered environment, if that makes any difference.
If it's supposed to be application-wide, then you should not store it in the session scope, but in the application scope. With storing in the session scope, you're unnecessarily duplicating the same data for every visitor. A singleton is also not needed at all, just instantiate once during server startup with help of a ServletContextListener and store it in the application scope using ServletContext#setAttribute().
+1 to BalusC, but I suspect that was just a typo on your part.
As for singletons, it depends on what you mean by singleton. If you have an EJB annotated with #Singleton, then that's fine (other dependency-injection providers may also support this pattern).
If you're talking about the standard singleton pattern, where you keep the instance in a static variable, then that's a bad idea. You should generally avoid static variables in Java EE or servlet containers, because the class loading can be a bit tricky - you may wind up with multiple copies when you don't expect it, or you may be sharing a single copy between different applications, or you may be keeping stuff in memory when you redeploy your application. You can make an exception in cases where the variable isn't exposed outside the class, and you don't really care how many copies of it you have (for example, logger objects).
Note: I am working on a clustered environment, if that makes any difference.
I don't disagree with what Mike and BalusC have already written, but I feel you're entering territory where implementation details matter. What you do and how you do it will depend on the back-end services, what sort of clustering, and what the application requirements are. I think the question is too broad to give specific answers.
Furthermore...
All Java EE profiles share a set of common features, such as naming and resource injection, packaging rules, security requirements, etc. This guarantees a degree of uniformity across all products, and indirectly applications, that fall under the “Java EE platform” umbrella. This also ensures that developers who are familiar with a certain profile, or with the full platform, can move easily to other profiles, avoiding excessive compartmentalization of skills and experience.
Java EE specifications define a certain level of compliance but the goal isn't to make every infrastructure heterogeneous. This sort of thing adds complexity to an already nebulous problem domain.
We have a project with a pretty considerable number of EJB 2 stateless session beans which were created quite a long time ago. These are not the first-line beans which are accessed from our client via RMI, rather they are used by that code to perform specific functions. However, I've come to believe that there's nothing to be gained by having them as session beans at all.
They do not need to be accessed via
RMI.
They do not retain any state,
they are just code that was factored
out of the first set of beans to
reduce their complexity.
They don't
have multiple different
implementations which we are swapping
out, each one has been as it was for
years (barring bug fixes and feature
additions).
None of them alter the
transaction that comes into them from the bean calling them
(that is they don't require a new
transaction, not participate in the
existing one, or otherwise change
things).
Why should these not all just be classes with a couple of static functions and no EJB trappings at all?
The only reason I can see is for clustering purposes (if you are doing clustering). That is the hand off to those beans could be on another VM on another machine if clustering is being done right to spread the load around.
That is likely not the case, and the movement to EJB's was just over-engineering. I'm suffering with that too.
Even transactions aren't really enough to justify it, you can have a single EJB that handles the transactions and call the different code through it via a Command type pattern.
There seems to be no reason why they shouldn't just be simple POJO's rather than stateless session beans. I think this is the conclusion that people came to after using EJB 1.x in this manner as well.
It's also the reason why frameworks such as Spring exist as an alternative to EJB's.
I'd say change them over to be just standard POJO's, but make sure you have a safety net of unit and functional tests (which might be a little bit harder with EJB's) to help you.
We currently have a web application loading a Spring application context which instantiates a stack of business objects, DAO objects and Hibernate. We would like to share this stack with another web application, to avoid having multiple instances of the same objects.
We have looked into several approaches; exposing the objects using JMX or JNDI, or using EJB3.
The different approaches all have their issues, and we are looking for a lightweight method.
Any suggestions on how to solve this?
Edit: I have received comments requesting me to elaborate a bit, so here goes:
The main problem we want to solve is that we want to have only one instance of Hibernate. This is due to problems with invalidation of Hibernate's 2nd level cache when running several client applications working with the same datasource. Also, the business/DAO/Hibernate stack is growing rather large, so not duplicating it just makes more sense.
First, we tried to look at how the business layer alone could be exposed to other web apps, and Spring offers JMX wrapping at the price of a tiny amount of XML. However, we were unable to bind the JMX entities to the JNDI tree, so we couldn't lookup the objects from the web apps.
Then we tried binding the business layer directly to JNDI. Although Spring didn't offer any method for this, using JNDITemplate to bind them was also trivial. But this led to several new problems: 1) Security manager denies access to RMI classloader, so the client failed once we tried to invoke methods on the JNDI resource. 2) Once the security issues were resolved, JBoss threw IllegalArgumentException: object is not an instance of declaring class. A bit of reading reveals that we need stub implementations for the JNDI resources, but this seems like a lot of hassle (perhaps Spring can help us?)
We haven't looked too much into EJB yet, but after the first two tries I'm wondering if what we're trying to achieve is at all possible.
To sum up what we're trying to achieve: One JBoss instance, several web apps utilizing one stack of business objects on top of DAO layer and Hibernate.
Best regards,
Nils
Are the web applications deployed on the same server?
I can't speak for Spring, but it is straightforward to move your business logic in to the EJB tier using Session Beans.
The application organization is straight forward. The Logic goes in to Session Beans, and these Session Beans are bundled within a single jar as an Java EE artifact with a ejb-jar.xml file (in EJB3, this will likely be practically empty).
Then bundle you Entity classes in to a seperate jar file.
Next, you will build each web app in to their own WAR file.
Finally, all of the jars and the wars are bundled in to a Java EE EAR, with the associated application.xml file (again, this will likely be quite minimal, simply enumerating the jars in the EAR).
This EAR is deployed wholesale to the app server.
Each WAR is effectively independent -- their own sessions, there own context paths, etc. But they share the common EJB back end, so you have only a single 2nd level cache.
You also use local references and calling semantic to talk to the EJBs since they're in the same server. No need for remote calls here.
I think this solves quite well the issue you're having, and its is quite straightforward in Java EE 5 with EJB 3.
Also, you can still use Spring for much of your work, as I understand, but I'm not a Spring person so I can not speak to the details.
What about spring parentContext?
Check out this article:
http://springtips.blogspot.com/2007/06/using-shared-parent-application-context.html
Terracotta might be a good fit here (disclosure: I am a developer for Terracotta). Terracotta transparently clusters Java objects at the JVM level, and integrates with both Spring and Hibernate. It is free and open source.
As you said, the problem of more than one client web app using an L2 cache is keeping those caches in synch. With Terracotta you can cluster a single Hibernate L2 cache. Each client node works with it's copy of that clustered cache, and Terracotta keeps it in synch. This link explains more.
As for your business objects, you can use Terracotta's Spring integration to cluster your beans - each web app can share clustered bean instances, and Terracotta keeps the clustered state in synch transparently.
Actually, if you want a lightweight solution and don't need transactions or clustering just use Spring support for RMI. It allows to expose Spring beans remotely using simple annotations in the latest versions. See http://static.springframework.org/spring/docs/2.0.x/reference/remoting.html.
You should take a look at the Terracotta Reference Web Application - Examinator. It has most of the components you are looking for - it's got Hibernate, JPA, and Spring with a MySQL backend.
It's been pre-tuned to scale up to 16 nodes, 20k concurrent users.
Check it out here: http://reference.terracotta.org/examinator
Thank you for your answers so far. We're still not quite there, but we have tried a few things now and see things more clearly. Here's a short update:
The solution which appears to be the most viable is EJB. However, this will require some amount of changes in our code, so we're not going to fully implement that solution right now. I'm almost surprised that we haven't been able to find some Spring feature to help us out here.
We have also tried the JNDI route, which ends with the need for stubs for all shared interfaces. This feels like a lot of hassle, considering that everything is on the same server anyway.
Yesterday, we had a small break through with JMX. Although JMX is definately not meant for this kind of use, we have proven that it can be done - with no code changes and a minimal amount of XML (a big Thank You to Spring for MBeanExporter and MBeanProxyFactoryBean). The major drawbacks to this method are performance and the fact that our domain classes must be shared through JBoss' server/lib folder. I.e., we have to remove some dependencies from our WARs and move them to server/lib, else we get ClassCastException when the business layer returns objects from our own domain model. I fully understand why this happens, but it is not ideal for what we're trying to achieve.
I thought it was time for a little update, because what appears to be the best solution will take some time to implement. I'll post our findings here once we've done that job.
Spring does have an integration point that might be of interest to you: EJB 3 injection nterceptor. This enables you to access spring beans from EJBs.
I'm not really sure what you are trying to solve; at the end of the day each jvm will either have replicated instances of the objects, or stubs representing objects existing on another (logical) server.
You could, setup a third 'business logic' server that has a remote api which your two web apps could call. The typical solution is to use EJB, but I think spring has remoting options built into its stack.
The other option is to use some form of shared cache architecture... which will synchronize object changes between the servers, but you still have two sets of instances.
Take a look at JBossCache. It allows you to easily share/replicate maps of data between mulitple JVM instances (same box or different). It is easy to use and has lots of wire level protocol options (TCP, UDP Multicast, etc.).