Well, its that time again. Time to work on the next version of Java EE and that means EJB 3.1. Since the EJB 3.1 list is a private one, I intend to regularly converse with the community through this blog to tell you what’s going on and to obtain valuable feedback.
One new thing that is being circulated in the expert group is the idea of a singleton EJB much like what we already provide in JBoss EJB 3.0 implementation through @Service beans. Singleton EJBs would be a single EJB instance, created at boot-time, with the same functionality as stateless and stateful beans (remote, local, and web service interface, transactions, security, injection ,etc…)
Singletons and concurrency
There’s a couple of debates going on within the expert group on singletons and their concurrency with multiple invocations. Should only single-threaded singletons be allowed? Since servlets can either ben single or multi-threaded, seems reasonable to allow the same thing in EJB land. But, what do you think? If we support both models, what should be the default? Again, your feedback is needed!
Convenient concurrency
Another idea being proposed is to expand the concurrency model even further and provide convenience annotations over the java.util.concurrent library, for instance
@Singleton public class MyBean { @ReadOnly public int getStuff() {...} @Write public void setStuff(int i) {...} }
Basically the @ReadOnly and @Write annotations would manage a read-write lock that is implicitly associated with the single instance and managed by the EJB container.
So, if we’re gonna do basic concurrency, what about transactional concurrency as well? Should read/write locks be transactional as well? Held for the duration of a transaction?
If all this is gonna happen, how do we declare the default concurrency? Here’s one idea:
enum ConcurrencyMode { SINGLE_THREADED, MULTI_THREADED, READ_WRITE, // use a readwritelock, but read is the default access if no annotation provided WRITE_READ, // use a readwriteock, but write is the default access if no annotation is provided TRANSACTIONAL_READ_WRITE, // same as READ_WRITE but transactional TRANSACTION_WRITE_READ // same as WRITE_READ but transactional } @Singleton(concurrency=WRITE_READ) public class myBean {...}
Feedback needed
Any feedback in the comments section of this blog. Even a simple +1 or -1, or +1 on @Singleton, -1 on concurrency are all valuable feedback!
Sep 19, 2007 @ 20:42:06
+1 on @Singleton…please PLEASE make it very clear when these are initialized and when they are destroyed. Would this mechanism be the sort of thing that would finally replace the ServletContextListener-used-to-perform-EJB-initialization-activity hack?
Concurrency…haven’t thought about it frequently or deeply enough to really have an opinion. Gut feel: the fancy read/write stuff seems a little overkill; in general, try to make it line up with other annotations in use (at least in spirit if not in practice).
Thanks for soliciting public feedback on what is usually a very closed hush-hush process.
Best,
Laird
Sep 19, 2007 @ 20:53:21
@Singleton @PostConstruct/@PreDestroy is supposed to by used for bootstrapping and initialization. One of the intent is, I believe, to finally have a component that can be used to initialized/cleaup on server startup/shutdown.
Sep 19, 2007 @ 21:11:30
I don’t quite understand, what would be a use case for a single-threaded @Signleton? Maybe I take too much intuition from the current @Service, which is naturally multi-threaded. Or does that mean that each method is synchronized?
+1 of course on @Signleton, but shouldn’t concurrency management be left to the developers? Wouldn’t it be the only place in the EJB 3 specs that such annotations would appear?
Cheers,
Adam
Sep 19, 2007 @ 21:11:34
I’m not an expert in concurrency. However, I know that in the past the Java community has been upset at decisions EGs have made that limit how they can do something. Therefore I think it is best to support all options like in your last example:
@Singleton(concurrency=WRITE_READ)
public class myBean {…}
Will Singleton beans know when the application server is starting up and shutting down similarly to the ServletContextListener? I think that this is very important.
Sep 19, 2007 @ 21:13:28
Please ignore my last paragraph. I didn’t press the submit button until after the other two comments were posted.
Sep 19, 2007 @ 21:20:20
What’s the usecase for a single-threaded Servlet 🙂 Yeah, it means each method is synchronized.
Sep 19, 2007 @ 23:53:34
Glad to hear @Singleton is in the works; I use the JBoss @Service pretty heavily in my applications.
My vote would be for a default concurrency strategy of single-threaded, blocking; it’s the lowest common denominator. Let’s assume a developer doesn’t correctly identify the uses of his/her EJB, and sticks with the status quo. Isn’t it much better to result in a performance degradation (perhaps crippling) than the inconsistent behavior that could result from unintended multi-threaded access? Seems that if you’re intuitive enough to change the strategy than one could assume you’ve thought about the value selected.
Can you explain the difference between transactional and non-transactional locks? If the lock on the singleton instance is not obtained/released in tandem with the UserTx, what is triggering these events? The start/end of the method invocation on that object alone?
S,
ALR
Sep 20, 2007 @ 07:26:54
So, if a single-threaded singleton means that every method is synchronized, why not let the developer synchronize every method (if she/he wishes to), instead of introducing a new way to do so. Maybe it is a good idea to have annotations which cause every method to be synchronized, but I think they do not fit into EJB3 — but some other JSR.
You could really say the same about the rest of the concurrency modes. Keep it simple :).
Sep 20, 2007 @ 09:52:58
I can see use cases for that: data caches, statistics aggregators, work that must not be done in parallel (file operations for instance) etc. In my opinion it’s not necessary to have it as a stateful bean though. There are no use cases for stateful beans in the world in the first place, as all the state should be kept in the database. As for concurrency: existing Stateless beans are guarenteed to be called by only one thread at a time. So it’s safe to use instance variables. This is a gross difference to Servlets where one instance is shared by all requests and the use of instance variables is normally not possible. Transaction and security context are not affected by the question as they are thread-local anyway.
For the principle of least surprise, I suggest to make a singleton bean single-threaded by default. If the developer chooses to make it multi-threaded, he is aware of the concurrency problem. For scalability I discourage a default use of locks or synchronization. By default just leave it up to the implementation to synchronize access. The container should only provide additional synchronization that can not be achieved by the developer with the usual techniques. Transactional access: what exactly does that mean in this case?. And the more complex the specification, the less support we will see for it and the more implementation bugs. At the end of the day a buggy feature is a lot worse than a missing one.
Sep 20, 2007 @ 11:27:02
@Singleton is a great Idea. I think concurency can be managed through a strategy. I’d put 3 options :
– Synchronized (default)
– Unsynchronized
– ThrowingException
I’d put the synchronized strategy by default so that developer by default don’t have to care for threading issues.
Unsynchronized is essential to allow developers that know how to handle it to do whaterver is required
ThrowingException would be there just to mimic the (annoying) behaviour you have with stateful beans. Had so many problems with this one I managed not to use stateless beans anymore…
Bernard
Sep 20, 2007 @ 14:13:47
While I think having the singleton pattern would be great in EJB-land the one thing I’m worried about is how it would behave in a clustered environment? Unless you can map it into JBoss cache I’m guessing the developer would just have to know that @Singletion components are not clustered.
So until I find that out
-1
If it can be clustered
+1
Sep 20, 2007 @ 14:28:31
Jonathan, clustering has a few options I think. For instance, should there be only one singleton running in the cluster? For that HASingleton deployer would be useful with JBoss Cache holding the state.
So, it sounds like you want the spec to define concurrency?
Sep 20, 2007 @ 15:01:53
we are using the service bean from JBoss ejb3 implementation and we are very pleased with it. it would be great if this make its ways to to the next ejb spec.
Equally important is the master/worker pattern implemented diffrentlich by JBOSS, IBM and Bea
Sep 20, 2007 @ 19:05:41
One comment on @Singleton @PostConstruct: It should be mandatory that the container needs to construct the Singleton as part of the boot process. Otherwise we have no guarantee that we can do some initialization there. Then EJBs would have the equivalent of load-on-startup for servlets.
Sep 20, 2007 @ 19:57:33
+1 for singleton.
+1 for Transactional Read/write lock. Held it for a duration of a transaction would open some opportunity for specific usecase.
Sep 20, 2007 @ 20:14:18
re:clustering – what is the possibility that a @singleton could be declaratively marked as a HASingleton, rather than doing so via the deployer folder?
@Singleton(clusterNodes=ONE|ALL) or somesuch?
Sep 20, 2007 @ 20:20:42
Justin: what is the possibility that a @singleton could be declaratively marked as a HASingleton, rather than doing so via the deployer folder?
Feasible. Been on our plate but its been low priority :(. Contributors welcome!
Sep 20, 2007 @ 20:22:01
The intention is for @PostConstruct to be run at boottime, or have a new callback that could be used on other EJB/EE components.
Sep 20, 2007 @ 20:55:05
It’s a nice-to-have from a packaging standpoint. Did you mean this? Thats the best match I could find in five minutes.
In any case, +1 for @Singleton.
Sep 21, 2007 @ 11:42:24
Has anybody ever heard of reentrancy?
http://en.wikipedia.org/wiki/Reentrant
Why were stateless session beans pooled anyway? They’re stateless, right?
Sep 23, 2007 @ 11:36:21
+1 on transactional (two-phase) locking. It’s probably too much to ask for type specific concurrency control too, I suppose?
Sep 24, 2007 @ 06:06:00
I’m pretty sick of seeing developers using the “Singleton” pattern in code, since they usually don’t know what the fuck they’re doing. So -1 on @Singleton, just for that reason. And if there’s going to be multiple instances in a cluster, then we’re no longer talking about them being single instance.
So, I’d rather see them referred to as services, and use a name like @Service instead. Or, something to indicate they are directly instantiated by the container deployment, like @Deployment or @Deployed or something.
And by default make the calls serialized, and if the user wants to override, allow @Reentrant or something to mark the the class thread safe. Keep it simple.
Annotations for concurrency control, if created, should really be generalized as part of the Java standard.
Sep 24, 2007 @ 14:07:24
Hey, I like the last comment (Elias). Agreed, upon further thought, that it isn’t really the Singleton nature that’s at issue here, it’s more the…the…SharedResource-ness? Elias, I’m not so sure it’s really a Service, per se; maybe there’s a better word.
Sep 24, 2007 @ 14:23:26
The singleton may not be a service. It may just be an “initialization” object that, for example, pre-populates JPA’s global cache, or provides a bridge for a framework developer. There’s still debate in the eg on whether singeltons should be allowed to be initialization objects (and have a different component for this like servlet listers), but that will be a topic for another blog.
Sep 24, 2007 @ 15:48:44
I think it is a good idea to have a @Singleton ( I don’t mind the name of it)
But please make concurrency semantics very explict. Don’t leave that to the container implementor.
I guess explicitly specifying it via annotation with the sensible default of single threaded (as principle of least surprise) is best.
And yes allow those singletons to be started before other “regular” EJBS so that they really can be used to ‘bootstrap’ the enterprise part. I don’t like the @PostConstruct annotation here, as it has a different semantic.
Also make it very clear if such a service can access other EJBs when it is initially called (do we need two initialization phases?)
Sep 26, 2007 @ 09:46:05
I think there are 2 aspects to this – initialisation (a la ‘startup’ servlet approach) and shared state maintenance (a la ‘stuff it in the DB’).
I would vote for both – they are entirely different use cases.
@Startup – run once and forget : single ‘onStartup’ method called at a specific point in the container lifecycle
@Service – singleton with maintained state as per the JBoss one : I certainly vote for a single ‘view’ of a Service bean across a cluster … but in that case it’s the state that’s important – there could be many instances of the class itself. My use case here would be a simple cache – but I also see a need for shared state across many MDB’s running in parallel. Note that a service bean could be instantiated after startup – and thus have available the other beans it might need.
Sep 27, 2007 @ 01:40:15
+1 SLSB instance pools blow.
Sep 27, 2007 @ 05:19:22
-1 Singleton sb.
I prefer a facade slsb delegating through to a pojo singleton with the facade slsb statically referencing the singleton. The pojo singleton uses synchronize (the java language rather than introducing an alias annotation to the EJB) as necessary. When newer and better K EE 10 comes along, I can easily replace facade EJBs with whatever the K server requires. Or, I can re-use the pojo singleton in both J EE 5 and ESB in the same architecture.
But, I’m still wondering why I find the Timer EJB so useful (it is a singleton?) – or was the Timer EJB simply misnamed and forced into an EJB construct when it might better have been a service bean?
Oct 01, 2007 @ 16:21:43
@Steven: Unlike Servlets a SLSB doesn’t need to be reentrant, and I quite like that. They are stateless in the sense that the caller must not rely on state being preserved between method calls as consecutive calls may go to different instances. You can still use instance variables in a SLSB (for example to hold state during private method calls without passing it through method parameters) and it’s still thread-safe.
Jan 24, 2008 @ 15:11:04
Three different concerns here:
1- Activation timing
2- Concurrency
3- Instance count
I wouldn’t use a term such as Singleton to cover the three.
May 07, 2008 @ 22:16:09
I realize that its a bit late (to say the least), but…
Please let there be an easy way to create a cluster-wide singleton with an annotation! In fact, I’d love to see the cluster mindset change a little bit. Let’s face it, few people are using EJB to create simple throwaway apps that will never run clustered. Many of them may not grow to that point, but anyone intentionally writing a low-use app is unlikely to use an environment such as EJB in which to do it.
Having an easy way to create a cluster-wide singleton without having to worry about cache access issues, the risk of creating two objects and destroying one if there’s a cache race (generally not a big deal, but something you have to deal with anyway), etc, would be wonderful. Sure, it can be done without it, but one of the massive wins in EJB3 has been taking concepts that were difficult and handling them with a single annotation so the developer doesn’t have to risk the “enter everything correctly and get your desired behavior; miss one thing and encounter weirdness” behavior we all grew to hate with EJB2…
Jan 20, 2009 @ 22:03:53
So what transpired of this? Is this in the 3.1 release, and can you brief the behavior of the singleton in the clustered environment. Does the implementation allow only one cluster-wide instance with data shared in Jboss cache?? Thanks