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.
1. Local Business Interface View
1.1 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.
1.2 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.
1.3 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.)
1.4 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.
2. 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.
3. 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.
```java
@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.
```java
@Stateless
public class MeineEJB {
public void localMethod() {}
}
```
4. 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() {}
}