0

Say I have an EJB with the following configuration:

package com.main.notsimulated

@Singleton
@EJB(name = "java:/sample/MainOne", beanInterface = MainOne.class)
public class MainOne {}

This ejb needs to be present for some other deployables to work. However, using this MainOne modue is not very feasable for me in a testing env. Instead, I would rather inject my own custom version at runtime.

package com.main.simulated

@Singleton
@EJB(name = "java:/sample/MainOne", beanInterface = MainOne.class)
public class MainOne {}

(Note, these are two different jar files)

Hence, my idea here is, let's try to replace the currently deployed with a custom version on the fly. The reason I want to do this is because I do not want to change the nonsimulated version at all, nor effect the consumers of the ejb in any way. i.e All that the consumer currently does is look for that particular jndi name, and performs an indejection and a casting to a particular interface.

I have looked at this post in hopes of figuring out if my MainOne Class from com.main.simulated can evict the currently instantiated MainOne class. However, the the selected answer states it is not programatically possible to start or stop an ejb. I have also looked at this post, but this is more of a practical guide as to how we can inject these beans inour calls.

Hence, my question is, can my latter implementation (com.main.simulated) somehow "replace" the other bean, and ensure the com.main.notsimulated version is never executed?

Community
  • 1
  • 1
angryip
  • 2,140
  • 5
  • 33
  • 67
  • Something similar to Spring's @Profile? – Andrew S Nov 23 '16 at 16:00
  • @AndrewS something like that could work. Without changing the base class form the nonsimluated, nor any of the clients, how could I empletement the simulated version to take profiles into consideration? – angryip Nov 23 '16 at 16:04

1 Answers1

0

Deploying two classes, with the same binding is obviously not possible. When trying to do so, one will get a binding exception. However, contrary to my original research, programatically binding a bean is entirely possible. Hence, the solution as to how one can "hijack" an old binding, and replace it with the new is as follows: (Note, replace the class names with what you need)

package com.main.simulated

@Startup
@Singleton
public class MainOne {

    @PostConstruct
    private void rebindClass() throws NamingException {
        final Context context = new InitialContext();
        context.rebind("java:/sample/MainOne", this);
    }

    // other methods that will be called

}

Three important things about this class are: Removal of the @EJB annotation, the @Startup annotation and the rebind of context. The @Startup ensures the @PostConstruct method gets called when our container loads our class. When this happens, the method rebinds a class for a value. Hence, this is the hijack location.

Hope this helps someone.

angryip
  • 2,140
  • 5
  • 33
  • 67