• Post Reply Bookmark Topic Watch Topic
  • New Topic

EJB Homes, InitialContextInstances and the Evil Genius  RSS feed

 
Joe Ess
Bartender
Posts: 9406
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I maintain a large application codebase and sometimes I can't decide if the guy who authored it (not me ) was a genius or a moron (maybe an evil genius).
Case in point: There's only one InitialContext instance for the entire code base. It's wrapped in your Standard Singelton Class and all the other classes use this single instance to get a Context instance. Where this has bitten me is when I moved our application off of RDBMS authentication to use an LDAP database. The context for accessing the LDAP has different credentials than this static instance and if the LDAP instance wasn't close()d, his credentials would somehow replace the other instance, effectively changing the principal returned by SessionContext.getCallerPrincipal() (not my sloppy coding, it was the BEA consultant!).
Another case: Whenever an EJB uses another EJB, the home instance of the accessed EJB is stored as an instance variable in the first EJB. There is also a home instance singelton, which stores a single home instance for each EJB as a static variable and provides static methods to obtain them.
It may be that I'm just more comfortable with the Servlet lifecycle, where most everything has a request-level life cycle, but I'm inclined to get rid of these singletons and start creating context instances and home instances where they are needed and disposing of them after they are used. Most all the documentation on things like Context and EJBHome are concerned with just getting the things, not with the proper management of them as resources. Can anyone weigh in with their experience?
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Joe,
As far as I know, it's still fairly standard to cache EJB Home instances as the lookup time is relatively expensive. This doesn't translate to having an Initial Context singleton though.
 
Mark Spritzler
ranger
Sheriff
Posts: 17309
11
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
the home instance of the accessed EJB is stored as an instance variable in the first EJB.


While you might have cache of home interfaces. Sometimes I have seen people store the Session object or Session information in a Stateless Session Bean, and this is very wrong.

Personally, I don't think storing the Context is a good idea, since the context is so readily available already. And like you say the values sound like they are "hard coded" in the Singleton, which make sit hard to change.

Mark
 
Reid M. Pinchback
Ranch Hand
Posts: 775
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In local JNDI trees there is probably little reason to store a context, but for JNDI providers outside the JVM, getting a context can be extremely expensive, so caching isn't so surprising. You have to be careful though, how many different places you cache it; it could be more of a resource load than you'd expect (like graphic contexts in AWT).
 
Reid M. Pinchback
Ranch Hand
Posts: 775
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Joe Ess:
There is also a home instance singelton, which stores a single home instance for each EJB as a static variable and provides static methods to obtain them.


If I understand you correctly, static (class level) mutable variables are holding references to EJB homes, and these statics, either directly or indirectly are used to provide values to EJB instances? That is insane and clearly violates the EJB spec.

It also shows that there were some aspects of the component model the previous developer hadn't twigged to yet, like the fact that beans and webapps get resources like EJBHomes/EJBLocalHomes via the ENC (environment naming context) for a reason. Just because you have a reference to *a* EJBHome/EJBLocalHome implementation doesn't mean that every other bean has to use the *same* implementation. Much like how Spring bean factories work, the ENC provides a deployment-time dependency injection mechanism for J2EE apps that allows you to alter implementations, transaction settings, security settings, etc.

Caching mutable static references to anything in EJB is undesirable and a spec violation, although some libraries do it internally and so it can be hard to completely avoid, but to do it with EJB interfaces is just plain broken and completely avoidable.
 
Joe Ess
Bartender
Posts: 9406
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jeanne Boyarsky:
Joe,
As far as I know, it's still fairly standard to cache EJB Home instances as the lookup time is relatively expensive. This doesn't translate to having an Initial Context singleton though.


So the context-ejb relationship is not like, say, a database connection and result set. I can safely dispose of the context and keep my home instances?

Originally posted by Mark Spritzler:

While you might have cache of home interfaces. Sometimes I have seen people store the Session object or Session information in a Stateless Session Bean, and this is very wrong.


I've worked with EJB's enough to know this, but I was wondering if the same is true with home instances.
By the way, all this caching certainly isn't for performance purposes. This application, while large, is low volume.

Originally posted by Reid M. Pinchback:

If I understand you correctly, static (class level) mutable variables are holding references to EJB homes, and these statics, either directly or indirectly are used to provide values to EJB instances? That is insane and clearly violates the EJB spec.

There's a ServiceHome object. He creates a home instance for each EJB's. If you needed, say, a User EJB representing a particular user, you'd call ServiceHome.getUserHome() to get the home instance and use that UserHome instance to do a userHome.findUserById(). I think that's fairly common usage. I'm just felt uncomfortable with the persistence of the Home instances.
 
Reid M. Pinchback
Ranch Hand
Posts: 775
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Joe Ess:
There's a ServiceHome object. He creates a home instance for each EJB's. If you needed, say, a User EJB representing a particular user, you'd call ServiceHome.getUserHome() to get the home instance and use that UserHome instance to do a userHome.findUserById(). I think that's fairly common usage. I'm just felt uncomfortable with the persistence of the Home instances.


If they are *instance* variables that are being cached then yes that is a reasonable and common practice for improving performance. If they are *static* variables, then it is a bad practice and violates the spec for substantive reasons (like thread safety).
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way, all this caching certainly isn't for performance purposes. This application, while large, is low volume.

So, what's the purpose of doing caching?
 
Joe Ess
Bartender
Posts: 9406
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Reid M. Pinchback:

If they are *instance* variables that are being cached then yes that is a reasonable and common practice for improving performance. If they are *static* variables, then it is a bad practice and violates the spec for substantive reasons (like thread safety).


Well, the home references are declared as instance variables in the EJB's. However, there's only one instance of each home, because they're static in the ServiceHome object. Should there be a unique instance for each home for each instance of an EJB? That wouldn't be difficult to change.

Originally posted by Roger Chung-Wee:

So, what's the purpose of doing caching?



Like I said, I can't decide if the guy who designed this thing was a genius or a moron. There's a number of features which were overdesigned, contributing dozens of classes where a handful would suffice.
 
Reid M. Pinchback
Ranch Hand
Posts: 775
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Joe Ess:
Should there be a unique instance for each home for each instance of an EJB? That wouldn't be difficult to change.


Yes. Each bean is responsible for getting its own home (proxy) references, with the recommended idiom being that the home bindings are provided in each EJB via its ENC (in other words, the deployment descriptor tells you what the bindings are).

The spec says when it is safe to do JNDI lookups; if I recall, I think you can always cache the homes as earl as the set*Context callbacks. Good time to do it for homes you know you will always use, otherwise you can just wait until the first time you have need for a home, and cache it then. The only thing you should be careful of is to not try and use methods on the home any earlier than the spec says you should (for example, creating and using beans from that home typically has to wait until later callbacks or business methods).
 
Jeanne Boyarsky
author & internet detective
Sheriff
Posts: 36393
453
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Joe Ess:
So the context-ejb relationship is not like, say, a database connection and result set. I can safely dispose of the context and keep my home instances?

Yes. The context is really just one object that you are getting a reference too. You aren't actually disposing of it. And even if you did, the objects in it would still exist since your code would have a reference to it.

The database connection creates a result set. The context just holds an EJB home interface. It doesn't create it.
 
Joe Ess
Bartender
Posts: 9406
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the feedback, everyone.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!