Consider the following (hugely simplified) scenario:
We have various clients accessing a server application. The clients are standalone Java Apps using Stateless Beans to communicate with the server. (However, there's a web app as well, but that's unrelevant now.) The server might be clustered. A client wants to know how many clients are connected to the server (not per server but per cluster).
Is the next design OK? Are there any flaws in it? Is there a better design? Any help/comments are appretiated.
The clients call Stateless Session Bean methods to get that info. In the static initializer of the SLSB we do a lookup of a Stateful Session Bean (is that possible?) that we later plan to use as a singleton. Store the JNDI handle in a static variable of the SLSB and use that handle to get the SFSB whenever it's needed to get the count. (We access the counter in the SFSB.)
-- We cannot use simply SFSB's 'cause they're bound to a client session and are instantiated for every client.
-- We cannot use simply static variables, for they're unique only inside a JVM or ClassLoader. Remember that the server could be clustered. The data should be shared between clustered server instances.
-- I don't really want to persist the counter data in any form to a DB, neither by Entity Beans nor by JDBC calls.
Hope this makes sense...
Is there a way to use a SFSB like that, without actually a calling client (one single client)? There's rumours around here that it's not possible. (I heard _that_ before a couple of times, though...) What will be the lifespan of that bean?
Thanks for your help.
If the connection count was needed in would add it to the database for the following reasons.
1) Simple solution that is easy to understand and document.
2) Querying for list of connected users would be easier in a database.
* Say down the road they want a list of users connected longer that X hours.
* Order by duration connected.
* Order by username
3) Easy to integrate by a third party.
Complex problem. And therefore my reply will be quite complex too :-(
First of all, it does not make that much sence (although it is possible) to call a stateful SB from a stateless one. Once you get stateless, it is impossible to re-establish state again. The stateless bean instances will get their own instance of the stateful bean.
The solution to let all stateless beans, and as a consequence many threads, use the same instance of the stateful bean is out of question. The EJB specification does not allow many client threads to access the same bean. This is explicitly illegal, and the behaviour of the container is therefore unspecified.
When it comes to the lookup of one bean from the static initializer of another bean, I am not 100 % sure about the behaviour. I have looked at the problem when working with Singletons, and I cannot find out from the EJB specification if static initializers have access to the initial context or not. From what I can see, it is undefined. And can you find a better reason for avoiding a solution in J2EE?
The database solution can be OK, but how do you handle timeouts? When is a client logged out? In the Web case, you don't really know if a client has closed the browser!
After all bad news, I simply don't know what solution I should propose. I suppose the application servers will not provide such informaltion (for security reasons). But take a look in the documentation of ask the vendor for help. It will be great if you can solve this issue outside your applicaltion code!
I think your container might provide some API to access the bean statistics. Please check your container documentation(In Weblogic you can see the active beans in the console, so there may be some API available with container level).
These statisics API are standardized in J2ee 1.4 and they are available in javax.management.j2ee.statistics this package.
Hope this help,