How does the Inprise Application Server, specifically the EJB Container, load classes?

From Support
Jump to: navigation, search
How does the Inprise Application Server, specifically the EJB Container, load classes?

When running IAS, there are three class loading policies regarding the loading of EJB jar files into a Container. These policies are reflected in the EJB properties you set via the Console:

  • jar: Separate classloader is used for each EJB jar file.
  • container: Single classloader is used for all EJBs hosted in the Container.
  • none: System classloader is used for all EJBs hosted in the Container.

When running the Container as standalone, there are three policies regarding the loading of EJB jar files into a Container:

  • Set -DEJBNoClassLoader ("no custom classloading"): All the classes the Container needs must be on the classpath. The Container simply uses the Java Virtural Machine's built-in classloader to load the classes. The limitations are as follows:
    • not being able to dynamically load/unload EJB jars into a running Container and,
    • all EJB jars to be loaded into the Container must be known and configured on the classpath before the Container is launched.
  • Set -DEJBOneClassLoader ("singleton custom classloader"): Classes packaged into the EJB jar file are all loaded using a Classloader defined by the EJB Container. Multiple EJB jar files:
    • All share the same classloader.
    • Have a single namespace for classes.
    • Most importantly, do not run into the now infamous ClassCastException when beanA in ejbJar1 invokes beanB from ejbJar2 when ejbJar1 and ejbJar2 are loaded in the same Container
    • Hot deploy features do not work perfectly because refreshing loaded classes is impossible.
  • The default is ("per jar classloader"): The Container uses a new classloader instance for every EJB jar file it loads. This gives the best functionality as far as dynamic loading/unloading of EJBs are concerned but runs into the limitations discussed above.

The ClassCastException will happen whenever calls are made via stubs that have been loaded using one classloader and the target object is in the same VM but loaded in another classloader. This occurs as an impasse between two things -- how Java works and how the Visibroker ORB optimizes intra-VM calls.

So, if a servlet and EJB are in the same server VM and the servlet calls the bean, then we will have a problem since servlets use their own classloader. You have to set EJBNoClassLoader for your Container to make this work.

When the same VM has a Container and a client, you run into the same problem where the looked up Home is loaded by the system classloader but the home implementation object was loaded using the EJB Container's classloader.

We have provided the above options to cater to all cases that users may need. Of course each has its limitation and one can argue why we do not just provide an option that always works. We are internally debating such a thing, but such an option may not have "visible" limitations like exceptions or limited hot deploy features but will have the insidious problem of a big performance hit -- basically it will give up much of the intra-VM smarts that you hoped to get in the first place by colocating beans. Somewhere we have to make engineering tradeoffs. Our view so far has been to surface the problem early in deployment by popping failures because you usually want the performance optimization. We think the solution is to set properties and specify a certain configuration.

Suggested model

The suggested model is as follows: The default (that is, per jar classloader) is used early in development when you are developing individual beans and constantly loading/unloading them. You test out the application with multiple cooperating beans across VMs and everything works like a charm.

Once that is done, you think about performance. Start partitioning communicating beans into the same VMs and hit ClassCast limitations with respect to optimized intra-VM calls. Use the EJBOneClassLoader to get around that. By this time you are not doing too much hot deploy and can live with "reload" limitations with this policy.

Finally, you have figured out the exact set of jars you want deployed to each Container in production and you have them placed on the classpath to get the best performance and no casting issues. Usually you do not "hot" deploy to production servers to avoid versioning issues.You tell the Container not to use its own classloader by setting EJBNoClassLoader policy.

 



Article originally contributed by Borland Developer Support