Index
[]AntApacheapplicationsauthenticationauthorization
Index
[]
Index
[]classesClassLoadersclientsconfigurationController Servlet
Index
[]DataSourcedebuggingdeploymentdeployment descriptorsdirectoriesdomains
Index
[]EAR filesEJB JAR filetransactionsemailsending messages
Index
[]
Index
[]HARs (Hibernate Archives)carsHome InterfacesHypersonic databases
Index
[]implementationinitializationinstallationinterfacesHome InterfacesIteration 1, JAW Motors example
Index
[]J2EEDeclarative SecurityJAR filesJavaMail APIJNDI referencesJAW Motors exampleIteration 1Session BeansJAX-RPC mapping fileJBossjboss.xmlJDBCJMS (Java Message Service)message modelsJNDI referencesJavaMail-basedJSPs
Index
[]logging
Index
[]
Index
[]
Index
[]persistence
Index
[]
Index
[]securityprogrammaticsecurity credentials propagationdeployment
Index
[]
Index
[]testingtierstransactionsEJBs
Index
[]
Index
[]View Cars page
Index
[]WAR filesWeb Servicesweb-based deployment descriptorsweb.xml
Index
[]
Index
[]
Index
[]
A.1. Namespaces
The JVM recognizes a class by its runtime identitythe class' full name (the package plus class name), along with the instance of the ClassLoader that instantiated the class. Each ClassLoader has its own namespace consisting of the classes it loads, and each fully qualified class name MUST be unique within that namespace. This naming convention is required by the J2EE specification. Two ClassLoaders could each load the same class, and the JVM would treat each class as a distinct type. Thus the JVM considers class com.jbossatwork.util.TextEmail in ClassLoader 1 different from the com.jbossatwork.util.TextEmail in ClassLoader 2 because they have different runtime identities based on the ClassLoader name. We'll see why this distinction is important when we get to the section on the JBoss ClassLoaders.
A.2. Class Loading in the J2EE
Class Loading is one of the least understood aspects of J2EE deployment. Although not officially part of the J2EE specification, most application servers use a strategy similar to the ClassLoader hierarchy in to support J2EE component deployment.
The J2EE-based ClassLoaders work as follows:
The EAR ClassLoader loads the classes from JARs contained in the EAR file.
The EJB ClassLoader loads EJBs and related classes that reside in the EJB JAR file.
The WAR ClassLoader loads the web-specific classes and JARs in the WAR file's WEB-INF/{class,lib} directories.
Because each ClassLoader has no access to the classes loaded by its children or siblings, the classes in the WAR file are not visible to EJBs. Of course EJBs shouldn't try to reference things in the WAR in the first place because it is poor architecture. Each layer should not know about the invoking layer, and you can't assume that a web-based presentation layer will always be in your application.
Figure A-2. Generic J2EE Application Server Class Loader Hierarchy
The J2EE specification is vague concerning the deployment order of the J2EE modules. Many application servers deploy the JARs and classes in the EAR, and then the classes in the EJB JAR, and finally, the classes and JARs in the WAR. In the JAW Motors application, the Common JAR strategy works because the EAR contains the Common JAR, so the application-specific dependency classes and the third party utility JARs get deployed first, then the EJBs in the EJB JAR are loaded, and the web components from the WARwhich depend on the EJBs and common classes and JARsdeploy last.
Here is a practical example that uses the class-loading scenario from . In the JAW Motors application, a JSP invokes a Servlet, which in turn uses an EJB; both the Servlet and the EJB use Log4J. Since the JSP and Servlet are packaged in the WAR, the WAR ClassLoader finds and loads the JSP and Servlet. When the Servlet instantiates the EJB, the WAR ClassLoader cannot find the EJB, so WAR ClassLoader defers to its parentthe EJB ClassLoader. The EJB JAR contains the EJB, so the EJB ClassLoader finds and loads the EJB on behalf of the WAR ClassLoader. When the Servlet instantiates the Log4J Logger to log messages, neither the WAR ClassLoader nor the EJB ClassLoader can find the Log4J JAR, so they delegate to their parent, the EAR ClassLoader. Since The Common JAR contains the Log4J JAR, the EAR ClassLoader finds and loads the Log4J Logger on behalf of the child ClassLoaders.
A.3. Class Loading with JBoss
JBoss.
Figure A-3. JBoss ClassLoader Hierarchy
JBoss' ClassLoader hierarchy differs from the strategy used by other J2EE application servers in the following ways:
The ClassLoader Repository
The ClassLoader Repository contains all classes loaded by a JBoss instance, including:
JBoss' internal boot classes, including its J2EE component implementations
Any classes or JARs specified on the command line when starting JBoss
All classes or JARs from each deployed application
By default, only one ClassLoader Repository covers the entire server. But you are free to declare any number of repositories and associate any deployed applications with a repository. To keep deployment simple, the JAW Motors application uses the default ClassLoader Repository.
Cross-referencing between EJB JAR and WAR files
Within an EAR, an EJB could access classes and/or properties packaged in a WAR file (Log4J for example). The converse is true as wellweb components could access resources bundled in an EJB JAR. However, we do not recommend this practice because it ties you to JBossyour application will not deploy on other application servers.
Loading classes
The WAR, EJB JAR, and EAR ClassLoaders do NOT load any classes. When an application loads its classes, each ClassLoader adds its contextual information (classes, property files, and JARs) to the ClassLoader context and defers to its parent. Finally, control passes to the JBoss Application ClassLoader, which loads the class from the ClassLoader Repository.
We still recommend using a Common JAR (that resides in the EAR), which contains all JARs and classes common to both an application's EJB JAR and WAR, because:
Some form of packaging JARs in an EAR file works with most J2EE application servers.
It enables you to share classes between applications. For example, if EAR 1 and EAR 2 both use com.jbossatwork.util.TextEmail.class , you could factor it out of both applications into a separate deployment. Then you would be free to cycle the EAR files independently and never have to worry about ClassCastException s when you hot deploy one of the applications.
A.4. Common ClassLoader Issues
ClassLoader issues are difficult to find and take a long time to debug. They fall into one of two categories:
Not enough visibility
You'll see one of the following exceptions:
Java API methods such as Class.forName( ) or ClassLoader.loadClass( ) throw a ClassNotFoundException . This exception happens when a class loader tries to load a class and can't find the class. Here are some possible causes: