I have some business objects that make calls to EJBs. If the object is instantiated in the web tier, then obviously it needs to use a remote home interface to do the lookup. If it's being called from an EJB, then it should use the local home to do the lookup. Is there any way to determine which one should be used? I'd like to avoid the performance penalty of remote calls if it can be implemented transparently. Would it be possible for a Service Locator to know if it is running in an EJB container? Thanks, Rick DeBay
You'd actually have to combine the Service Locator and the Business Delegate patterns. Remember that the local and remote interfaces are two separate interfaces -- you'd either have to play funny games with super interfaces (not recommended) or have delegates that could be swapped for each other. Kyle
Originally posted by Kyle Brown: You'd actually have to combine the Service Locator and the Business Delegate patterns.
That's what I usually do. The Singleton Service Locator caches home interfaces, and uses it when a resource is requested. We don't use entity beans (or won't when I get done) so that's not a problem, all the delegate needs to get is the remote bean, not the home. The delegate's job then becomes wrapping errors, talking to the locator, and encapsulating a Transfer Object Assembler.
Rather than try to locate which container it's running in dynamically (and BTW, there is no foolproof API for this) you'd probably be better off setting this as some sort of configuration parameter. In something like a startup bean set the value in a static variable that your service locator can read. And BTW, it doesn't have to be within the EJB container to use local interfaces. As long as your Web and EJB container are co-located in the same JVM you can use local references (there are some classloader tricks to this, but it is possible...) Kyle
Don't know if i understand you correct ? Do your web container and EJB container run in different VMs ? Cause only then you have the restriction that you must use remote interfaces. Otherwise you can use also Local Interfaces from your web tier Olli
Antipatterns are seductive, aren't they? Looking at this further, I realized the signatures would be different for the local and remote interface (the RMI exception). I'm sure there are other drawbacks too. I was hoping for a shortcut, but I'll have to refactor the existing code even more now. Regarding the business components running in the same JVM as the web container, I don't want to assume this case. I want the final code to be as flexible as possible, and not have to refactor it again if the web container and the EJB container are on seperate machines. Perhaps for J2EE 1.5 home interfaces could return a reference to a local or remote object automagically, and have one interface instead of two. Rick DeBay
The signatures must be different not only because of network exceptions but moreso because the they use different calling conventions. Remote calls use "pass-by-value" while local calls use "pass-by-reference." A bean written with local semantics cannot work remotely, even if the remote interface has the exact same signature as the local interface. Having said that, most appservers will happily "convert" remote calls to local ones if both the client & the server are within the same JVM. So even if you program solely to the remote interface, you get the performance of local calls, while still having the option of moving each side to a different JVM. It's the best of both worlds. While this conversion contravenes the J2EE spec, you can get a huge performance boost using this feature if you're mindful not to (accidentally) depend on pass-by-reference semantics. Older appservers enabled this optimization by default, while on newer ones you must turn it on explicitly. -Ade Barkah