0

According to EJB specs, non final static fields are not allowed. Is this still the case for an EJB 3.1 stateless session bean defined as singleton?

Just to make things clearer and to prevent question like why you want to do it:

I have a situation where I need an EJB to start working on server start-up ,do some DB related work and only when it is done it will signal all other components in the system that they can start their work.

This EJB will also be defined with timer, so it will start every few minutes and thus, if it failed the first time it will try again until it succeeds, or until someone notices there is a problem. Once succeeded, the flag will be changed and all other components (timer EJB's) can kick in.

So I have a Singleton EJB and I need it to hold a static (global) flag that all other components/EJBs can refer to.

Tomer
  • 17,787
  • 15
  • 78
  • 137
  • 4
    Adding a static variable to a singleton makes no sense - only one exists in the system, so why would you need shared state? Also, the whole point of stateless session beans is *not* to have state, so they can be pooled and reused more easily.. So why would you make a stateless session bean a singleton? And why would you add (global, to make things worse) state to it? – weltraumpirat May 21 '12 at 08:42

2 Answers2

1

Non-final static fields are still prohibited as you'll run into problems as soon as you try to cluster your application. EJB singletons are only singletons on the server instance they are running on. If you have two server instances you could have two versions of the singleton with different values in your static field.

If you need a global flag, better to store it in the database.

Nick Wilson
  • 4,959
  • 29
  • 42
  • My application is not clustered and not planning to be clustered any time soon, so in that case there shouldn't be a problem, right? I thought about saving it to DB, but then every time a components asks if it can start, I need to check in DB and that is a lot of extra traffic. – Tomer May 21 '12 at 11:22
  • It would work as long as the class defining the static doesn't get garbage collected (unlikely), but there are other things to consider. Is the initialisation a one-off, i.e. do you want the flag to survive a server restart? If so the DB would still be better. There's no reason you can't cache the flag to prevent too many DB hits. – Nick Wilson May 21 '12 at 12:33
  • The installation is basically a one-off, but even if the server is restarted, the EJB will identify there are no rows in the table (as they were deleted the first time it ran) and will set the flag to true. – Tomer May 21 '12 at 12:54
  • @NickWilson Singleton state is already per-JVM, so I don't think "differing static values across a cluster" is a compelling answer. – Brett Kail May 21 '12 at 21:31
0

Note that a class is one-to-many with a singleton EJB definition. In other words:

<session>
  <ejb-name>TestA</ejb-name>
  <ejb-class>org.example.SingletonBean</ejb-class>
</session>
<session>
  <ejb-name>TestB</ejb-name>
  <ejb-class>org.example.SingletonBean</ejb-class>
</session>

In this example, there will be multiple instances of the SingletonBean class, one for the TestA EJB and another for the TestB EJB. Given this use case and the propensity for the EJB programming model to try to protect the programmer (for better or worse), it seems reasonable to keep the restriction on static fields.

Given that the container is managing the single instance of the singleton EJB, you might as well store your global state as an instance variable in the singleton anyway. Inject the singleton into your other beans, and they can all access the shared state through member variables. That's the point of singleton EJBs anyway.

Brett Kail
  • 33,593
  • 2
  • 85
  • 90