In a J2SE 2 (that is, J2SE 1.2 or later) environment, class loaders are arranged in a parent-child tree. Normally, when a class loader is asked to load a particular class or resource, it delegates the request to a parent class loader first, and then looks in its own repositories only if the parent class loader(s) cannot find the requested class or resource. The model for web application class loaders differs slightly from this, as discussed below, but the main principles are the same.
System - 这个类装载器通常是以CLASSPATH环境变量的内容为基础来初始化的。所有的这些类既可被Tomcat内部classes使用,又可被网络程序使用。不过,标准的Tomcat 5启动脚本( $CATALINA_HOME/bin/catalina.sh or %CATALINA_HOME%\bin\catalina.bat )完全忽略了CLASSPATH环境变量自身的内容,相反从下面的贮藏室去建造系统类装载器:
$CATALINA_HOME/bin/commons-logging-api.jar - Jakarta commons 记录应用程序界面。
$CATALINA_HOME/bin/commons-daemon.jar - Jakarta commons daemon API.
jmx.jar - JMX 1.2 执行。
Common - This class loader contains additional classes that are made visible to both Tomcat internal classes and to all web applications. Normally, application classes should NOT be placed here. All unpacked classes and resources in $CATALINA_HOME/common/classes, as well as classes and resources in JAR files under the $CATALINA_HOME/commons/endorsed, $CATALINA_HOME/commons/i18n and $CATALINA_HOME/common/lib directories, are made visible through this class loader. By default, that includes the following:
commons-el.jar - Jakarta commons el, 执行Jasper使用的表达语言。
jasper-compiler.jar - The JSP 2.0 编译器。
jasper-compiler-jdt.jar - The Eclipse JDT Java compiler.
naming-factory-dbcp.jar - Jakarta commons DBCP, providing a JDBC connection pool to web applications. The classes have been moved out of their default org.apache.commons package.
naming-java.jar - Handler for the java: namespace.
naming-resources.jar - The specialized JNDI naming context implementation used to represent the static resources of a web application. This is not related to the support of the J2EE ENC, and cannot be removed.
servlet-api.jar - The Servlet 2.4 API.
tomcat-i18n-**.jar - Optional JARs containing resource bundles for other languages. As default bundles are also included in each individual JAR, they can be safely removed if no internationalization of messages is needed.
tomcat-ajp.jar - Classes for the Java portion of the AJP web server connector, which allows Tomcat to run behind web servers such as Apache and iPlanet iAS and iWS.
As mentioned above, the web application class loader diverges from the default Java 2 delegation model (in accordance with the recommendations in the Servlet Specification, version 2.3, section 9.7.2 Web Application Classloader). When a request to load a class from the web application's WebappX class loader is processed, this class loader will look in the local repositories first, instead of delegating before looking. There are exceptions. Classes which are part of the JRE base classes cannot be overriden. For some classes (such as the XML parser components in J2SE 1.4+), the J2SE 1.4 endorsed feature can be used (see the common classloader definition above). Last, any JAR containing servlet API classes will be ignored by the classloader. All other class loaders in Tomcat 5 follow the usual delegation pattern.
因此,从一个网络程序的角度来看,类和资源的装载以这样的顺序在下列贮藏室进行查找:
你的JVM的Bootstrap类
系统类装载器类(描述如上)
你的网络程序的/WEB-INF/classes
你的网络程序的/WEB-INF/lib/*.jar
$CATALINA_HOME/common/classes
$CATALINA_HOME/common/endorsed/*.jar
$CATALINA_HOME/common/i18n/*.jar
$CATALINA_HOME/common/lib/*.jar
$CATALINA_BASE/shared/classes
$CATALINA_BASE/shared/lib/*.jar
2.使用JMX,配合tomcat的启动配置,监控tomcat内存使用情况
在tomcat的catalina.bat中加入:
set JAVA_OPTS
=
%JAVA_OPTS% -Dcom.sun.management.jmxremote.port=8890
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
启动tomcat后,就可以通过jdk的bin目录下的jconsole来监控tomcat的内存使用。
//调用Tomcat的JMX服务,如停止、启动web应用
public static boolean callWebModuleMBeanMethod(String appName,String methodName) throws Exception{
MBeanServer mBeanServer = null;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer=(MBeanServer)MBeanServerFactory.findMBeanServer( null).get(0);
} else {
throw new Exception("cann't find catalina MBeanServer");
}
Set names = null;
try {
names = mBeanServer.queryNames(new ObjectName( "*:j2eeType=WebModule,name=//localhost/"+appName+",*"), null); } catch (Exception e) {
throw new Exception("cann't find "+appName+ " web moudule mbean! can't undeploy web app.\n"+e.getMessage());
}
if(names==null || names.size()==0) {
log.debug("can't find "+appName+ " web moudule mbean!");
return false;
}
ObjectName oname =null;
Iterator it = names.iterator();
if (it.hasNext()) {
oname=(ObjectName) it.next();
}
if(oname==null)
return false;
try {
mBeanServer.invoke(oname,methodName,null,null);
return true;
} catch (Exception e) {
throw new Exception("can't "+methodName+" "+appName+ " web application!\n"+e.getMessage());
}
}
public static void main(String[] args){
callWebModuleMBeanMethod("app1","stop"); //停止web应用app1
callWebModuleMBeanMethod("app1","start"); //启动web应用app1
}