Reputation: 47675
Imagine you have two implementations of a @Local
interface
@Local
public interface LocalInterface {
}
@Stateless
public class MyFirstImplementation implements LocalInterface {
}
@Stateless
public class MySecondImplementation implements LocalInterface {
}
And I want to choose, without recompiling the project (that is, at runtime or using an external configuration property) which one (MyFirstImplementation or MySecondImplementation) I want to use.
public class MyClass {
@EJB
LocalInterface local;
}
Once one implementation is chosen, it does not have to change. I am using JBoss 5.1 if that helps.
Upvotes: 4
Views: 2635
Reputation: 47675
Another approach is to find the EJB reference with JNDI instead of relying on the automatic injection, just in case it could help anyone else:
public class MyClass {
LocalInterface local;
@PostConstruct
public void init() {
local = findImplementation();
}
private LocalInterface findImplementation() {
try {
InitialContext context = new InitialContext();
String ejbPath = // read from an external property
return (LocalInterface) context.lookup(ejbPath);
} catch ... { ... }
}
}
This is what I finally did, because with JBoss 5 (< Java EE 6, EJB 3.0) you can not make use of the useful @Produces
annotation. I mark PedroKowalski's answer as accepted because CDI annotations seem to be the better solution if you do not have other restrictions.
Upvotes: 2
Reputation: 38163
The method outlined by PedroKowalski is a typical way to do this. Another trick with respect to the "external configuration property", is simply configuring your builder such that only 1 implementation ends up in the jar you generate that holds the EJBs.
So you don't have to recompile classes or change any source code, but you do have to rebuild your jar to choose another implementation.
Upvotes: 1
Reputation: 18174
You can achieve it using the deployment descriptor - ejb-jar.xml. Something like this (might not be 100% accurate, but I think you've got the point):
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>MyClass</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/myLocalReferencedBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.yourpackage.LocalInterface</local>
<ejb-link>MyFirstImplementation</ejb-link>
<injection-target>local</injection-target>
</ejb-ref>
</session>
<session>
<ejb-name>MyFirstImplementation</ejb-name>
<!-- ... -->
</session>
<session>
<ejb-name>MySecondImplementation</ejb-name>
<!-- ... -->
</session>
</enterprise-beans>
</ejb-jar>
Another way is to use the CDI as described here: Inject @EJB bean based on conditions
Upvotes: 3