Tomcat classloader的加载顺序

最近项目中遇到在Tomcat7.0.26中类加载顺序不稳定的情况,github上拉了源码看了下搞明白了。项目中的问题是,我们可以通过字母顺序定义jar文件在webapp\WEB-INF\lib下的加载顺序,但是在tomcat\lib\ext下就不灵了。其实问题在于这两个位置的jar, tomcat是用的不同的classloader去加载的,所以结果自然不同。

对于common和system class,tomcat使用的是org.apache.catalina.startup.ClassLoaderFactory产生的classloader,入口在Bootstrap.initClassLoaders()。这个classloader里面遍历文件夹下的jar文件时使用的是java api: File.list()。看javadoc对顺序的解释。

     * <p> There is no guarantee that the name strings in the resulting array
     * will appear in any specific order; they are not, in particular,
     * guaranteed to appear in alphabetical order.

而在WebappClassloader中,tomcat对于File.list()取到的列表又做了一次字母顺序排序。

org.apache.naming.resources.FileDirContext

    protected List<NamingEntry> list(File file) {

        List<NamingEntry> entries = new ArrayList<NamingEntry>();
        if (!file.isDirectory())
            return entries;
        String[] names = file.list();
        if (names==null) {
            /* Some IO error occurred such as bad file permissions.
               Prevent a NPE with Arrays.sort(names) */
            log.warn(sm.getString("fileResources.listingNull",
                                  file.getAbsolutePath()));
            return entries;
        }

        Arrays.sort(names);             // Sort alphabetically
        NamingEntry entry = null;
        ......

猜你喜欢

转载自theking.iteye.com/blog/2371127