Search code examples
java-ee-6ejb-3.1

Configuration for EJB lookups at runtime


I have several services deployed as EJBs on a JBoss-AS-7.1 server. Many applications use these EJBs by doing a lookup like this:

@EJB(lookup = "java:global/FooService/FooBean!com.xyz.FooBeanRemote")
private FooBeanRemote fooBeanRemote;

The problem is that the lookup string is hard-coded in the source. I want to be able to change this lookup at runtime - without a re-compilation - because FooService may be updated some time in the future, and perhaps have a different implementation. In addition, the ejb could also move to a different server instance.

What would be the best way to achieve this?


Solution

    1. Use ejb-jar.xml instead of annotation (check here)
    2. use InitialContext in your code to lookup for bean and move bean name to properties file
    3. Implement CDI producer methods in separate jar

    --EDIT--- Quick HOWTO about last point:

    1. Create qualifier

    @Qualifier
    @Retention(RUNTIME)
    @Target({FIELD, TYPE, METHOD})
    public @interface FooService {
    }
    

    2. Create producer method

    public class EJBProducer {
        @Produces
        @FooService
        @EJB(lookup = "java:global/FooService/FooBean!com.xyz.FooBeanRemote")
        private FooBeanRemote fooBeanRemote;
    }
    

    3. Use in your code

    @Inject @FooService
    private FooBeanRemote fooBeanRemote;
    

    Two first points may be in another jar archive (remember to include there META-INF/beans.xml file). You can also use producer method instead of field, and access ejb programmatically.