There have been frequent discussions on this site about the rule that says you shouldn't use statics in your EJBs. Most people interpret the spec to also mean that your bean should not access any mutable singleton, no matter which class it resides in or represents.
Also, there have been a few articles at Javaworld about how dangerous singletons are in a distributed environment or in a VM with multiple classloaders. It is difficult to guarantee that a singleton is in fact a singleton, especially in an EJB environment.
The proper way to use singletons, the experts say (e.g. Ed Roman), is to store your singleton in JNDI so that it can be managed appropriately by the J2EE container and so clients that need access don't have to care where the singleton resides.
Well, none of the articles, books or posts I've read discuss the one important issue: behavior-state dependency.
In other words, if a singleton's behavior does not depend on its state, then I see nothing wrong with letting multiple instances of a singleton exist that are directly accessed by the bean.
For example, a singleton object may lazily initialize its state or pool/cache objects for performance reasons. These activities involve state transitions that are encapsulated and hidden from the client such that they have no effect on the singleton's outward behavior.
If a client borrows an object from a pool, the client does not need to worry about the pool's internal mechanism for initializing or growing the pool. If a client performs a query on a singleton, the client does not care if the singleton caches the result for future queries. Any state changes that occur in the singleton are invisible to the client.
To clarify this concept even further, such a singleton is internally stateful but externally stateless.
This brings me to my next conclusion that a externally stateless singleton must also be externally immutable and logically equivalent to an immutable static final from a client perspective. Hence, I see no reason why these kinds of singletons violate the spirit of the spec.
Internally, mulitiple singleton instances might exist in multiple classloaders/VMs, but externally they seem like one singleton to any client that accesses them. This is similar to a stateless session bean. To the client, a stateless bean appears as one instance but internally the container pools a bunch of instances. The fact that multiple instances exist does not matter to the client.
Lastly, placing an externally stateless/immutable singleton into a JNDI tree would seem to defeat the purpose of many singletons that are designed purely to enhance performance. If you are using a singleton to pool or cache objects, you usually do not want a query on the singleton to traverse a network. The purpose of the singleton may actually be to avoid repeated network calls. So, putting these kinds of singletons in JNDI is wrong because JNDI may expose the possibility of a network call.
Anyway, I'd like to see what others think about this issue. I wish Sun would elaborate more on the spec and not keep it so unrealistically simplistic.
josuna at youcentric dot com
What you are describing is no singleton, as there is no single instance, instead you talk about (as you said yourself) a stateless bean.
Thus I'd use a stateless bean, as the server can instantiate it on demand, you have transactions, monitoring etc.
The "fact" that this means remote calls which are slow is just a myth, as all app servers (all that I know of, with exception of the J2EE RI, not sure about it) do no real remote call, but a local one (of course, there is still overhead for the tx-context etc., but not that much).
With EJB 2 this is taken into the standard with local interfaces, so the transition will be smooth.
So I see no reason for such a "singleton" as it is equivalent to an SSB, just that you will have to implement the pooling yourself, which often (always?) requires "synchronized" which can become quite dangerous in J2EE/EJB environments.
The motivation of Singleton is to have a truly single point of contact to an object. The motivation is not the fastest way to get to an object, it is to have a global creator and letting the class to manage its instance. Of cource there would be additonal overheads in implementing this.
I would agree with your premise that if (and only if) you have a logically stateless singleton, it will need to be externally immutable. This can be thought of as in the same terms as a read-only 'singleton' object, then. What I find hard to envision is teh need for such an object - one that transitions in state internally, but those changes do not affect external behavior (and hence the rest of the system) in any way. As far as the singleton pattern defining one and only one copy of an object, in java terms that equates to one copy of an object per specific class loader. One could argue that there is rarely such a thing as a singleton implementation, then, in java.
Should sun specify everything in the J2EE specs ? Perhaps. But we have to expect real-world experience to help us in determining what works well and what doesnt. Sun prohibit a number of things in an EJB container, and we have to rely on J2EE patterns to help us find a workaround. We are not there yet, but getting closer. The JNDI singleton solution works well for the need for a distributed singleton. The read-only singleton per class-loader works for implementing a read-only cache. The example you quote would probably work the same way as a read only cache, but would require careful thought to ensure the assumptions were truely correct for the specific design scenarios.
cday at acm dot org