Custom services and the WebSphere classloaders
 Technote (troubleshooting)
 
Problem(Abstract)
When starting an application server, you have encountered unexpected or exception messages concerning the creation of your CustomService by the WebSphere® Application Server. A typical message might read:

[mm/dd/yy hh:mm:ss:uuu XXX] CustomService W WSVR0018W:
Unable to create CustomService:
java.lang.NoClassDefFoundError: <the_fully_qualified_name_of_the_class_not_found>
 
Cause
This problem is usually caused by specifying an incorrect classpath when configuring the CustomService using the administrative console. For example, the classpath does not contain the user's CustomService implementation class, or some of its dependent classes. Sometimes, however, the problem is more subtle and requires an understanding of how CustomService classes interact with the WebSphere Application Server runtime environment, and more specifically, the WebSphere Classloaders.
 
Resolving the problem
Tip: To resolve this problem, ensure that all CustomService-related artifacts (JARs, classes, and so forth) are in the classpath specified in the Custom Service's configuration in the administrative console. If not, refactor the CustomService artifacts or reconfigure the classpath of your CustomService to satisfy this condition. Save your changes and restart the server to verify your fix.

If you still encounter the problem, read the following discussion before adopting the plausible solution of placing your CustomService artifacts in the JVM™ classpath to resolve the NoClassDefFoundError. This will only cause the server to fail with the same error, only for the class com.ibm.websphere.runtime.CustomService. If you are still confused, read the following.

The classpath setting you specified for your CustomService is added to the local classpath of the WebSphere Extensions classloader (WSExtCL) early in the start sequence of the application server. Next in the sequence, the server instantiates user-specified CustomServices and invokes the services' initialize method. The context classloader of the thread executing the initialize method is still the WSExtCL. Finally, during server quiesce the runtime environment invokes the CustomServices' shutdown method. Again, the context classloader for the shutdown method is the WSExtCL.

The WebSphere Extensions classloader resides between the Java™ classloader (JavaCL) and the WebSphere Application classloader (WSAppCL). That is, the JavaCL is the parent of the WSExtCL, and the WSExtCL is the parent of the WSAppCL.

The WSAppCL is actually a tree of classloaders that load your applications EAR, EJB™ and WAR artifacts. This tree will change structure depending on classloader policy settings. Also, the JavaCL is fixed lineage of three classloaders. For this discussion, JavaCL and WSAppCL are represented as single composite entities:

[JavaCL] -- Java artifacts loaded here.
|
WSExtCL -- Application server and CustomService artifacts loaded here.
|
[WSAppCL] -- Application artifacts loaded here.

So, what does all this mean to developing a CustomService?

First, the classes comprising a CustomService scope to the application server, meaning that ALL applications hosted by that server can utilize your CustomService classes. Also, these classes will persist in the WSExtCL cache over the lifecycle of the application server.

Second, because of the location of the WSExtCL in the preceding classloader structure, and because classloading only delegates upward, the WSExtCL cannot locate application classes appearing in the local classpaths of the classloaders below it. Thus, your
CustomService classes cannot have dependencies on application classes. This agrees with the concept of a CustomService, which is a pluggable extension of the WebSphere server environment.

This also explains why you will get a NoClassDefFoundError when placing your CustomService classes on the JVM classpath of the application server. Your CustomService classes will be loaded by the JavaCL, which cannot resolve the dependencies on WebSphere runtime classes visible only in the WSExtCL local classpath, namely interface com.ibm.websphere.runtime.CustomService.

Tip: Your CustomService classes cannot not have dependencies on any application classes; but conversely, your application classes might have dependencies on CustomService classes. Ensure that your CustomService classes have no dependencies on application classes, and refactor the CustomService and Application artifacts as necessary. Using the administrative console, reconfigure your CustomService, save your changes, and restart the server to verify your fix.

This should resolve the problem, but here is a little more...

From the preceding discussion, it seems plausible that changing the context classloader in your CustomService code could alleviate class-visibility problems. Do not attempt this -- IBM WebSphere absolutely will not support this solution, and it is dangerous!

Finally, you cannot control the ranking of a Custom Service's creation or initialization and shutdown within the server's start and shutdown sequences. Thus, for instance, you cannot assume WebSphere services are available for use within CustomService initialization.
 
 
Cross Reference information
Segment Product Component Platform Version Edition
Application Servers Runtimes for Java Technology Java SDK
 
 


Document Information


Product categories: Software > Application Servers > Distributed Application & Web Servers > WebSphere Application Server > Classloader
Operating system(s): Windows
Software version: 5.0
Software edition:
Reference #: 1180880
IBM Group: Software Group
Modified date: Sep 30, 2004