Search code examples
javajakarta-eestaticejb

Call Singleton EJB during initializing a static variable


I have a thread safe heavy resource and I would like to initialize this as a static class variable. During initializing this object I need to read some "connection" parameters from external property file.

To read the init parameters I would like to use my exicting Configuration Singleton EJB but it seems that my injected configuration bean is null at deployment time (when EE container initializes my static variable).

This is my Configuration EJB:

@Startup
@Singleton
@LocalBean
public class Configuration {

    @Lock(LockType.READ)
    public String getValue(String key) {
        return ...;
    }
}

This is the way how I would like to initialize my HeavyObject:

@Stateless
public class SenderBean {

    private static HeavyObject something;

    @Inject
    private Configuration configuration;

    public SendNotificationBean()  {
        String host = configuration.getValue("....");
        String port= configuration.getValue("....");

        something = new HeavyObject(host, port);
    }
}

But configuration is null:

Caused By: java.lang.NullPointerException
        at com.aaa.bbb.business.SenderBean.configureProxy(SenderBean.java:187)

Maybe I need to change the order how container initializes EJB-s?


Solution

  • It will not work since the container calls the default constructor before it injects anything. There is an annotation @PostConstruct for that.

    To get around this I would also make HeavyObject a singleton bean and inject Configuration in it. Something like:

    @Singleton
    public class HeavyObject {
    
        @Inject
        private Configuration conf;
    
        @PostConstruct
        private void configure() {
            // make something with the conf
        }
    
    }
    

    and inject it:

    @Stateless
    public class SenderBean {
    
        @Inject
        private HeavyObject ho;
        ...
    }
    

    Of course this is just only one way to do it but I would recommend to avoid static stuff in beans and think carefully what is in the beans responsibility. That is why I have put the @PostConstruct configuration logic to HeavyObject singleton instead of running it on the SenderBean.

    Nothing still hinders you to inject Configuration to SenderBean also if there is use for that.