![]() |
|
Classes are the basic building blocks of Java, outside of which no executable code can be written. A classloader refers to a component that is used to load classes.
Classloaders form a basic component of Java whose function is to load classes at runtime to the Java Virtual Machine (JVM). In other words, a classloader is an object that loads classes into memory, and is responsible for navigating and loading class files at runtime.
Classloaders implement java.lang.ClassLoader and allow different portions of the container, and the Web applications running on the container, to have access to different repositories of available classes and resources.
deploy-config.xml.Application classes precedence can be set by a flag for an application or globally for all applications. You can get the application to load its own classes in the system classpath. This would be available only on demand and not as a default option.
The CLs can be added at any time during code execution. Every CL, other than the Bootstrap CL, *has a parent.
When a CL is asked to load a particular class or resource, it delegates the request to its parent CL first, which, in turn, sends it to its own parent CL up the hierarchy. If the requested class/resource is not found, the request is sent back to the parent.
Bootstrap
The Bootstrap CL is the parent in the Java classloader hierarchy. It has ‘null’ parent. The JVM creates the Bootstrap CL, which loads the Java Development Kit (JDK) internal classes and java.* packages included in the JVM. For example, the Bootstrap CL loads java.lang.String. It loads the basic runtime class of JVM - rt.jar, along with any classes from jar files present in the System Extensions directory ($JAVA_HOME/jre/lib/ext). Bootstrap serves as the default parent for Extension CL and System CL.
Note: Some JVMs may implement this as more than one classloader, or it may not be visible as a CL.
JDK Extension
The Extension CL is a child of the Bootstrap CL. The Extension CL is the parent of all Application CLs and has the capability to pick up classpath, and detect the addition of jars to the classpath. It loads any JAR files placed in the Extension directory of the JDK. This is a convenient means of extending the JDK without adding entries to the classpath. However, anything in the Extension directory must be self-contained and can only refer to classes in the Extension directory or JDK classes. It loads the classes present in the directory path .jre/lib/ext.
System
The System CL is the child of the Extension CL. It loads the classes from the classpath environment variable.
Pramati Extension CL
The CL .jre/lib/ext directory can be changed by pointing to a node specific directory. The Extension CL is also used during loading of external classes like DataSources and startup hooks etc. Jar files, classes directories or zip files can be dropped without the server being stopped in the jre/lib/ext dir.
Application
The Application classloaders are created by pramati server to manage application class loading. Different strategies are handled to suite specific requirements.
Note: The behavior of the above structure is not related to .jre/lib/ext.The jars don't get picked up when you copy them manually. The classpaths have to be set for the jars to be picked.
Application Classes Precedence
By setting a flag for the whole application or a Web module, you can get the application to load its own classes over the same class in the system class path. This would be available only on demand and not as a default option. This is usually required for applications that need to use their own version of classes rather than the ones which the server uses.
Application Groups
Ability to share classes among applications using an application group. A group can be defined in deploy-config.xml. Grouping enables an application to access the classes packaged in another application in the same group. When an application belonging to a group is restarted, all started applications of that group have to be restarted because the applications use a common classloader.
When the Deploy Service tries to deploy an application, it loads the ejb/rar classloader and Web classloader. After which the application loads the classes through these classloaders. The ejb/rar classloader loads all jars and all jars inside rars. The Web classloader loads all jars required for the Web module. The Bootstrap classloader, Ext classloader and the System classloader are loaded by the Java runtime environment.
The Pramati Ext classloader loads all other external classes from the directory specified in the server-config.xml. The default directory is . The rar classloader loads all the standalone rars.
A single classloader can be used to load multiple applications, if the applications are setup in a logical group. Classloader for multiple applications can be set in deploy-config.xml.
<classloader-for-multiple-apps enabled="false"> <application-group apps="abcd.ear,xyz.jar"/> </classloader-for-multiple-apps>In the above case if
classloader-for-multiple-apps is false, a single classloader is loader for each application. In the above case, if no group is defined, a universal group for all the applications is assumed.
Any application not mentioned in the apps list as shown above will get its own dedicated classloader. If no group is specified, then a single classloader is used.
Single Classloader for Applications
The Deploy Service can be instructed to use a single classloader at the time of deployment of Web, connector and bean components within an application from the pramati-j2ee-server.xml file.
<use-single-classloader-for-app> true <use-single-classloader-for-app>CLs have preloaded classes for all applications that enable even an EJB to pick up Web classes, once this feature is enabled. The Web loader would be the same instance and not use the EJB CL as a parent to enable Web classes access by EJB.
Preferring Deployed Classes
This option is used to specify the preference of the classes for the classloader at the time of deployment of the application.
<prefer-deployed-classes for="application"/>
In this case if the application has classes that are also present in the system classpath, the application classes are picked up by the classloader. In this case, the application also includes Web modules.
<prefer-deployed-classes for="web-module"/>
If the Web module classes are to be preferred over the other classes, the above option can be specified.
<prefer-deployed-classes for="none"/>
In this case there is no preference for the classloader and the classes are loaded normally.
Setting Up the Ext Directory
By default the external classes are loaded from <install_dir>/server/libext. But a different ext directory can be specified, from where the classes can be auto loaded. This can be done by using <ext-classloader-dir> from server-config.xml. Since server-config.xml is specific to a server instance, multiple ext directory can be set for multiple server instances.
When the Server starts, the:
All classes that form part of Server are placed in System Classpath.
All the EJB modules (jars) within an application have a single CL, whereas each Web module (war) has a separate CL. The structure is such that the System Classpath acts as the parent for the EJB modules, which, in turn, serves as the parent for each of the Web modules. In other words, each instance of the Web module is a direct child of the EJB module.
It is common for Web applications to call EJBs. Server application classloader architecture allows JSPs and servlets to see the EJB interfaces in their parent classloader. This architecture also allows Web applications to be redeployed without redeploying the EJB tier. It is more common to change JSP pages and servlets than to change the EJB tier.
java.class.path system property when the JVM is invoked. This CL can always be found via the static method ClassLoader.getSystemClassLoader(). If not specified, any user-instantiated CL will have this loader as its parent.
Every application receives its own classloader hierarchy, and the parent of this hierarchy is System CL. This isolates applications so that one application cannot see the CLs or classes of another. In CLs, no sibling or friend concepts exist. Application CLs can only see their parent classloader - the System CL. This allows Server to host multiple isolated applications within the same JVM.
Server automatically creates a set of CLs when an application is deployed. The base application CL loads any jar files in the application. A child CL is created for each Web application.
An ear is a package of all the jars and wars.
If you deploy a jar and a war separately, they are treated as two applications by the Server. If they are deployed together within an ear file, they are treated as one application. This produces a classloader arrangement that allows servlets and JSPs to find the EJB classes.
All jars should be explicitly placed in the system classpath.
<install_dir>/lib/ext)You can place a driver such as the Oracle JDBC Driver classes12_01.zip in the system classpath.
You can also add shared utility classes to the Java system classpath. If you modify your utility classes and they are in the Java system classpath, however, you will have to restart the Server after you modify the utility classes. Helper jars may include the utility jars that serve to provide some additional functions, and may be duly referenced by using the path entries in MANIFEST.MF.
Besides other information, the MANIFEST.MF contains details regarding:
com.pramati.j2ee servera.jarThe J2EE specification provides the manifest classpath entry as a means for a component to specify that it requires an auxiliary jar of classes. You only need to use this manifest classpath entry if you have additional supporting jar files as part of your jar or war file. In such cases, when you create the jar or war file, you must include a manifest file with a classpath element that references the required jar files.
The following is a simple manifest file that references a utility.jar file:
Manifest-Version: 1.0 [CRLF] Classpath: utility.jar [CRLF]In first line of the manifest file, you must always include the
Manifest-Version attribute, followed by a new line (CR | LF |CRLF) and then the Classpath attribute. More information about the manifest format can be found at: http://java.sun.com/j2se/1.4/docs/guide/jar/jar.html#JAR.
The manifest classpath entries refer to other archives relative to the current archive in which these entries are defined. This structure allows multiple wars and jars to share a common library jar. The manifest file itself should be located in the archive at META-INF/MANIFEST.MF.
For more information, see manifest.html.
For example, let's say we have the following jar files: a.jar ; b.jar ; c.jar and d.jar. The classpath in the MANIFEST.MF of a.jar is: b.jar /..folder/c.jar, and the classpath of b.jar refers to d.jar. The effective class path to be used is: a.jar;b.jar;d.jar;c.jar.
Important
In other words, if e.jar is loaded at run time, and makes a call to f.jar, which needs g.jar to be loaded first, you will get an exception if g.jar is placed lower in the CL hierarchy than f.jar.
What Happens When:
e.jar calls f.jar - The search begins only after the request reaches the parent BootStrap CL that looks for f.jar in the Extension CL, and then System CL where it finds it.
f.jar calls for g.jar - Once found, f.jar makes a call to g.jar, which, since it is not in the same CL, the search will again take the 'highest to lowest' approach - in the meanwhile, e.jar, not being able to run f.jar, would give off an exception.
Hence, placing the jar files in the proper hierarchy is of utmost importance so as to not provide those exceptions.
There are two classes class1 and class2, and there are two jar files EJB_JAR1 and EJB_JAR2. The two classes are required only by EJB_JAR1, and not by EJB_JAR2. The contents for EJB_JAR1 would be the beanclasses + class1 + class2 + ejb_jar.xml (present in the META-INF folder of the jar file.)
Case 2
There are two classes class1 and class2, and there are 'n' number of jar files EJB_JAR1... EJB_JARn in EAR1. The two classes are required only by all the jar files. The contents for EAR1 would be EJB_JAR1 +... + EJB_JARn + common.jar (that has class1 and class2.)
Note: Remember, the MANIFEST.MF should have a reference to the classpath entry of common.jar.
This jar is located at <install-dir>/server/nodes/default/archives/<application name>/classes, where 'default' could be a folder created by a user with a different name.
a) Modifications are made in JSPs
This is the case when after a class has been loaded using a CL, the JSP page is modified.
After making the changes in the JSP and after recompiling the page, if you try to load the class again using the CL, you will find that the JSP page does not reflect the changes. The reason is that although recompilation updates the file, the CL does not load the new file because it picks up JSP pages loaded earlier using a map to its existing paths.
To overcome this, the JSP engine uses smart code generation to check the time stamp of the modified file against the existing file. It changes the class name with an incremental value and places it in the same path, so that the CL picks up the updated file.
b) Application is redeployed
When you have to deploy a new version of an already deployed application on your system, you need to create a new application CL.You cannot use the existing CL because classes might have changed in the new version, which you should reload. Smart code generation skips classes that have not been modified, loads new classes and creates a new CL structure.
Client.jarDuring the preparation phase, RMI Stubs of Home and the Remote Interfaces of EJBs are placed in the Client.jar.
Application helper jars
These are to be provided by the application, with a reference in the client Classpath.
util.jar within the EJB module, and the same jar file must also be placed on the client VM at runtime.
To avoid a classcast exception while casting a JMS message content to a particular class, the class must be packaged in the EJB module's jar in which the MDB resides. This is the preferred method to avoid any classcast exceptions.
The class can also be packaged in the utility.jar, which is referred by the EJB module through the Classpath entries in MANIFEST.MF.
ClassCastException
The cause of this error is simple, say, casting an Integer to String. Often, the situation is one of "same class, different loader" type, where the source and target types have the same class name.
Class Duplication
This problem arises when:
Normally, the existence of duplicate classes is not a problem. In order for an exception to occur, an instance created in one CL must be passed into the CL of the other. This can be achieved through any storage facility visible to both classloaders, including:
Class.forName() or ClassLoader.loadClass()).application.xml file to share classes across all applications. Keep configurations portable. Choose configuration options in the following order:
Class.forName(), always pass the CL returned by Thread.currentThread().getContextClassLoader. If you are loading a properties file, use Thread.currentThread().getContextClassLoader().getResourceAsStream().To avoid a classcast exception while casting a JMS message content to a particular class, the class must be packaged in the EJB module's jar in which the MDB resides. This is the preferred method to avoid any classcast exceptions. The class can also be packaged in the utility.jar, which is referred by the EJB module through the Classpath entries in MANIFEST.MF.
What goes into the client jar during preparation?
During the preparation phase, RMI Stubs of Home and the Remote Interfaces of EJBs are placed in the Client.jar.
Where to place application exceptions when using Java clients?
If a J2EE application that is being accessed through a Java client throws a runtime exception, the client needs to have that exception in its Classpath. These application exceptions need to be packaged as separate jar files (util.jar) within the EJB module, and the same jar file must also be placed on the VM client so as to be able to catch them at runtime. Refer to the exceptions in the section on Common Classloader Problems.
Where to place application exceptions when Concentrators access EJBs in Pramati Server?
Concentrators are clients as other Web servers, portal applications etc. that run on other servers and try to access EJBs deployed on Pramati Server. To allow concentrators to access EJBs in the Server, do the same as for handling exceptions.
How to specify the Classpath option when starting Server from a remote VM using Java program?
If the Server is started from a remote VM using a Java program, the classpath option must be specified giving the complete path for running the application. A code sample for the same is provided below:
// code snippet for starting J2ee server.
ArrayList commandList=new ArrayList();
if(System.getProperty("os.name").startsWith("Windows")) file://for windows & NT
commandList.add(javaHome + File.separator + "bin" + File.separator + "javaw");
else file://any other OS
commandList.add(javaHome + File.separator + "bin" + File.separator + "java");
commandList.add("-D="); // add jvm options; for every jvm option add one entry like this.
commandList.add("-classpath");
commandList.add(); file://add server classpath here;
// that is the class path set by the setup.bat file
commandList.add("-Dinstall.root=/server");
commandList.add("com.pramati.J2eeServer");
// following two lines are not required for default server.
commandList.add("-config");
commandList.add("/server/nodes/StandAlone//config/server-config.xml"); // for stand alone server.
or
commandList.add("/server/nodes/Cluster//config/cluster-config.xml"); // for cluster node.
commandList.add("-username"); // this is not required if username password is
commandList.add(""); // "root" and "pramati" respectively.
commandList.add("-password"); //
commandList.add(""); //
commandList.add("-redirect");
commandList.add("-noCommandLine");
Runtime.exec(commandList.toArray(new String[0]));
// end of code snippet
classloading: The process of installing a class file into the JVM to create a class.
BootStrap CL/Primordial CL: JVMs in-built CL responsible for storing the core system classes. User-defined CL: An instance of a subclass of CL with user defined behavior (overridden methods) for certain aspects of class loading. It is responsible for loading all classes other than the core system classes.
| © Pramati Technologies 2007 | Runs on Pramati Server | Feedback | Legal |