ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

EJB 2 and J2EE Packaging, Part II
Pages: 1, 2

In order for Web applications to make use of EJBs deployed in the same EAR file, the Web applications need to have visibility to the external interfaces and stub implementation classes of those EJBs. Since the EJB and Web application classloaders are siblings in this scenario, the Web applications do not have direct visibility to the right class files. So to solve this problem, the EJB classloader can take all of the public interfaces of each of the EJBs and their stub implementation files and "export" them to the EAR classloader where they'll be visible by all applications in the EAR. The Web applications will then be able to readily load the classes needed to use any EJB.

Additionally, dependency utility libraries can be loaded in different places based upon where the library is specified. If a single Web application lists a dependency library in its WEB-INF\lib directory, then that library is unique to that Web application. There is no need for other applications to access the contents of that library and it should not be loaded by the EAR classloader. In this situation, the Web application custom classloader will load the utility JAR file. Other Web applications can include the same dependency in their own WEB-INF\lib to maintain this isolation.

For dependency utility libraries that must be shared between EJB and Web applications, those libraries need to be loaded at the EAR classloader. It turns out that any library specified in the manifest Class-Path: entry of an EJB will be loaded by an EAR classloader to give the right visibility to those classes. This allows an EJB developer to package any common exception classes and custom input parameter classes that are visible to a Web application and the EJB into a common.jar file that is placed in the manifest Class-Path:. In addition to the public interfaces and stub implementation classes, the common.jar file will also be loaded at the EAR level, allowing a Web application to have visibility to all of the classes used by the EJB.

The Post-EJB 2.0 PFD2 Option

The EJB 2.0 Public Final Draft 2 introduced the concept of local interfaces and put an interesting twist into the EAR classloading problem. With local interfaces, co-located clients and EJBs can be accessed using pass-by-reference semantics instead of pass-by-value semantics. In order for a client of an EJB to do pass-by-reference invocations, having visibility to the public interfaces and stub implementation classes of an EJB will not work. In fact, the client of an EJB needs to have a direct reference to the implementation classes of the EJB's container. Because of local interfaces, clients of EJBs need to be able to load much more than they needed to previously. Because of this restriction, the classloading scheme detailed above will not work. The solution to this problem is to make classloaders of any applications that may need to use EJB children of the EJB classloader.

Please refer to Figure 2: Complex Classloading Approach for a graphical representation of a complex classloading scheme that a vendor could implement. In this model, Web application classloaders are children of the EJB classloader. This allows all Web applications to have visibility to all of the files they need in order to behave as clients of the EJBs. Each Web application is still loaded in a custom classloader to achieve isolation, though. In this implementation, the EJB classloader does not need to export any files to the EAR classloader, making the overall structure simpler to understand.

Figure 2. Complex Classloading Approach

An Ambiguity in the Specification

There is an ambiguity in the J2EE specification that has been exposed by certain implementations seen to date. The J2EE specification is ambiguous as to how dependency libraries specified in the manifest Class-Path: of a Web application should be loaded. It is very clear that a utility library specified by WEB-INF\lib should only be loaded by the classloader of the Web application and remains isolated. However, if a utility library is specified in the manifest Class-Path: of the Web application, it is not stated as to whether the library should be loaded by the Web application's classloader or exported to the EAR classloader. This can have a behavioral impact. If it is known that a utility library will only be loaded once for all Web applications, the Web applications can take advantage of knowing that a singleton class will only create a single object that can be shared among all Web applications. However, if the utility library were isolated by each Web application classloader, a singleton class would create a single object in each Web application.

Currently, Silverstream's application server and the J2EE reference implementation load utility libraries specified in the manifest Class-Path: of a Web application at the EAR classloader level. WebLogic Server 6.1 Beta loads these libraries as part of the Web application classloader. It appears, though, that it is likely that WebLogic Server 6.1 GA will modify this approach to support loading Web application utility libraries at the EAR level. (This actually makes sense, since you can always get Web application isolation by placing utility libraries in the WEB-INF\lib directory.)


It is important to note that for both of the scenarios described in this architecture, if two Web applications want to use two different versions of the same EJB (the different versions have slightly modified class files), this can only be achieved by doing two separate EAR applications. Since all EJBs are effectively loaded at the EAR level, only one version of a class specified in an EJB can be loaded by the EAR application at any given time.

Given the discussion in this article, I recommend that, when designing an application that uses JSPs, servlets, and EJBs together, any class that is shared by more than one application be placed into a common.jar file that is specified in the manifest Class-Path: entry of all applications that make use of it. Additionally, add any other support libraries to the appropriate manifest Class-Path: and place any Web application-specific libraries in the WEB-INF\lib. Following this approach, you should have smooth sailing from here on out!

Tyler Jewell , Director, Technical Evangelism, BEA Systems Tyler oversees BEA's technology evangelism efforts that are focused on driving early adoption of strategic BEA technologies into the ISV and developer community.

Read more EJB 2 columns.

Return to ONJava.com.