Introduction and summary of recommendations
This article describes the behavior of the classloader visibility options available in IBM ® WebSphere® Application Server (hereafter called WebSphere), and makes recommendations that simplify their use. Some techniques are provided to make working with the classloaders easier, particularly when using WebSphere Studio Application Developer (hereafter called WebSphere Studio, as these techniques also apply to other WebSphere Studio configurations).
The main recommendations are:
- Whenever possible, do not use Module visibility, as it can be complex, difficult to deploy to, and is deprecated in WebSphere 4.03.
- Do use the new J2EE Application visibility provided in WebSphere 4.03, as it conforms to the J2EE 1.3 specification, and is therefore the least likely to change in the future. Adopting this visibility now will simplify migration to WebSphere Version 5.
- If you are working with WebSphere 4.02 or earlier and unable to upgrade at this time, use Application visibility instead.
The discussion below includes these additional recommendations:
- Think carefully about how you implement the Singleton pattern, as the behavior of the classic implementation is complex in an environment with multiple JVMs and classloaders.
- If you use the Zip Creation Utility (see References) to link non-J2EE JavaTM projects in WebSphere Studio with JAR files deployed in enterprise application EAR files, specify a build path separate from the source folders in the workspace. This avoids exporting source code into your deployable application.
The topics covered are:
- WebSphere classloader settings and their evolution
- Which classloader setting should you choose?
- How and when should you implement the Singleton pattern in a J2EE application?
- How to specify interdependencies between application modules
- Upgrading the WebSphere Studio 4.03 Test Environment to WebSphere 4.03
- Creating JAR files Using WebSphere Studio and the Zip Creation Utility
What is a modular application?
For the purposes of this article, modular J2EE applications:
- Contain web modules and/or EJB modules.
- Also contain one or more JAR files, which in turn contain common application code or utility classes.
Some of these JAR files may be provided by third parties (such
as reporting utilities or Struts). Often, there are dependencies between
multiple JAR files in the same enterprise application. This article uses the
term utility JAR to mean a JAR file deployed within the .EAR file itself
(as opposed to the
WEB-INF/lib directory of
a Web module, for example), and referenced by Web or EJB modules. The term JAR
file or just JAR refers to JAR files in general.
To make the most of this article, see also the following resources on WebSphere Developer Domain:
- Read the description of classloaders in J2EE Classloading Demystified by Tim deBoer.
- Read the discussion and recommendations on packaging common code for use by multiple enterprise applications, or multiple modules in a single application, in J2EE Packaging and Common Code by Keys Botzum, to be published soon on WebSphere Developer Domain.
- Download the Zip Creation plug-in tool and read the guidance for developing utility JARs in Developing J2EE Utility JARS in WebSphere Studio Application Developer by Tim deBoer.
- See the WebSphere InfoCenter, Section 6.4.1, Setting Classpaths
- Download the WebSphere Studio Zip Creation plug-in if you haven't already done so.
- Both WebSphere Application Server and WebSphere Studio should be at Version 4.0.3 or later, or if this is not practical, then at least Version 4.0.2. Previous levels do not have important fixes that allow the development and execution of modular applications.
- WebSphere Studio version 4.03 does not provide a WebSphere Application Server 4.03 Test Environment unless you specifically apply the WebSphere Application Server Advanced Single Server Edition PTF 3 to the Test Environment plug-in in WebSphere Studio. This paper shows you how to perform the required upgrade.
WebSphere classloader options and their evolution
WebSphere Version 4 originally offered four classloader options:
- Server visibility provided a single classpath across all classloaders in the entire application server -- all the classes in all the enterprise applications could reference each other, however they were deployed.
- Compatibility visibility was provided to emulate the classloader arrangements of WebSphere 3.5.
- Application visibility allowed all the classloaders within a single enterprise application to reference each other. So, within each enterprise application, classes deployed in any utility JAR or module could reference classes deployed in any other utility JAR or module.
- Module visibility provided a separate classloader for each web or EJB module in the Enterprise Application, and enforced a separate classpath for each classloader. So, classes deployed in one utility JAR or module could not reference classes deployed in any other utility JAR or module, unless Manifest classpath entries were used to specify the dependency. These dependencies could only be specified within a single enterprise application.
PTF 3 for WebSphere 4.0 (or 4.0.3) changed the behavior of all the classloader settings. The recommendations in this article are intended to avoid dependence on any aspect of the class loader behavior that changed in PTF3, or that may change in the future. In particular, PTF3 added a new, recommended setting: new J2EE Application mode visibility. Figure 1 below shows a description of this setting, taken from the PTF3 release notes in the WebSphere InfoCenter.
Figure 1. Classloader visibility changes in WebSphere 4.03
The new J2EE Application visibility setting is consistent with Section 184.108.40.206 of the J2EE 1.3 Specification, Context Class Loader. The system property configuration to enable this visibility is shown in Figure 2 below, which depicts the JVM Settings tab of the application server properties in the WebSphere Application Server, Advanced Edition Administrator's Console. This setting overrides any Module Visibility setting you specify in the General tab of the Application Server properties.
Figure 2. Specifying new J2EE Application Visibility in WebSphere Application Server Advanced Edition
Which classloader setting should you choose?
- Do not use Server visibility -- it can result in hard-to-manage dependencies between code in multiple applications -- see J2EE Packaging and Common Code by Keys Botzum in the references above for discussion of problems relating to sharing common code among multiple applications.
- Do not use Module visibility -- it can be too difficult to configure, has been deprecated in WebSphere 4.0.3, and the behavior of its classloaders is more complex than originally documented. See below for discussion.
- Do not use Compatibility visibility -- it is provided for backwards compatibility, based on WebSphere 3.5 rather than the J2EE deployment model, and may be deprecated in future.
- Unless you are constrained to the WebSphere 4.0.2 run time, do not use Application visibility -- it is not as recommended by the future J2EE 1.3 specification, and so may change or be deprecated in future.
- Do use new J2EE application visibility -- it is relatively simple, and in line with the future J2EE 1.3 specification, and so less likely to change. It is likely to provide your application with the maximum portability across J2EE application servers.
At this point it helps to clarify some differences between Application visibility and new J2EE Application visibility in PTF3.
- Application visibility now provides a single classloader across all web and EJB modules. All classes are shared across all modules.
- New J2EE Application visibility provides a separate classloader for
each Web module, and a shared classloader for all utility JAR files and EJB
- All Web modules can reference classes in all utility JAR files and EJB modules.
- EJB modules can reference classes in all utility JAR files, but cannot reference classes in Web modules.
- Classes in one Web module cannot reference classes in other Web modules.
To strengthen the recommendations, let's look at some of the requirements you might have that appear to lead to one of the classloader visibilities not recommended above. In many cases, the best answer is to stick with new J2EE Application visibility. In particular, we'll address the differences between Application visibility, new J2EE Application visibility, and Module visibility.
Does the J2EE 1.2 specification recommend Module visibility?
The J2EE 1.2 specification does not make any recommendations on this topic. The J2EE 1.3 specification recommends the behavior found in the new J2EE Application visibility setting. The original WebSphere Version 4 documentation did recommend Module visibility, but that has changed with the Release Notes for WebSphere 4.0.3.
Why might you want to use Server visibility?
If you have Web modules, EJB modules, or JAR files used by multiple applications, you might want to simplify the deployment configuration by using Server visibility, and deploying them once, in a single enterprise application on which other enterprise applications depend. Some examples of modules and JAR files that you might want to use in this way are:
- Infrastructure components, such as JMS drivers
- Third-party utilities, such as Struts, Log4J
- Bespoke utilities, such as command frameworks, common data objects
- An EJB module containing Entity EJBs representing common elements of the business data model
However, this often leads to complications. For example, what happens when one application requires a new version of one of the modules or JAR files, but another application is unable to run a regression test against the upgrade?
For JAR files, it is often better to deploy them as utility JARs within each enterprise application EAR file that needs them. Similarly, you could consider deploying common EJB modules, or at least the associated client stubs, in each enterprise application that uses them. This lets you manage more than one version of the common code in the run time -- while there are issues associated with managing multiple versions, this approach at least gives you some flexibility.
For JAR files that you do want to deploy once for use by multiple applications, WebSphere provides the application extensions and runtime extensions classpaths as an alternative to Server visibility. These issues relate to hosting multiple applications on a single WebSphere server. If you will only ever host a single application on each server, they may not arise. However, this sort of rule is difficult to enforce in anything other than the short term, and following the alternatives suggested above will produce a more flexible, portable, and cleanly packaged application.
For further discussion and advice, see J2EE Packaging and Common Code, and Section 6.4.1, Setting Classpaths, in the WebSphere InfoCenter, both included in References above.
Why might you want to use Compatibility visibility?
If you're running a WebSphere 3.5 application, or an application developed in VisualAge® for Java Version 4, you'll need to run with Compatibility visibility. However, this setting is now substantially similar to Application visibility or new J2EE Application visibility, so you should consider migrating. In any case, you should be planning to migrate away from any reliance on WebSphere 3.5 compatibility.
Why might you want to use Application visibility?
You may already be using Application visibility, in which case you should get along fine for now. If you can apply PTF3 or use WebSphere 4.0.3, it's worth planning a migration to new J2EE Application visibility to minimize the impact of any future changes.
As described above, the main difference between Application visibility and new J2EE Application visibility is that Application visibility lets classes in EJB modules reference classes in Web modules, and classes in one Web module reference classes in another Web module. If you need to do this, you will need to use Application visibility. However, a better approach is to consider restructuring your application to avoid the requirement.
To illustrate this, suppose that your application needs to display weather reports in various cities. This information is expensive to retrieve from the data source, so you cache it in memory. The information is required both by a servlet common to several Web sites that display a full weather report, and by other servlets that display just the temperature as part of some other content. So, you might deploy a WeatherReportServlet and WeatherReportCache in one Web module, and your other servlets in different Web modules. Servlets in any Web module can reference the WeatherReportCache class to access the data they need. However, some points suggest a better arrangement of the code and remove the need to use Application visibility.
- The shared code is not a servlet, it is just a class, so it can be deployed in a utility JAR instead. This also makes the code accessible to any EJB modules that might require it.
- So, the only reason to use Application visibility is if a servlet class
needs to be referenced by an EJB module or a servlet in another Web module.
However, neither of these references is really desirable:
- The intention of EJB components is to be independent as far as possible from the client type (Web application, thick client, and so on). They should not depend on specific client classes.
- The Servlet 2.2 specification prohibits servlets in any Web module from sharing information in HTTPSession with servlets in other Web modules. This makes it very difficult in practice to build a closely-coupled Web application from servlets in multiple Web modules. It is better to view each Web module as a standalone Web application. So, it's not a good idea to introduce run-time code dependencies between Web modules.
Therefore we recommend that you remove run-time dependencies between EJB modules and Web modules, and between multiple Web modules. Instead, deploy common code in JAR files in the enterprise application. This will also enable your application to run in new J2EE Application visibility.
Why might you want to use Module visibility?
If you have an EJB module and a Web module in the same EAR file that need to reference different versions of the same classes, you might want to run with Module visibility. However, changes to Module visibility in PTF3 described below mean that this will not work.
If more than one module in your application uses a utility JAR that contains a singleton class, and both need to use an independent copy of the singleton, you might want to run with Module visibility. However, as described below, this does not work consistently in practice, particularly across fixpak levels.
The discussion below describes why Module visibility does not address either of these requirements:
- If a class is deployed in and loaded by the Web or EJB modules, the class and any singleton instance are specific to the module. This lets you deploy separate copies of the same class, or provide separate instances of the same singleton class.
- Until PTF3: If a class is deployed in a utility JAR used by only one module: It is loaded by the module classloader, and is specific to the module. This lets you deploy separate versions of the same class, or provide separate instances of the same singleton class.
- Until PTF3: if a class is deployed in a utility JAR used by more than one module: WebSphere creates an additional dependency classloader, and the class is specific to this. This classloader is accessed by all modules dependent on the utility JAR file, so the class and any singleton instances are shared across all modules.
- After PTF3: All utility JAR files are loaded by the EJB/dependency classloader. So, any class or singleton instance deployed in any utility JAR is shared across all modules.
The behavior is depicted in Figures 3, 4, and 5. In the example, an enterprise
application is shown containing a single Web and a single EJB module. The Web
module uses the
archives; the EJB module uses the
Before PTF3, it can be seen that
is loaded by the Web module classloader, and
is loaded by the EJB module classloader. However,
is used by both modules, and is loaded by the dependency classloader. Therefore,
SharedUtility.jar cannot reference
the Web module, or the EJB module, and classes and instances in
are shared between the Web and EJB Modules.
After PTF3, it can be seen that all utility JAR files are loaded by the EJB module Classloader. Therefore, classes and instances in all utility JAR files are shared between the Web and EJB modules.
Figure 3. Sample modular application
Figure 4. Classloader behavior in Module visibility until PTF3
Figure 5. Classloader behavior in Module visibility after PTF3
The results are threefold:
- Module visibility does not fulfill these requirements in any simple manner.
- The behavior of the classloaders might change in future, so their detailed behavior cannot be relied on.
- The complexity of this behavior means that only the most experienced Java developers are likely to be comfortable with it. Such complexity is generally not warranted -- it is better to find alternative, simpler approaches.
How and when should you implement the singleton pattern in a J2EE application?
The previous section described how the behavior of singletons depends on the precise arrangement of classpaths, and that this is liable to change. So, it is very difficult to be sure of the scope within which the singleton pattern guarantees a single instance.
The implications of this for the role of the singleton pattern in J2EE application design are:
- If you require a basic cache for common data or services, and are concerned with minimizing the number of copies rather than ensuring that there is only one, then a classic singleton implementation is still viable as there will be a small number of instances per JVM. The exact number will depend on the arrangement of the classloaders and their usage patterns.
- If you require a real, application scope single instance (that is, not any J2EE or WebSphere usage of the word application, but your entire customer information system or whatever), then a classic singleton is not the answer -- even if there is only one instance per JVM, there will be more than one JVM if you clone your application server. Probably the only thing you can guarantee to be unique across the whole application is a row in a database table -- so you might consider an Entity EJB and a single-valued primary key instead.
- If you have a component that needs a number of instances defined at some more granular level, then this granularity will either be defined in terms of your application as a whole, or represent a more sophisticated form of cache. In the former case, you might again consider an Entity EJB, this time with a small, controlled number of primary keys. In the latter case, you could extend the classic singleton implementation.
- There are more sophisticated problems related particularly to read/write caches that are beyond the scope of this article, but this discussion should at least have highlighted some issues that distributed J2EE applications introduce to them.
Another way of looking at the Entity EJB solution is that
it is an alternative implementation of the singleton pattern: instead of using
class variables to provide universal scope, a database is used, and control
over the number of instances is provided by the
method rather than a private constructor.
How to specify interdependencies between application modules
The techniques to configure the run-time classloader dependencies depend on whether the run time uses new J2EE Application, Applicationor Module visibility, and are covered separately. This section applies to WebSphere Studio, but should contain useful guidance for all WebSphere users.
New J2EE application visibility configuration
The Edit Module Dependencies facility in WebSphere Studio
should be used to configure
MANIFEST.MF Class-Path entries of the Web and EJB
modules to explicitly indicate dependences on all the utility JAR files that
their code eventually uses.
Application visibility configuration
For this visibility, use the same process as for New J2EE application visibility.
Module visibility configuration
Take the following steps:
- Using Edit Module Dependencies for the Web module, specify:
- The EJB module.
- Any utility JAR files that are directly referenced by the Web module.
- Using Edit Module Dependencies for the EJB module, specify:
- Any utility JAR files that are directly referenced by the EJB module.
- The JAR manifest extensions feature is needed to allow each individual utility JAR to specify dependencies on other utility JAR files. This cannotbe specified at the Web or EJB module level using Edit Module Dependencies.
The manifest extensions feature works as follows:
- When the classloader loads any class from a JAR file, it looks in the
META-INF\MANIFEST.MFfile of the JAR for a Class-Path setting. Any entries specified there are added to the classpath for classes loaded from the JAR file.
- The Class-Path setting is a space-delimited list of relative path names of other JAR files. The path names are interpreted relative to the root of the EAR file.
For example, consider an EAR file that contains:
utilityA.jar depends on
MANIFEST.MF file of
should look like this:
----- START ---- Manifest-Version: 1.0 Class-Path: utilityB.jar extras\utilityC.jar ------ END ------
- Filenames are case sensitive.
- Manifest-Version and Class-Path should appear on separate lines.
- It is vital that one new line appears after the final entry in the Class-Path
setting. Without it, two things happen:
- The WebSphere Test Environment in WebSphere Studio will not recognize the settings.
- When the Enterprise Application is exported as an EAR file, the Class-Path setting in the manifest file will be lost.
So, how do we create the
MANIFEST.MF file in WebSphere Studio?
- In the root of the Java project representing the utility JAR, create a
META-INFand a file in that directory
MANIFEST.MF. Make sure all uppercase characters are used.
- Edit the
MANIFEST.MFfile, and add the Class-Path: setting as above, being careful to add one new line at the end.
- WebSphere Studio maps this file to the Java output directory, and the Zip creation utility adds it to the utility JAR file.
- Repeat the process for all utility JAR files until all dependencies are
Figure 6. Creating the MANIFEST.MF for a Java Project in WebSphere Studio
It is interesting to note that this technique works for all the classloader visibility settings. However, it is more complex than the simpler techniques previously described for new J2EE Application visibility and Application visibility. This is another indication that Module visibility is too complex to use in practice.
If you investigate the archive using WinZip, you may not see
MANIFEST.MF file, because by default, WinZip
ignores files with all uppercase filenames. To change this behavior:
- Open WinZip and go to Options and Configuration.
- Check Allow all uppercase filenames.
Upgrading the WebSphere Studio Test Environment to WebSphere 4.03
WebSphere Studio 4.03 provides a WebSphere Test Environment at level 4.02, not 4.03. In order to upgrade the test environment to level 4.03, and so be able to test applications using new J2EE Application visibility, follow the steps below. (These steps are for WebSphere Studio on Windows®.)
- Download PTF3 for WebSphere Application Server Advanced Single Server Edition. Select the download package for your platform marked AEs not AE.
- Extract the fixpak from its ZIP file into a temporary directory.
- Close WebSphere Studio.
- Make a note of the WebSphere Studio installation directory.
- Create a temporary directory for the PTF installation logs and make a note of it. Create subdirectories called Backup, Logs, and Temp within this directory.
- You now need to configure the application server fixpak to run in silent
mode. To do this, either follow the fixpak installation guide, or create a
.batfile in the temporary directory where you extracted the fixpak, and add the following commands to it:
set WS_HOME=<Enter the WebSphere studio installation directory here> set LOG_HOME= <Enter your temporary directory for the PTF installation logs here> set WAS_UPDATE_HOME=%WS_HOME%\plugins\com.ibm.etools.websphere.runtime set JDK_UPDATE_HOME=%WS_HOME%\plugins\com.ibm.etools.server.jdk set BACKUP_DIR=%LOG_HOME%\Backup set LOGS_DIR=%LOG_HOME%\Logs set TMP=%LOG_HOME%\Temp
The file I used looks like this:
set WS_HOME=D:\Programs\WebSphere\WS set LOG_HOME=D:\Programs\WebSphere\Install\WAS403WS set WAS_UPDATE_HOME=%WS_HOME%\plugins\com.ibm.etools.websphere.runtime set JDK_UPDATE_HOME=%WS_HOME%\plugins\com.ibm.etools.server.jdk set BACKUP_DIR=%LOG_HOME%\Backup set LOGS_DIR=%LOG_HOME%\Logs set TMP=%LOG_HOME%\Temp
From a command prompt in the directory containing the fixpak,
.bat file. Then run the fixpak installation
in silent mode using the command
The fixpak installation will upgrade the WebSphere Studio Test Environment to
In order to configure the upgraded test environment in WebSphere
Studio, add the system property
as described in the PTF3 Release Notes. To do this, open the server instance
editor for the Test Environment, and add the system property on the Environments
tab, as shown in Figure 7 below.
As with WebSphere Application Server, this system property will override whatever classloader visibility option you specify in the Module Visibility setting of the Test Environment Configuration Editor.
Figure 7. Specifying new J2EE application visibility in the WebSphere Studio Test Environment
Creating JAR files using WebSphere Studio with the Zip Creation utility
The WebSphere Studio plug-in referenced in the background reading provides a facility to associate a Java Project with a JAR file contained in an Enterprise Application Project or EAR file. This tool automatically updates the JAR file within your Enterprise Application Project whenever the associated Java project is updated. The JAR file can then be specified as a run-time and compile-time dependency for the Web and EJB modules through the Edit Module Dependencies wizard.
By default, this plug-in uses the contents of the Java Project Build output folder. This default is specified by the Include Java Output Folder check box in the Zip Creation section of the Java Project properties. However, by default, the Build output folder of a Java project is the Java project root, so both source and compiled code are mapped to the generated JAR. As a result, when the Enterprise Application EAR file is exported, this source code is also exported (whether or not the Export source files option is checked in the EAR export wizard). This can cause compilation errors at run time if JSPs reference classes in the utility JAR file.
The solution is to ensure that the project has a separate build path from the source folders:
- Right-click on the Java Project root folder and select New => Folder. Call this something like classes to indicate it is intended to contain the compiled code.
- Open the Java Build Path page of the Java Project properties. Specify the new folder as the Build output folder.
- Accept the default settings for the Zip Creation properties of the Java project.
Figure 8. Specifying a build output folder for a Java project in WebSphere Studio
The utility JAR files will now contain only compiled code.
This article discussed some key issues surrounding the use of the classloader visibility options in WebSphere Application Server Version 4 or later. It also discussed the very useful Zip creation utility, and the implementation of singleton patterns in an environment with multiple JVMs and classloaders. We hope you have a deeper understanding of the complex WebSphere Application Server classloader structure, and the reasons why nearly all applications should consider only the new J2EE Application visibility or Application visibility options. The other classloader options, particularly Module visibility, are simply too complex for practical use. In addition, the J2EE 1.3 specification gives a clear statement of direction for all application servers, and choosing new J2EE Application visibility now will put you in a good position to move forward.
Thanks to Tom Alcott, Keys Botzum, Dave Artus, Alexandre Polozoff, and Paul Gover for reviewing and contributing comments to this article. Thanks also to Gary Martin for information on updating the WebSphere Studio Test Environment to Version 4.03.
Questions from users
Great info. One question -- if I already downloaded and installed WebSphere Application Server Enterprise Edition 4.1, should I still install the package? Also, the article states that this PTF3 (FixPak3) fixes the server within WebSphere Studio Application Developer to support J2EE 1.3. Is this fix also for WebSphere Application Server? Please clarify. Thanks for your help, Igor Livshin?
Response from author
If by "package" you mean the Zip creation utility, then yes, go ahead and install it. Regarding the PTF3 Fixpak:
- PTF3 does not upgrade either WebSphere Studio Application Developer or WebSphere Application Server to J2EE 1.3 -- the article doesn't say this.
- PTF3 does upgrade WebSphere Application Server, including important changes to classloader behavior.
- One of the key points the article makes is that it is important that the classloaders in the development environment (WebSphere Studio Application Developer) behave the same way as those in the run time (WebSphere Application Server). So, after you've applied PTF3 to WebSphere Application Server, you need a way of applying the same changes to the test environment in WebSphere Studio Application Developer
- There is no fixpak available specifically to do this for WebSphere Studio Application Developer. However, because the test environment is an embedded version of WebSphere Application Server, you can apply the WebSphere Application Server PTF3 to WebSphere Studio Application Developer. That's what the article describes.
- The above points remain true if you have WebSphere Application Server Enterprise Edition 4.1.
A question on the Zip Creation utility. The problem we've found with separating source and compiled code in the utility project is that it's then difficult to debug from within the project(s) that use the JAR-ed code. Stepping into code in a JAR requires that the source be in a JAR as well -- you can't simply point the debugger to the source within the workspace. Any good way around this? Thanks.
Response from author
The answer is that there is no easy way around this issue -- either you have source code in the JAR and can see it in the debugger, or you don't have it in the JAR and can't see it. The approach I have started using is to begin with the source and compiled code in the same directory -- .java and .class files together, meaning you get the source in the JAR and can debug. Once the code is stable, I change the build output folder, delete the .class files from the source directory, and rebuild the project, removing the source from the JAR file. It's all a bit manual, but it's the easiest way I know -- and you're still avoiding the need to continuously export and re-import the JAR file.
Thanks for a good article. I have some EJBs that are used by several applications. I want to deploy them in one EAR file and then use the remote interface in other EAR files. I also have some common classes passed to and from the EJBs. The only way I have been able to make this work is by deploying the common classes in the websphere/lib/app directory. But I would much rather have the common class JAR in each of the EAR files, which works fine if the EJB EAR ear file is deployed on one server and the applications on another. Is it possible to make this also work on one server -- all EAR files under one JVM? -- Thanks, Michael Schoning
Response from author
The problem described here -- sharing common classes between two EJB JARs in the same JVM -- is a known one. The particular issue is that the ORB in the JVM has difficulty with the calls between EJB JARs if more than one classloader has loaded a common class -- as happens in this scenario. To fix this, set the system property:
This setting allows the ORB to share those classes that are common between the two modules. You should be at WebSphere Application Server V4.0.4 (i.e. with PTF4) or later before using this setting. WebSphere V5 does not have this problem.
I was hoping this article would explain how the classloader policy can be configured in WebSphere V4.0.3 so an application-specific JAR can be used in preference to the run-time version, namely xerces.jar. I am having version conflicts on this front and the Web info suggests using the PARENT_LAST classloader mode, which appears to be WebSphere V5 only. Can this be done in WebSphere V4.0.3? Help urgently needed.
Response from author
There are two answers to this question, depending on the precise meaning of "application-specific." If "application-specific" means "I want to override a WebSphere provided JAR for all applications on my server," then the Application Extensions (AEX) classpath, is the one to use. It's described in the InfoCenter -- search on "classloader" and look for the topic "Setting classpaths." On the other hand, if "application-specific" means "I want to override it for only one application," I'm not sure you can to do this in V4, but it would be worth raising the issue with IBM support. For further information on this question, see also References above.
This is the best article I have seen on classloading in WebSphere Studio. However, the solutions offered do not solve a J2EE classloading problem I continue to have. I am using WebSphere Studio Application Developer AEs V4.0.3 ptf30217.01 and WebSphere Application Server AE V4.0.4 ptf40230.02. Classes that load fine during development throw errors when run on WebSphere Application Server. Can you possibly offer some advice? Thanks.
Response from author
I would need more information to fully diagnose this problem, so you may want to raise the issue with IBM support. In the meantime, here are some suggestions:
- Check that both WebSphere Application Server and the WebSphere Studio Test Environment have the same classloader visibility setting, preferably J2EE application. (The defaults for the two products are different.)
- Use the instructions in my article to upgrade the WebSphere Studio Test Environment to PTF4 (the same level as the run time).
- Check exactly which classes have problems.
- If a class cast exception is being thrown, Java is trying to cast an object of type A into type B. Add some logging code to the application to confirm what both types are, and then run in both WebSphere Application Server and WebSphere Studio to find the difference.