Discussions

EJB design: EJB Handle

  1. EJB Handle (18 messages)

    I want to store the handle to my state full session bean in the LDAP, so I can always access the same session bean. This session bean is meant to be a single source responsible to compile information about my application in its internal hashtable.

    Anyone sees any problem with this approach, where it may not work ?

    Thanks in advance.

    Threaded Messages (18)

  2. EJB Handle[ Go to top ]

    I see two major concerns:

    1. Session beans are ment to serve one client and one client only. This is reflected in the spec in several aspects. One of the important problems is that a concurrent call will not only be unable to proceed (session beans are single-threaded), it may even throw an exception. App servers may choose to queue concurrent method calls, but they do not have to.

    2. If not accessed for a long duration, the session bean will eventually be destroyed. First, it will be passivated. But the App server will eventually delete the passivated instance. You may be able to configure your way around this for some App servers, but the solution won't be portable. A server crash may also cause problems.

    I suggest you think of storing the information in an LDAP service (or another directory service) or a database, and allow it to be accessed through an entity bean or a stateless session bean.

    Gal
  3. EJB Handle[ Go to top ]

    Thanks Gal,

    Your comments were very helpful. It certainly addressed some of my concerns, however I am left with the following delima and it would be great if you could shedd some light:

    First I have to clearify my privous post in regard to the scope of the controller statefull session bean. The controller statefull session bean will maintian instances of an AuthorizationEJB (which are state full SB as well) in its internal hastable. We need to keep these AuthorizationEJBs in once place so if the user logs in to our application from two different http sessions, we can revoke one of them, therefore we iterate thru the hashtable to determine if the user has logged in already, if so revoke the existing AuthorizationEJB by calling home.remove() on it then create a new AuthorizationEJB and store it in the controller state full session bean's hashtable.

    Currently our application is Corba based and we are easily accomplishing this task. However we are migrating our app into J2EE/EJB but after reading your comments I am begining to beleive this perhaps can not be accomplished with J2EE/EJB technologies.

    Do you have any thoughts on how I can accomplish this authorization solution ?

    Thanks in advance.
  4. EJB Handle[ Go to top ]

    The reason your solution does not naturally fit into the J2EE/EJB model is that it has an inherent scalability problem. All the AuthorizationEJBs references have to be maintained in a single hashtable, meaning a single JVM. This isn't very fault tolerant. If that one box crashes the whole application is in a problematic state.
    If you want to achieve this solution (along with it's problems listed above) in EJB, probably the easiest way would be to have a stateless session bean that maintains the hashtable in a static field. This isn't exactly by the spec, but as long as you deploy this bean on one box only there shouldn't be a problem. Each client invocation would go through a seperate instance, but all will access the same hashtable.

    Probably a more stable solution would be to update the user record in the DB to reflect whether or not the user is currently logged in. That way you can check if a user is logged in from any box, and you don't have to depend on a single box. The downside of course is that database access is slower than updating a hashtable directly, but I doubt this would have noticable effects.

    By the way, what happens in your application if the user logs in in another HTTP session but the old session is still active? If you delete the old one using home.remove(...) the next time the old session tries to access the bean it would get a weird error like java.rmi.NoSuchObjectException. Is that what you want?

    Gal
  5. EJB Handle[ Go to top ]

    Thanks again Gal. You definitly have brought up a good point regarding the inherent scalability problem and fault tolerance.

    <Gal>
    If you want to achieve this solution....in EJB, probably the easiest way would be to have a stateless session bean that maintains the hashtable in a static field. .... as long as you deploy this bean on one box only there shouldn't be a problem. Each client invocation would go through a separate instance, but all will access the same hashtable.


    We are indeed deploying this app to only one box. Initally we looked at the state less ejb with static hashtable solution. The only concern was that the EJB container can potentially create instances of the state less EJB in more than one JVM and that would become problematic.

    <Gal>
    By the way, what happens in your application if the user logs in in another HTTP session but the old session is still active? If you delete the old one using home.remove(...) the next time the old session tries to access the bean it would get a weird error like java.rmi.NoSuchObjectException. Is that what you want?


    Yes this is precisely what we want to accomplish. The application will catches the exception and displays "Your authorization has revoked" to the user. We are doing this with CORBA version of the application.

    <Gal>
    Probably a more stable solution would be to update the user record in the DB to reflect whether or not the user is currently logged in. That way you can check if a user is logged in from any box, and you don't have to depend on a single box. The downside of course is that database access is slower than updating a hashtable directly, but I doubt this would have noticable effects


    We also looked at this option in the past. The only way this would work if we serialized the handle to AuthorizationEJB and store it in the DB or LDAP, then in cases where we need to revoke the user's authorization we would perform the home.remove() using the handle. Do you think any flaw in storing the serialized handle to DB or LDAP?

    Thanks.
  6. EJB Handle[ Go to top ]

    <Tony>
    We are indeed deploying this app to only one box. Initally we looked at the state less ejb with static hashtable solution. The only concern was that the EJB container can potentially create instances of the state less EJB in more than one JVM and that would become problematic.


    Indeed, there can be a problem if the App server loads the bean in several different VMs. On the other hand, I don't think I know any server that does this.

    <Tony>
    We also looked at this option in the past. The only way this would work if we serialized the handle to AuthorizationEJB and store it in the DB or LDAP, then in cases where we need to revoke the user's authorization we would perform the home.remove() using the handle. Do you think any flaw in storing the serialized handle to DB or LDAP?


    I can't see any problem with storing a handle in the DB (or LDAP, or wherever you store your user accounts).

    There is still the conceptual problem of session beans being designed to serve only one client. How do you intend to avoid concurrent calls to the AuthorizationEJB bean? For instance, what if while a user invokes it, a second user logs in with the same name and tries to remove it?

    Gal
  7. EJB Handle[ Go to top ]

    Gal,

    Thank you very much. Your inputs have been exceptionally helpful.

    <Gal>
    There is still the conceptual problem of session beans being designed to serve only one client. How do you intend to avoid concurrent calls to the AuthorizationEJB bean? For instance, what if while a user invokes it, a second user logs in with the same name and tries to remove it?


    Our controller stateless SB is going to create one AuthorizationEJB per user; the handle for the AuthorizationEJB will be serialized and stored in the DB along with the user id. I believe this approach will address all the concerns you had in terms of concurrency, scalability and fault tolerance.

    We will pay a small performance penalty to check each user against the database as they login but I believe the design will be more solid with less violation of the EJB spec.

    Thanks,
    Tony.
  8. EJB Handle[ Go to top ]

    I just want to be sure you are aware that you can't make concurrent calls to a stateful session bean. If one client has called some method of the statefull bean and while the method is running another client (logging in as the same user) tries to remove the bean, the results are unspecified by the EJB spec. The remove request may be queued, or it may fail with an exception. Are you aware of this?

    Gal
  9. EJB Handle[ Go to top ]

    Gal,

    We have address that issue in the design. There won't be any concurrent calls to the statefull session bean. Each user will have its own instance of AuthorizaionEJB. For instance when John login, he will get an instance of AuthorizationEJB which will be different than Jane's instance and so on.

    Thanks,
    Tony.
  10. EJB Handle[ Go to top ]

    You didn't understand my point. I asked what would happen if John logged in, invoked a method on the AuthorizationEJB, and then logged in again at the same time from a different computer. No Jane, two logins for the same user.

    Gal
  11. EJB Handle[ Go to top ]

    Gal,

    When John logs in from his httpSession he'll get an instance of AuthorizationEJB. Let's call this one the "instance1". John starts another httpSession and logs in again. The stateless SB controller will detect the "instance1" for John thus retrieves the handle and call home.remove() on "instance1", then create the "instance2" of AuthorizationEJB and stores its serialized handle in the DB.

    Hope this clarified your concern.

    Thanks,
    Tony.
  12. EJB Handle[ Go to top ]

    Maybe this will clarify the scenario I am describing:

    When John logs in from his httpSession he'll get an instance of AuthorizationEJB. Let's call this one the "instance1". John calls some method, "method1", on instance1.
    Concurrently, John starts another httpSession (say, from a different computer)and logs in again. The stateless SB controller will detect the "instance1" for John thus retrieves the handle and call home.remove() on "instance1". This call takes place while "method1" is till running, and thus cause unspecified results.

    Do you understand what I'm trying do describe?

    Gal
  13. EJB Handle[ Go to top ]

    Hi there,

    Your example clarified your point. From our application perspective it would be irrelevent what happens to the user at that point. The AuthorizationEJB only provides selector methods and therefore there are two scenarios can happen:

    1-John calls instance1.getxxx() and while this method is running the container removes instance1. John's httpSession either hangs or receives an exception.
    2-John calls instance1.getxxx(), method finish running and the container removes instance1. John will get an exception on his subsequent call to instance1.

    In either case a lesson learned for John to follow the documentation and not try to break the system.

    Please let me know what you think.

    Tony.
  14. EJB Handle[ Go to top ]

    <Tony>
    1-John calls instance1.getxxx() and while this method is running the container removes instance1. John's httpSession either hangs or receives an exception.
    2-John calls instance1.getxxx(), method finish running and the container removes instance1. John will get an exception on his subsequent call to instance1.


    Let's call the client/session/browser that calls instance1.getxxx() John1 and the client/session/browser that logs-in and tries to remove instance1 John2. In scenario 1, John2 will be the one to hang or fail with an exception. The session bean will not be removed. Are we clear on that?

    Gal
  15. EJB Handle[ Go to top ]

    <Gal>
    Let's call the client/session/browser that calls instance1.getxxx() John1 and the client/session/browser that logs-in and tries to remove instance1 John2. In scenario 1, John2 will be the one to hang or fail with an exception. The session bean will not be removed. Are we clear on that?



    Thanks, That's correct. In scenario1 John2 may fail. However our existing documentation states that if a user tries to login to the application from multiple sessions, the application will attempt to revoke all previous authentications and this may lead to unexpected results.

    At this point I am a little concern with storing the EJB handle to the DB; simply from the EJB life cycle perspective. I am thinking about changing the AuthorizationEJB to a regular serializable Java object and pass it to the client. I will have this object to call the controller for validity per use case operation. This approach will be more complient with the EJB Spec.

    Like to hear your thoughts.

    Thanks.
  16. EJB Handle[ Go to top ]

    I'm not sure I understand what exactly your concerns are with regard to storing an EJB handle in the DB. However, there are without a doubt many other options you can consider. I'm not sure exactly what you mean by "serializing a normal Java object". You can write some session identifier to the DB and check it whenever a call is made. This identifier can even be a random number generated at the beggining of the session.

    Gal
  17. EJB Handle[ Go to top ]

    <Gal>
    I'm not sure I understand what exactly your concerns are with regard to storing an EJB handle in the DB. However, there are without a doubt many other options you can consider.


    Here is my concerns in regard to EJB handle:

    Aside from the http users, there are external systems (We call them back end users) accessing our application using the API interface. There will be only one AuthorizationEJB per external system. If a given external system logs in 10 times simultanously, it will get the same AuthorizationEJB. They can connect to our application, obtain an AuthorizationEJB perform transactions for days with long periods of inactivities in between. If the container decides to passivate and remove their AuthorizationEJB after 38 hours of inacticity, it will break the use case requirement. These are internal systems to the company who are funding and defining requirements of our application.

    My alternative solution of using a plain java object will prevents the mishaps of EJB removal.

    <Gal>
    I'm not sure exactly what you mean by "serializing a normal Java object". You can write some session identifier to the DB and check it whenever a call is made. This identifier can even be a random number generated at the beggining of the session.



    The plain java object must implement the java.io.Serializable since it will be passed to the UI or back end clients across the network. Of course I was thinking to store the session id rather than a random number, cause it needs to be unique.

    Tony.
  18. EJB Handle[ Go to top ]

    <Tony>
    The plain java object must implement the java.io.Serializable since it will be passed to the UI or back end clients across the network. Of course I was thinking to store the session id rather than a random number, cause it needs to be unique.


    If you have an accessible session ID you can use it. If you use a random 128-bit random number, the chances of collision are much smaller than the chance of an asteroid hitting earth and destroying every living thing. And if that happens, you probably wouldn't care much about session collisions :)

    Gal
  19. EJB Handle[ Go to top ]

    <Gal>
    If you have an accessible session ID you can use it. If you use a random 128-bit random number, the chances of collision are much smaller than the chance of an asteroid hitting earth and destroying every living thing. And if that happens, you probably wouldn't care much about session collisions :)



    LOL, that's true, the session collision would be the least of my worries.

    Just out of curiosity since we have been talking on this thread for a while and you are somewhat familiar to this problem domain, does a better solution come to mind ?

    Thanks,
    Tony.