0

Would like to find out whether we can call Stateless Ejb in class static block to retrieve data from database, the code as captured below ? Thanks.

public class MyCacheManager {

    private static final HashMap states = new HashMap();
    //Can we inject stateless ejb here ?

    public static String getState(String abbrev) {
        return (String) states.get(abbrev);
    }

    static {
        // can we call stateless ejb method here to retrieve data from 
        database ?
        //JDBC stuff to load the data
    }
}

Updated Comment

Instead of using static block, I have decided to use Singleton class, as understand singleton is suitable to store information, while static block usually used to create common functions.

Due to certain reason, I need to use POJO to implement the Singleton pattern with JDK 6 now, to store the static hashmap, instead of using Singleton EJB. The program call flow and structure as per below, thus would like to get advice whether it is technically feasible, including below queries ? Thanks, Leanne.

1) ServletContextListener class to instantiate below Singleton POJO using MySingleton.getInstance() method ?

2) Singleton Class injected with Session EJB to call DAO to populate the static hashmap using @Inject with CDI beans.xml ?

3) All the EJBs to call the public method of singleton Pojo to access the static hashmap using MySingleton.getInstance().authenticateLogin syntax?

4) What is the different if I use "final class MySingleton" or without final ?

package org.common.authenticate;

public final class MySingleton {
    private static MySingleton instance;
    private HashMap<String, AuthenInfo> authenInfo;

    // Inject EJB to call DAO for retrieving authentication information?
    @Inject
    private MyAuthenticateEjb myAuthenticateEjb; 

    private MySingleton() {
       // Use above MyAuthenticateEjb to retrieve authenticate info and 
       // populate the HashMap authenInfo
    }

    public static MySingleton getInstance() 
    {
        if (instance == null) {
            instance = new MySingleton();
        }
        return instance;
    }

    public Boolean authenticateLogin(String userNm, String pwd, String 
           apiName) {
           // use above authenInfo HashMap to authenticate whether system is
           // authorised to the call API
    }
}
Leanne
  • 127
  • 1
  • 2
  • 12
  • Check comment help for using `@` in the comments, you need to format it as code when it is code. plain "at sign + username" is to address msg to a specific user and just one user. So how do you plan to use EJBs with JDK5? – pirho Jan 21 '19 at 17:47
  • @pirho, Thanks for your comment. I have included my comment, appreciate the advice here. Leanne. – Leanne Jan 22 '19 at 08:59
  • Please have a look at [MCVE instructions](https://stackoverflow.com/help/mcve). It makes question unnecessary broad if you first update your original question and then ask 4 a bit separate things. To have Q/A useful for others also it is better to ask a new well prepared question per different question instead of adding those to the original question. But nothing hinders you to refer to this original question if you keep in mind that your any new question qualifies MCVE. Also you have [tag:EJB] but you plan to use it on `JDK 6`? You need [tag:J2EE] right? – pirho Jan 27 '19 at 15:02
  • @pirho hi, am i right that i need to remove above 4 queries and post it in separate question ? Yes, i need to use jdk 6 and ejb 3.1. Thanks – Leanne Jan 28 '19 at 07:56

1 Answers1

2

I'm afraid not. The static block is executed - at the latest - one and only one time before the very first constructor call. On the other hand injections take place after the instance constructor has been executed.

And also if you were thinking about to make the injected field static see this. It is not allowed. The point of @Stateless (or for example @Singleton) is that the container takes care of the "static" nature of bean.

But essentially: ýou would try to use instance variable from static context.

What might help you in your problem would be @PostConstruct. See more information why.

Note also if using instance initializer (so not with static) like:

{
    // can we call stateless ejb method here to retrieve data from 
}

it would also be called before constructor.

Yet if injecting is not the requirement you could try to make a JNDI search in your static block. However depending on the phase static block is executed it might result into unpredictable results - if it even works, not sure - and thus not recommended.

Usually whenever you need to have that kind of static access you would create a bean like:

@Startup // make init eagerly
@Singleton
public class StaticHelperBean  {

    @Inject 
    private SomeBean someBeanInstance;

    @Getter
    private static SomeBean someBean;

    @Getter
    private static SomeStuff someStuff;

    @PostConstruct
    private void postConstruct {
        someBean = someBeanInstance;
        someStuff = someStuffInit();
    }
}

But this is the last resort. You should always first try to design your software so that you can inject stateless bean wherever you need it.

pirho
  • 11,565
  • 12
  • 43
  • 70
  • 1
    I would add that static blocks such as this can make writing unit tests unnecessarily difficult. – Steve C Jan 27 '19 at 05:06
  • Yes,a good point also. There is a need for extra caution depending on how mocking is done. – pirho Jan 27 '19 at 14:54