Defining EJB 3.1 Views (Local, Remote, No-Interface)
This post will talk about possible ways of defining EJB views using annotations (I’ll just mention about using EJB Deployment Descriptor at the end.) I’ll focus on the most current EJB 3.1 views omitting legacy local, remote and home interfaces. Therefore, we can choose between:
- remote business interface view,
- local business interface view,
- no-interface view.
I won’t discuss functional differences between those views but rather focus on possible ways of defining them.
Local Business Interface View
Interface has
@Local
annotation; EJB is implementing this interface.@Local public interface LocalA { void localA(); }
@Stateless public class MeineEJB implements LocalA { @Override public void localA() {} }
Advantages:
- You don’t have to specify interface type in your EJB. You just “Java implement” it and the container do the rest.
- Information about interface type is strongly attached to the interface so it might be easier to understand for other developers.
- Thanks to the Java
implements
clause you can use javac or your IDE to make sure all EJB business methods are implemented.
Disadvantages:
- Your interface now is tightly coupled with EJB technology (importing
javax.ejb.*
package.) You must now provide your API client with required libraries to use it.
Interface is a plain Java interface without annotation; EJB with
@Local
annotation is implementing it.EJB must define what interface is supposed to be exposed as local business interface (there is a default for that – see point no. 3.)
public interface LocalA { void localA(); }
@Stateless @Local(LocalA.class) public class MeineEJB implements LocalA { @Override public void localA() {} }
Advantages:
- Information about interface type is loosely-coupled. You can ship your API to the client and don’t care about EJB semantics. If you’ll hide it with a facade your end-user (even a developer) doesn’t even have to know it’s using EJB technology under the hood.
- Thanks to the Java
implements
clause you can use javac or your IDE to make sure all EJB business methods are implemented.
Disadvantages:
- Your EJB must now define all its business interfaces using
@Local
annotation so it’s additional work for you. Not only you implement an interface but you need to remember to declare that your EJB is exposing it. There is nothing (from the javac perspective) preventing you from putting an interface into@Local
annotation that is not actually implemented by your EJB.
Interface is a plain Java interface without annotation; EJB is implementing it.
Because it’s the only implemented interface of the EJB, a container assumes that it must be a local business interface. If EJB would implement more than one interface – the container will not be able to recognize which one is your local business interface.
public interface LocalA { void localA(); }
@Stateless public class MeineEJB implements LocalA { @Override public void localA() {} }
Advantages:
- Has all the advantages of the 1st and 2nd approaches discussed above.
Disadvantages:
- It assumes default behavior of the EJB container and developers knowledge about it. It will not work if you’re using more than one EJB view. Moreover, it will not work even if your EJB is implementing more than one interface (not necessarily an EJB view.)
Interface is a plain Java interface without annotation; EJB with
@Local
annotation is not implementing it.What’s interesting in this case is that because you’re not using Java
implements
clause you can actually have different signatures for methods in interface and EJB. Any such mismatch will result in an exception thrown by the container. Also note the lack of@Override
annotation on the business interface method implementation. This is because we’re not implementing any interface in Java terms.public interface LocalA { void localA(); }
@Stateless @Local(LocalA.class) public class MeineEJB { public void localA() {} }
Advantages:
- Information about interface type is loosely-coupled. You can ship your API to the client and don’t care about EJB semantics. If you’ll hide it with a facade your end-user (even a developer) doesn’t even have to know it’s using EJB technology under the hood.
Disadvantages:
- Has all the disadvantages of the 2nd approach discussed above.
- Knowledge that some method you declared as
@Local
interface is not implemented relies heavly on used IDE. Intellij IDEA will mark this as an error but AFAIR Eclipse won’t. - This is, in my opinion, combination of the most important disadvantages and therefore the worst way of defining EJB view.
Remote Business Interface View
Cases 1, 2 and 4 for Local Business Interface Views are also valid for Remote Business Interface Views. Point no. 3 is an exception. The container will never assume anything about remote interfaces. If an EJB is implementing some interface and it’s not defining what kind of interface it is – it’ll always assume it’s local.
No-interface View
I’m sure that after reading the above sections you’re able to figure out pros and cos of using the following two approaches to define no-interface EJB views. Hence, I will not discuss them here.
EJB is annotated as
@LocalBean
.This EJB can — but doesn’t have to — implement some interfaces (plain Java or business local/remote interfaces). The
@LocalBean
is valid only for an EJB class.@Stateless @LocalBean public class MeineEJB { public void localMethod() {} }
EJB doesn’t have any special annotations.
The container assumes that if a class is annotated as EJB but is not implementing any interfaces and doesn’t have any views-related annotations – it will expose a no-interface view.
@Stateless public class MeineEJB { public void localMethod() {} }
EJB Deployment Descriptor (ejb-jar.xml)
All previous sections were considering EJB views defined using annotations. You can also define EJB views using deployment descriptor (ejb-jar.xml
). Example:
public interface LocalA { void localA(); }
public interface RemoteA { void remoteA(); }
@Stateless public class MeineEJB { public void localA() {} public void remoteA() {} }
<ejb-jar xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd' version='3.1'> <enterprise-beans> <session> <ejb-name>MeineEJB</ejb-name> <business-local>com.piotrnowicki.remotelocalejb.LocalA</business-remote> <business-remote>com.piotrnowicki.remotelocalejb.RemoteA</business-remote> <local-bean/> </session> </enterprise-beans> </ejb-jar>
The above code and DD defines an EJB exposing three views (local business, remote business and no-interface). This is semantically identical to:
@Stateless @Local(LocalA.class) @Remote(RemoteA.class) @LocalBean public class MeineEJB { public void localA() {} public void remoteA() {} }
Reference: Defining EJB 3.1 Views (Local, Remote, No-Interface) from our JCG partner Piotr Nowicki at the Piotr Nowicki’s Homepage blog.