Tomcat6.0.18的bin目录下有一个bootstrap.jar文件bin\bootstrap.jar
,而这个jar中的类org.apache.catalina.startup.Bootstrap
在catalina_Home/lib/catalina.jar
文件中也存在。为什么要把同样的class放在2个不同的jar中,而且还单独提取出来放到bin目录下?
bin\bootstrap.jar是catalina_Home/lib/catalina.jar的子集
从源码中可以看到,Tomcat6.0.18使用common ClassLoader 在启动后加载catalina_Home/lib
目录下的jar,但执行启动脚本时,是把catalina_Home/bin
目录下的bootstrap.jar
设置到-classpath
中,然后执行MAINCLASS=org.apache.catalina.startup.Bootstrap
。
此时,也就是启动时,是使用System ClassLoader
来加载的Bootstrap.class
。
如果不单独提取出bootstrap.jar,而是将整个catalina.jar设置到-classpath
中,这时catalina.jar中的所有class将会被System ClassLoader加载。
就会出现问题了,catalina.jar中的类引用了catalina_Home/lib
目录下的其他类class,比如A,而A是在common ClassLoader 加载的,位于加载路径的下端, 而此时catalina.jar却是被System ClassLoader加载,位于加载路劲的上端,默认的双亲委派会导致加载器只能向上委托加载,不能向下
,导致catalina.jar中的 类引用不到A。
因此,冗余catalina_Home/lib/catalina.jar
,把里面重要的类放到启动时由系统类加载器System ClassLoader提前加载,这些类不引用应用类,应用类是启动后,才由common ClassLoader 加载的,避免了引用错误问题。