Re-using resources in stateless session beans

Discussions

J2EE patterns: Re-using resources in stateless session beans

  1. It is often overlooked that although stateless session beans cannot store conversational client related state, they can store client-independent state in member variables.

    It is extremely beneficial to performance if initialised resources are stored as member variables in stateless session beans, for reuse in other method calls and by other clients.

    For example, rather than initialise an HTTPConnection to an external resource in every method call, an HTTPConnection should be initialised once and stored as a member variable. In particluar if a proxy server and authentication is involved initialisation is an expensive activity.

    Lazy initialisation is recommended, so that unnecessary initialisation does not occur.

    The connection will be preserved in between activations and passivations and method calls.

    This approach has successfully improved the performance and efficiency of my stateless session beans.



    Threaded Messages (34)

  2. Charles, it is definitly beneficial to separate client (or data instance) specific resources from resources that can be shared across instances.

    Ed Roman talks about this very pattern on page 189 of Mastering EJB. He refers to these two types of resources as:

    1) Bean-Specific Resources
     - resources that tie a bean instance to a particular client (for session beans) or data instance (for entity beans).
     - references to particular entity bean instances are examples of member variables that are bean-specific

    2) Bean-independant Resources
     - resources that can be re-used across transactions, no matter what data instance your entity bean (or usecase your session bean) represents.
     - a good example of this is Home Object references, Factory-like objects, or references to stateless session beans.

        The most common thing to store in stateless session beans are the home objects of entity beans the session beans needs to interact with. Home objects are typically expensive to instantiate, thus caching them is a good idea.

    Floyd
  3. Consider resource pooling[ Go to top ]

    Resource pooling is an alternative to storing reusable resources as instance variables in stateless session beans. Typical examples of resource pooling provided by most appservers are database connection pools and thread pools. Similarly, you can create resource pools for other resources which are expensive to create and can be reused, for instance HTTPConnections.

    Resource pooling is capable of providing more control of resource usage than stateless session bean instance variables. Consider the case when a lot of beans are instantiated to handle high load situations. In this case, each bean will create its own resourc. In comparison, a resource pool could set a reasonable max threshold, controlling resource usage.
  4. Consider resource pooling[ Go to top ]

    Resource pooling was the first option we considered.

    We were unable to find a way of creating resource
    pools for arbitrary resources in weblogic (i.e
    it only seems possible to pool resources specifically
    catered for such as database connections.)

    It is our understanding that the Connector specification
    will address this deficiency, but in the mean time
    the method described is the best option.

    Which servers have you created arbitrary pools for
    and how?
  5. Consider resource pooling[ Go to top ]

    I have not created resource pools for specific application servers. However, you may create and use resource pools without tight application server integration. The pool can be a normal Java class, implemented as a Singleton or loaded during server startup (or any other way you prefer :)

    You may take a look at this this JavaWorld article to get an idea of a general, simple resource pool implementation.
  6. Consider resource pooling[ Go to top ]

    I can't see how this would work in an EJB container.

    You can't have read/write static fields (upon which
    singletons rely) in an EJB container. This is
    due to threading problems (you can't synchronise
    access within a container) and because EJB containers
    will contain multiple virtual machines and within
    a cluster you can make very few assumptions about what
    will happen ....

    Maybe I should have written a better description of the
    reasons for the solution proposed.

    rgds, C
  7. Consider resource pooling[ Go to top ]

    I agree that these arguments are valid from an EJB perspective. The EJB programming restrictions exists to ensure consistent behaviour and portable beans.

    However, you can still use these mechanisms from your beans, provided you understand the consequenses. If you use a Singleton to implement your resource pool, take into account in your design that several Singleton instances may exist if your appserver uses multiple JVMs. You can also design and implement your resource pool to work in a multiple JVM environment. In a clustered environment, it probably makes sense to have one resource pool instance per application server instance. In conqlusion: Most solutions have pros and cons, pick the solution that is best suited to satisfy your requirements :)
  8. Consider resource pooling[ Go to top ]

    I agree that some sort of solution could be constructed,
    however as the relationship between containers
    and JVMs in under-specified you may
    run into difficulties. My instinct would be that a solution along resource pool lines may therefore become quite complex. Putting a resource pool outside the container
    would result in lots of remote calls and you would
    lose the performance benefits.

    Storing a resource as a member variable, although
    not the only solution, is simple, scalable and
    effective.

    Let me know if you ever try implementing a generic
    resource pool in an EJB environment, as this would
    be of interest to many people.

    rgds. C
  9. Consider resource pooling[ Go to top ]

    I was able to produce a Resource Adapter for a generic HTTPConnection. Looks like JCA Container in JBOSS is doing its thing pretty good. I got 20 times faster overall performance in comparison with saving the HTTPConnection in Stateless Session Bean instance variable.

    Looks, like it is not a big deal to do the same with whatever connection you are forced to deal with (TCP or whatever).

    cheers,

    Serguei Bakhteiarov
  10. Consider resource pooling[ Go to top ]

    I would like to know more about the consequences of stateless session bean accessing an ordinary java object. This java object is not an Entity Bean. I need to use this java object as a wrapper/helper to access the 3rd party API that I want to encapsulate within my app. Since, the 3rd party API uses local files for processing data, I need to provide a simple helper class to wrap this API as EJB specs doesn't allow accessing files directly.

    Session Facade-->OrdinaryJavaObject---->3rd Party API.

    I wanted to know if any one ever has implemented such solution and how are the issues such as scalability, performance, synchronization etc handled ?
    For e.g if there are 20 stateless session beans all trying to access this wrapper, how would the synchronization etc be handled ?
  11. Consider resource pooling[ Go to top ]

    There are few ways to do that.
    There is my favorite one though, - it is a canonical example of JCA adapter for the file system.

    This is really scalable solution of the common problem, - accessing file system from within EJB container.

    JBOSS has an example code for the File System JCA adapter, please have a look and you will not regret.

    cheers,

    Serguei Bakhteiarov
  12. just as a flip side - consider the following with stateful ejbs. declare variables that you want to stick around for any client usage as transient (i.e., never passivated/activated - such as, maybe, a sales tax table in a shopping cart....) since with stateful ejbs the ejbCreate() method gets called for each client's usage of the ejb - initialize the transient data in the ctor (spec doesn't disallow this specifically :) ) or lazily(!) in ejbCreate() - since ejbCreate() could be called thousands of times during the life of the ejb.

    when doing stuff like this, initializing transient data in stateful ejbs or variables in stateless ejbs, especially if the initialization costs are high for initializing this data, make sure you're pooling ejbs correctly - that your server isn't constructing / destructing ejbs voraciously!
  13. Hi Keith,

    Not to nitpick, but actually ejbCreate() is only called once for a stateless session bean instance. Although slsbHome.create() is called to get each remote reference, this does not correspond to an ejbCreate() on the beans. The container just pulls an instance out of the pool to serve the request.
  14. hi
    i wanted to make a socket connection in my stateless session bean with the help of a support (helper)class
    i would like to have a socket pool created for this purpose. Is this advisable? If Yes, How do i do it?
    My worry is that if i create a pool of sockets the socket connection might time out how do i monitor this?
  15. Hi
       This is regarding the Re-using in statless session beans
    As you said we can use member variables to store resources that are common to all clients but after one method call
    the statless session bean instance dies then how the stored resources in member variable will be used by other method calls? please clarify my doupt?

  16.   Ramasubramanian Balasubramanian said:
      
      As you said we can use member variables to store resources that are common to all clients but after one method call the statless session bean instance dies then how the stored resources in member variable will be used by other method calls? please clarify my doupt?

    -----------

      My response:

      Stateless session beans are usually only destroyed after a timeout period (although they can be destroyed for other reasons too, for example, to conserve memory). The whole point of a stateless session bean is that it can be shared amongst many clients. If a stateless session bean were created and destroyed upon every single call by any client, it would defeat the entire purpose. If you are observing this behavior in your own application, you probably have the deployment descriptors for your beans configured for extremely small timeout periods, for example, 1 second. This should generally be a much higher value.

    God bless,
    -Toby
  17. Thanks a lot Toby realy blessed.
    Another basic doupt How to intialize the member variables of a stateless session beans(because we cannot pass arguments to ejbCreate() method of stateless session bean).
    Advance thanks
    Rama

  18. Ramasubramanian Balasubramanian said:

    Thanks a lot Toby realy blessed.
    Another basic doupt How to intialize the member variables of a stateless session beans(because we cannot pass arguments to ejbCreate() method of stateless session bean).
    Advance thanks
    Rama

    ---------

    My reply:

      Generally speaking, you shouldn't need information from any client to initialize the member variables which are your SSB (stateless session bean) resources. This is because those resources aren't associated with any particular client (make sense?).

      For example, your SSB might make use of other EJBs. In that case it could lookup the home interfaces for those EJB's in it's ejbCreate method and store them away to avoid having to make JNDI lookups during every client invocation.

    God bless,
    -Toby Reyelts
  19. Ramasubramanian,

    If you were initializing members of your SSB based on arguments from your client, you'd essentially be holding client state, wouldn't you?

    The kind of members you want in your SSB are things like handles to other EJB's, or maybe a connection to an LDAP server, etc... Things which are not client specific. Those things can be read from a global configuration, or even from the deployment descriptor if you so choose.

    God bless,
    -Toby Reyelts
  20. Hello there,
    Pl forgive me if I do not understand the Stateless Session Beans (I will call it SSB from now on). If you want to store some resources for all clients to use, I am not sure SSB is a good idea. My understanding is that SSB could be shared across multiple clients and the Server/Container has a pool of SSB instances of the Same bean. So I the container is servicing the 20 clients, using say 5 SSBs we could potentially have five references to resources (may be even 5 instances of precious resources). My belief is that, the instnace variables of the SSBs are not shared.

    What if we use a Entity Bean for this. Lets say we create a dummy table with only one column and row. And we store all the information, every client needs to share inside this bean (as transient), this approach could work right?

    Could somebody enlighten me please?

    Matt
  21. Matt,

    If it is an inexpensive resource (say a handle to another EJB), it's perfectly fine to stash it away as a member variable. If it's more expensive (say a connection to some sort of server), then you should pool the resource. For example, think about the way that JDBC connections are handled.

    God bless,
    -Toby Reyelts
  22. I am looking to store an XML document as a member variable providing for the reuse suggested. My question is what if I need to make changes to that XML document at some stage. Is there a way of removing existing instances of the session bean from the container so that I can start afresh?

  23. Michael Maram wrote:
    I am looking to store an XML document as a member variable providing for the reuse suggested. My question is what if I need to make changes to that XML document at some stage. Is there a way of removing existing instances of the session bean from the container so that I can start afresh?

    My Response:

    If you need to be able to change the value of the document, it shouldn't be stored as a member variable of a stateless session bean. Caching values in member variables of SLSB's is good for things like Home objects of EJB's you need to use, or other objects that are expensive to create and do not change.

    If you're going to need to change your XML document, maybe it would be better as an Entity EJB?
  24. Could you please elaborate on the that?! We are trying to do just that: Use an XML-file to store properties that are global to the whole application. We have a Session bean with only one Method .getProperty(String propertyName), which accesses an EntityBean which has a PrimaryKey that always returns true in the .equals(...)-Method. The EntityBean fetches the XML from disk in the load-Methods and serves subsequent calls from the parsed XML. Has anyone ever tried something like this?! It looks like some sort of Singleton-Pattern using EJB's - any other proposals on how to do this?!
  25. According to the EJB specification you shouldn't be accessing files from an EJB....
  26. What about reusing home interfaces of other beans as static member of a stateless bean.
    Could we have (safely) in a stateless bean something like:

    static SomeHome myhome = null;
    static {
     .... initialize my home, new context, lookup , etc.
    }

    and reuse this home reference at every bean instance:
    Enumeration e = myhome.findByAll();

    Does somebody see any problem here ?
    Is it considered fully safe ?
    What in a ejb cluster environment?
  27. Bledar,

       I am not sure if that approach is portable, as there is no guarantee that the InitialContext is setup properly for an EJB when it is first created, infact I am pretty sure it isn't.

       Therefor, to use your approach, you couldn't even access deployment descriptor entries, you would have to hardcode jndiname, url, and all those strings directly into your beans (which sucks compared to just doing: new InitialContext()).

    Floyd
  28. Can we use member variables in Stateless Session bean ?
    If not why ?
  29. Yes you can, as long as the data is not client specific. That is the whole idea behind this pattern.

  30. I am thinking of using a Stateless Session Bean as a place to store global information for an application. Some of them are actually what I would call "boring" entities. They would be awful to have as entity bean as the container would constantly be going to the database. Okay let me clarify:
    - Where and how can I cache StateProvinces and Countries?
    - I'm thinking of using a Stateless Session bean for that?
    - What do you think? Do you have a simple better solution?

    Thanks!

    Stephan
  31. These are typical codetables, read-only by nature. I would consider using read-only entity beans (if your container supports them), or simply use JDBC directly. You dont't need much transaction support, security etc anyway. Store them in memory as Singletons or SLSB static variables.
  32. I have a particular question related to reusing references to SSB remote objects:

    Is it better to keep a reference to a remote object of a SSB throughout the lief of a servlet, or instantiate a new one each time it is needed?

    For example, we could setup a remote object for a SSB in the init method of a servlet, then reuse it throughout the life of the servlet. The classes that are called by the servlet could use it as well.

    Or, we could setup a remote reference just before we need it, in each method where it is required?

    Does it matter? I know that the application server pools references. What are the implications to holding onto a remote object? Is holding onto references to remote objects bad or good?

    Thanks for any insight!
      Keith Elliott
  33. Iam having a situation where i have something similar.
    I have a set of objects which need to be accessed by all clients.Most of the time, its read only, but it can be updated as well. If i store it in ,lets say a static variable, what would happen in a clustered environment ?
    I will have one such variable per jvm. so if a client updates the SLSB, and it updates the static variable in one machine, will it synchronize with the remaining jvms. how stable is this behavior ? Also how is the synchronization of typical 'reader-writers' problem taken care ? Any help would be appreciated.
  34. Good[ Go to top ]

    Very good comment
  35. Hi Everybody,

    I am getting this error when running my application:

    An illegal attempt to use multiple resources that have only one-phase capability has occurred within a global transaction.

    I am using wsad 5.1.2, and connecting to 4 oracle datasources.

    I tried switching the JBDC driver class to oracle.jdbc.xa.client.OracleXADataSource.

    it works fine at the beginning, but after a while i am getting the following server error(wsad test environment)

    recoveryClasspath = D:\Program Files\IBM\WebSphere Studio\Application Developer\v5.1.2\runtimes\base_v51/lib/rsadapter.rar
    . The error code was XAER_RMERR. The exception stack trace follows: javax.transaction.xa.XAException
    at java.lang.Throwable.<init>(Throwable.java)
    at javax.transaction.xa.XAException.<init>(XAException.java:63)
    at oracle.jdbc.xa.OracleXAResource.recover(OracleXAResource.java:508)
    at com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl.recover(WSRdbXaResourceImpl.java:672)
    at com.ibm.ws.Transaction.JTA.XARminst.recover(XARminst.java:130)
    at com.ibm.ws.Transaction.JTA.XARecoveryData.recover(XARecoveryData.java:673)
    at com.ibm.ws.Transaction.JTA.RecoveryManager.resync(RecoveryManager.java:1415)
    at com.ibm.ws.Transaction.JTA.ResyncThread.run(RecoveryManager.java:1448)

    Can anyone give me some advice on this ?

    Thanks in advance!

    JJ