服务模块时Tomcat类加载顺序而不发布

时间:2013-10-30 07:08:51

标签: java eclipse tomcat

我正在使用带有eclipse的tomcat。

根据tomcat的文件:

从Web应用程序的角度来看,类或资源加载在以下存储库中按以下顺序查找:

  • JVM系统类加载器类的Bootstrap类(描述 以上)
  • / WEB-INF /您的Web应用程序的类
  • 您的Web应用程序的
  • / WEB-INF / lib / * .jar
  • 常见的类加载器类(如上所述)

因此,在加载类时,tomcat将在 WEB-INF / lib 之前查找 WEB-INF / classes 。 我们可以在WEB-INF / lib中覆盖jar文件中的某些类,tomcat将获取覆盖的类。

但是现在如果我通过检查"服务模块而没有发布"来改变tomcat服务器选项。 ,然后不再加载被覆盖的类。

是否有任何解决方案可以使其再次运行,但我仍然希望tomcat在不发布的情况下提供模块服务。


编辑:
我在这个文件夹 f:\ eclipse_projects \ .metadata.plugins \ org.eclipse.wst.server.core \ tmp0 \ conf 中找到了一些可能有用的东西。 有一个server.xml,它包含这样的内容:

<Resources className="org.eclipse.jst.server.tomcat.loader.WtpDirContext" 
    extraResourcePaths="" 
    virtualClasspath="F:\eclipse_projects\ALS7C3\bin"/>
<Loader className="org.eclipse.jst.server.tomcat.loader.WtpWebappLoader" 
    useSystemClassLoaderAsParent="false" 
    virtualClasspath="F:\eclipse_projects\ALS7C3\bin"/>

似乎在运行tomcat时选项&#34;服务模块没有发布&#34;检查后,eclipse将使用它自己的loader.This加载器包含在一个jar文件中,该文件将被复制到 f:\ eclipse_projects \ .metadata.plugins \ org.eclipse.wst.server.core \ tmp0 \ lib **当你在eclipse中启动tomcat时。 以下是** org.eclipse.jst.server.tomcat.loader.WtpDirContext 的源代码的一部分:

public Object lookup(String name) throws NamingException {
        if (name.startsWith("/WEB-INF/") && name.endsWith(".tld")) {
            String tldName = name.substring(name.lastIndexOf("/") + 1);
            if (virtualMappings != null && virtualMappings.containsKey(tldName)) {
                return new FileResource(virtualMappings.get(tldName));
            }
        } else if (tagfileMappings != null && name.startsWith("/META-INF/tags")
                && (name.endsWith(".tag") || name.endsWith(".tagx"))) {
            // already loaded tag file
            return new FileResource(tagfileMappings.get(name));
        } 

        Object retSuper;
        NamingException superEx;
        try {
            retSuper = super.lookup(name);
            return retSuper;
        } catch (NamingException ex) {
            retSuper = null;
            superEx = ex;
        }
        if (mappedResourcePaths != null) {
            // Perform lookup using the extra resource paths
            for (Map.Entry<String, List<String>> mapping : mappedResourcePaths.entrySet()) {
                String path = mapping.getKey();
                List<String> dirList = mapping.getValue();
                if (name.equals(path)) {
                    for (String resourcesDir : dirList) {
                        File f = new File(resourcesDir);
                        if (f.exists() && f.canRead()) {
                            if (f.isFile()) {
                                return new FileResource(f);
                            }
                            else {
                                // TODO Handle directory
                            }
                        }
                    }
                }
                path += "/";
                if (name.startsWith(path)) {
                    String res = name.substring(path.length());
                    for (String resourcesDir : dirList) {
                        File f = new File (resourcesDir + "/" + res);
                        if (f.exists() && f.canRead()) {
                            if (f.isFile()) {
                                return new FileResource(f);
                            }
                            else {
                                // TODO Handle directory
                            }
                        }
                    }
                }
            }
        }
        throw superEx;
    }

似乎它首先处理jsp标签库然后调用 super.lookup ,如果无法在 super.lookup 中找到它,它会尝试在virtualClasspath中加载资源,&#34; F:\ eclipse_projects \ ALS7C3 \ bin&#34;在我的例子中,它是在没有发布服务模块时eclipse输出类文件的地方。

所以,我想,如果我可以覆盖 org.eclipse.jst.server.tomcat.loader.WtpDirContext 查找方法,我可以得到我想要的东西,但是这个jar文件包含在 org.eclipse.jst.server.tomcat.core.jar 中,两者都是签名的。

我不知道如何覆盖这样的jar文件。

任何人都可以提供帮助吗?

2 个答案:

答案 0 :(得分:0)

以下是我使用eclipse / tomcat进行热部署的方法:

  1. 停止tomcat
  2. 打开tomcat配置菜单
  3. 在“服务器选项”选项卡中选中“未发布的服务模块”
  4. 在“发布”标签中选中“永不发布”
  5. 保存配置
  6. 以调试模式启动tomcat(这非常重要)
  7. 如果您更改了配置文件,可能会尝试使用新的tomcat。

答案 1 :(得分:0)

覆盖这些类的解决方案是修改工作区项目中的Servers\???-config\catalina.properties

  

common.loader = $ {catalina.base} / lib中,$ {catalina.base} / lib中/ *。罐子,$ {的catalina.home} / lib中,$ {的catalina.home} / lib中/ *。罐子

属性common.loader是Tomcat公共ClassLoader的类路径设置 Webtools插件将 org.eclipse.jst.server.tomcat.core.jar 复制到${catalina.base}/lib。 您可以覆盖这些类并将${catalina.base}/lib,${catalina.base}/lib/*.jar替换为新路径。