12.5.1 Step 1: Simple Web module packaging
Start with the following assumption: our utility class is only used by a servlet. We have placed the VersionCheckerV1.jar file under the WEB-INF/lib directory of the Web module.
Tip: You place JAR files used by a single Web module, or a JAR file that only this Web module should see under WEB-INF/lib.
When we run the application in such a configuration, we obtain the results shown in Example 12-6.
Example 12-6 Class loader: Example 1
VersionChecker called from Servlet VersionChecker is v1.0.
Loaded by com.ibm.ws.classloader.CompoundClassLoader@71827182
Local ClassPath: C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\ClassloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\classes;C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\ClassloaderExample.ear\ClassloaderExampleWeb.war\WEB-INF\lib\VersionCheckerV1.jar;C:\WebSphere\AppServer\profiles\AppSrv02\installedApps\kcgg1d8Node02Cell\ClassloaderExample.ear\ClassloaderExampleWeb.war
Delegation Mode: PARENT_FIRST
There are a few things we can learn from this trace:
1. The type of the WAR class loader is com.ibm.ws.classloader.CompoundClassLoader.
2. It searches classes in the following order: ClassloaderExampleWeb.war\WEB-INF\classes ClassloaderExampleWeb.war\WEB-INF\lib\VersionCheckerV1.jar ClassloaderExampleWeb.warThe WEB-INF/classes folder holds unpacked resources (such as servlet classes, plain Java classes, and property files), while the WEB-INF/lib holds resources packaged as JAR files. You can choose to package your Java code in JAR files and place them in the lib directory or you can put them unpacked in the classes directory. They will both be on the same classpath. Because our sample application was developed and exported from the Application Server Toolkit, our servlet goes into the classes folder, because the toolkit does not package the Java classes in a JAR file when exporting an application.
The root of the WAR file is the next place where you can put code or properties, but you really should not do that because that folder is the document root for the Web server (if the File Serving Servlet capabilities are enabled, which they are by default) so anything that is in that folder is accessible from a browser. According to the J2EE specification, though, the WEB-INF folder is protected, which is why the classes and lib folders are under WEB-INF.
The class loader class path is dynamically built at application startup.
We can now also use the Class Loader Viewer to display the class loader. In the console, select Troubleshooting | Class Loader Viewer. Then expand server1 | Applications | ClassloaderExample | Web modules and click the ClassloaderExampleWeb.war, as shown in Figure 12-6.
Figure 12-6 Class Loader Viewer showing applications tree
When the Web module is expanded, the Class Loader Viewer shows the hierarchy of class loaders all the way from the JDK Extensions and JDK application class loaders at the top to the WAR class loader at the bottom, called the compound class loader.
Figure 12-7 Class Loader Viewer showing class loader hierarchy
If you expand the classpath for the WAS Module - Compound Class Loader, you see the same information as our VersionChecker class prints. See Example 12-7.
Example 12-7 Class Loader Viewer showing class path for WAR class loader
file:/C:/WebSphere/AppServer/profiles/AppSrv02/installedApps/kcgg1d8Node02Cell/ClassloaderExample.ear/ClassloaderExampleWeb.war/WEB-INF/classes file:/C:/WebSphere/AppServer/profiles/AppSrv02/installedApps/kcgg1d8Node02Cell/ClassloaderExample.ear/ClassloaderExampleWeb.war/WEB-INF/lib/VersionCheckerV1.jar file:/C:/WebSphere/AppServer/profiles/AppSrv02/installedApps/kcgg1d8Node02Cell/ClassloaderExample.ear/ClassloaderExampleWeb.war
For the Class Loader Viewer to display the classes loaded, the Class Loader Viewer Service must be enabled as described in Class loader viewer.
The Class Loader Viewer also has a table view that displays all the class loaders and the classes loaded by each of them on a single page. The table view also displays the Delegation mode. True means that classes are loaded with parent class loader first (PARENT_FIRST), while false means that classes are loaded with application class loader first (PARENT_LAST), or the WAR class loader in the case of a Web module.
Figure 12-8 Class Loader Viewer table view
As you can see, the WAR class loader has loaded our example servlet and the VersionChecker class, just as expected.
The Class Loader Viewer also has a search feature where you can search for classes, JAR files, folders, and so on. This can be particularly useful if you do not know which of the class loaders loaded a class you are interested in. The search feature is case sensitive but allows wild cards, so a search for *VersionChecker* finds our VersionChecker class.