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 ]