I am currently working on a web application and still wonder where i can sneak-in some ejb. But there are 2 questions i need to clarify: My 2 questions: 1) When a request is received by the servlet/jsp why do most examples (i.e. from books) i have seen choose a "remote" call to the ejb object? Is it not better to just call the "local" ejb object? I mean with marshalling and unmarshalling, the response time will be awful. 2) Is there a way in ejb to make the call to either remote or local dynamic? For instance, i want to always use a local call but my server will automatically switch to a remote call (i.e call another server/jvm) when the default server has too much traffic? Currently i am hard coding the calls to either remote or local. Gosh there has to be a better way. Is there?
1. The reason is that by coding to the remote interface, you won't have to change your application when you move to a clustered or multi-tier environment. For example, say your site grows and grows such that you now need one physical box for the DB, one for the EJB layer, and one for the WEB layer. If you had coded to local interfaces, you'd be doing a lot of work. Note that some EJB containers will do this for you. IIRC, WebLogic used to detect that the bean you were calling was actually local and avoid the serialization. However, what if you *counted on* the serialization, effectively creating pass-by-value for object graphs? If you modify those graphs, thinking they're local copies, you'd suddenly be modifying the original objects. Bad times ahead. 2. I don't think you can do this dynamically, but you can at least abstract the process so that at application startup you can choose to use remote or local interfaces. This is called the Business Delegate pattern. Create an interface that looks just like your local interface (it probably is the same). Then create two delegates that implement that interface: a local version and a remote version. They should each hold the session bean stub and proxy methods calls to it. The only difference is that the remote version catches RemoteExceptions to maintain the same interface. For example, say you have a single method in your session bean:
Your local and business interface would have the same signature; the remote interface would add only RemoteException to the throws clause. Here's how you'd implement the delegates:
Do whatever you want when you catch RemoteException. I have my delegates throwing an unchecked ServiceException after logging it. This way the interface doesn't change, and the clients can't handle the exception directly. It propagates up to the higher-level framework. You'll need to provide methods to set up the service initially when you create the delegate, but the Factory pattern would help here. [ August 07, 2003: Message edited by: David Harkness ]
Two other reasons for the use of the 'remote' object. Prior to EJB 2.0 spec, there was no 'local' object. Therefore, if you want to get a certification based on the older spec (like the SCEA) you better know about remote objects. Also, as most reference books are either older, or are version 2, they often just reuse the older examples. The other reason if for testing purposes. Most of the time, your test app that will call the EJB is not located in the same JVM, so you will need to use the remote call. What I generally do is create both objects, and use them as appropriate. Mastering EJB2.0 available for a free download on serverside.com gives examples of how to create both objects and when to use them.
The other reason if for testing purposes. Most of the time, your test app that will call the EJB is not located in the same JVM, so you will need to use the remote call.
Refer to this unit testing tool Cactus Cactus is deployed within the same VM (server) as your Local EJB Objects. Tests are triggered from the client that in turn invoke the cactus redirector which in turn can run your tests. Cactus extends JUnit so you still write JUnit tests. It offers lot more.
Joined: Jan 23, 2002
Thanks everyone for your response. That was enlightening.