Can I deploy an EJB under multiple names in a similar way as this is possible in Spring using a name alias?
2 Answers
According to EJB 3.0 specification:
At declaration time:
name
The annotation element name defines the bean “name” and defaults to the unqualified name of the bean class. The bean name must be unique in the scope of the module containing the EJB.
Referencing a EJB:
beanName
The beanName element specifies the bean “name” as declared in the @Stateful and @Stateless annotations via the name element or in the deployment descriptor via the element. The beanName element is most useful when more than one EJB implement the same business interface in an application: the beanName lets the developer reference a specific EJB in a specific module.
So, yes you could but the ejb must be packaged in different modules and then point it through the beanName.
Not As Spring., there could be ways but that is vendor specific, NOT PORTABLE.

- 3,317
- 5
- 32
- 51
Yes, it is possible to deploy same EJB under multiple names or aliases using ejb-jar.xml
descriptor.
Moreover both name defined in the EJB xml descriptor and one defined in the annotation will be taken into account (although I would not risk mixing between xml descriptor and annotations in this case for portability reasons).
This example works on JBoss AS 7.1.1.Final:
@Local
public interface PingWorker {
String ping(String name);
}
@Stateless(name = "PingAlias") // first name
public class PingWorkerBean implements PingWorker {
@Override
public String ping(String name) {
return "Hello " + name;
}
}
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0">
<enterprise-beans>
<session>
<ejb-name>PingWorker</ejb-name> <!-- second name -->
<ejb-class>com.xyz.service.PingWorkerBean</ejb-class>
<session-type>Stateless</session-type>
</session>
<session>
<ejb-name>PingProcessor</ejb-name> <!-- third name -->
<ejb-class>com.xyz.service.PingWorkerBean</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
</ejb-jar>
In referencing component you can declare:
@Stateless
public class PingBean implements Ping {
@EJB(beanName = "PingAlias")
private PingWorker pingWorkerByAnnotaion;
@EJB(beanName = "PingWorker")
private PingWorker pingWorkerByDescriptorOne;
@EJB(beanName = "PingProcessor")
private PingWorker pingWorkerByDescriptorTwo;
}
and all three references should be satisfied. On deployment there are three EJBs deployed which expose the same interface and implementation but with different names:
java:global/ear-app-1/ejb-1/PingProcessor!com.xyz.service.PingWorker
java:app/ejb-1/PingProcessor!com.xyz.service.PingWorker
java:module/PingProcessor!com.xyz.service.PingWorker
java:global/ear-app-1/ejb-1/PingProcessor
java:app/ejb-1/PingProcessor
java:module/PingProcessor
java:global/ear-app-1/ejb-1/PingAlias!com.xyz.service.PingWorker
java:app/ejb-1/PingAlias!com.xyz.service.PingWorker
java:module/PingAlias!com.xyz.service.PingWorker
java:global/ear-app-1/ejb-1/PingAlias
java:app/ejb-1/PingAlias
java:module/PingAlias
java:global/ear-app-1/ejb-1/PingWorker!com.xyz.service.PingWorker
java:app/ejb-1/PingWorker!com.xyz.service.PingWorker
java:module/PingWorker!com.xyz.service.PingWorker
java:global/ear-app-1/ejb-1/PingWorker
java:app/ejb-1/PingWorker
java:module/PingWorker
As you may see this works differently than aliases in Spring. While in Spring aliases are only different names that refer to the same instance or set of instances (depends on the scope) - in EJB you need to declare EJBs multiple times. In the EJB container these become separate EJBs in terms of instance pools etc.
Depending on what you are trying to achieve - you may also consider overriding referenced EJB name in referencing EJB (override annotation beanName
with descriptor <ejb-link/>
). More on this here:
Choose EJB to be injected without recompiling.