Adam Bien's Weblog

Monday Jun 22, 2009

Beans With Both Views (@Local And @Remote) - An Anti Pattern?

It seems to be a pre assumption, that an EJB should have only one view - either @Remote or @Local. The views are not only useful for distribution, but also for the expression of visibility and private / public contracts in particular. A ServiceFacade is the only artifact, which is allowed to be visible from outside the container, so it can come with @Remote. Others, like, Services are not allowed to be exposed directly to the outside world.

If you are using @Remote interfaces, all the parameters and return values have to be copied. This is what the spec says. The application servers provide their own proprietary and not-portable solutions to pass the the parameters and return values "per reference" and not "per value". The business @Local interfaces have the "per reference" semantics as well. All parameters and return values are returned directly and not copied.

The @Local and @Remote interfaces can be aligned with the private (or more precisely package-wide) and public visibility and so the principle of encapsulation / data hiding as well. @Remote is visible to the outside world, and @Local is not. Therefore @Remote could be considered as public and @Local as package-wide visibility. 

Especially the public contracts of a ServiceFacade should remain as stable as possible, every change could break potentially many clients. However, there is often needed, to provide a pragmatic access to the component's API, without breaking the API. This is easily achievable with EJB 3:

  • You have to provide both interfaces @Local and @Remote
  • @Remote interface defines the public contract
  • @Local inherits from the @Remote. @Local can remain empty at the beginning
  • The Bean implements the @Local interface and exposes both. 
The sample (from http://kenai.com/projects/javaee-patterns - project ServiceFacade, package com.abien.patterns.business.sf.mc) demonstrates that:
public interface BookOrderingServiceLocal extends BookOrderingServiceRemote{
    public void cancelOrder(String id);
}

public interface BookOrderingServiceRemote {
    public void order(String isbn,String name);
    public Object referenceTest(Object reference);
}
@Stateless @Local(BookOrderingServiceLocal.class) @Remote(BookOrderingServiceRemote.class) @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public class BookOrderingServiceBean implements BookOrderingServiceLocal {

 

I have still no idea, why a Session Bean with two views was considered as an anti-pattern. I used that since several years - the approach works perfectly and is application server independent. 

[See also: Dual View Facade Strategy on page 60 in Real World Java EE Patterns


[my tweets]  Rss My book: Real World Java EE - Rethinking Best Practices

Kommentare:

Hi Adam,

I think there is a little error:

@Remote inherits from the @Local

... isnt it the other way round?

Gesendet von Jonas Bandi am June 22, 2009 at 10:56 AM CEST #

@Jonas,

thanks - absolutely - I corrected that in the text. Source code was and is still o.k..

thanks!,

adam

Gesendet von Adam Bien am June 22, 2009 at 11:46 AM CEST #

Hi Adam,
are you sure that supplying both views to a bean was considered an anti-pattern rather than applying both *annotations* to the bean *class*?
I think there was a recommendation somewhere that annotating the bean class with both @Remote and @Local might not be portable and that you should therefore annotate the *interfaces* with a single annotation each (and let the class implement both/all interfaces).
But I, too, do think that providing both views for a bean makes perfect sense.
Thomas

Gesendet von Thomas Much am June 22, 2009 at 09:02 PM CEST #

@Thomas,

I read about this anti-pattern in some J2EE book - cannot remember it. In my book, however, its a pattern - with the "anti" prefix...

thanks!,

adam

Gesendet von Adam Bien am June 22, 2009 at 09:09 PM CEST #

Thanks for the tip.
Actually I don't know if this is the right place but...
I have many distinct database or let say different datasources. At the same time I need to build different application that can interact with this pool of sources.
I started defining a set of remote EJBs which expose part of the databases needed by applications. Then applications use the DBs pool through my EJBs.
I'm worried about maintaining a lot of small applications in case I modify something on the db side.
A lot of tutorials are focused on building just one application and just one db in mind, so I can't figure out if my approach can be succesfull or not.

So just a question.
What do you suggest to do in this kind of scenario ? Any idea is apprechiated.

Best regards.

Gesendet von Raoul am June 30, 2009 at 05:39 PM CEST #

Senden Sie einen Kommentar:
  • HTML Syntax: Ausgeschaltet
Interviews/About
My Recent Book
Java One 2009
CommunityOne East N.Y.C
JavaONE 2008 Interview
Search
...the last 150 posts
...the last 10 comments
greenfire.dev.java.net
Links
my.netbeans.org
Visitors
License