论坛首页 Java企业应用论坛

嵌入式Tomcat怎么能让Context自动reload

浏览 22362 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-03-25  
启动embedded tomcat的代码网上狠多,但是没有一个例子是让context自动reload的。如果能打开这个功能,对开发肯定大有帮助。

普通的Tomcat打开reloadable狠容易,只要改server.xml就行叻。但是对于Embedded Tomcat,我希望全部工作都在代码中完成,不使用任何配置文件。

我试着这样,可是毫无效果:
            context = tomcat.createContext(...);;
            context.setReloadable(true);;
            host.addChild(context);;


在tomcat源代码里翻叻一晚上,也没发现什么头绪,似乎WebappLoader是个重要的线索,但是我还是搞不出来:(

附我启动embedded tomcat的关键代码:
    private void initEmbedded(); {
        tomcat = new Embedded();;
        tomcat.setCatalinaBase(getTomcatPath(););;

        Host host =
            tomcat.createHost(
                "localhost",
                tomcat.getCatalinaHome(); + "/webapps"
            );;

        String[] contexts = getContextsMappingPath();;
        String[] contextsPath = getContextsAbsolutePath();;
        Context context = null;

        for (int i = 0; i < contexts.length; ++i); {
            context = tomcat.createContext(contexts[i], contextsPath[i]);;
            context.setReloadable(true);;
            host.addChild(context);;
        }

        Engine engine = tomcat.createEngine();;
        engine.setName("ShowdoorDevAppServer");;
        engine.addChild(host);;
        engine.setDefaultHost(host.getName(););;

        tomcat.addEngine(engine);;
        tomcat.addConnector(
            tomcat.createConnector("localhost", 8080, false);
        );;
    }
   发表时间:2006-03-26  
我现在无语叻,受tqyq在这个帖子里的启发:

http://forum.iteye.com/viewtopic.php?t=18624&postdays=0&postorder=asc&start=60

我也试着在Eclipse里以Debug而不是Run的方式运行我上面的类,结果果然是成功叻,随便怎么修改类文件,就是及时生效!就是及时生效!!!气死我叻,为叻这个问题我两天没睡好叻。

虽然问题解决叻,不过我觉得还是有必要研究一下怎样让embedded tomcat自己能侦测类的变化并且reload context,脱离Eclipse Debug的帮助。


我把我整个类贡献出来吧,针对Tomcat 5.5.x的

这是客户端调用类:
import embedded.EmbeddedTomcatLauncher;

public class MyTomcatLauncher extends EmbeddedTomcatLauncher {
    public static void main(String[] args); {
        //开始运行嵌入式Tomcat,狠简单,就new一下当前类然后startTomcat();就行
        new MyTomcatLauncher();.startTomcat();;
    }

    //这里返回你要加载的项目的绝对地址的String数组
    @Override
    protected String[] getContextsAbsolutePath(); {
        return new String[] {
            "/home/hongliang/workspace/scaffold/webapp"
        };
    }

    //这里返回你上面写的项目要映射后的路径,跟上面的数组一一对应
    @Override
    protected String[] getContextsMappingPath(); {
        return new String[] {"/scaffold"};
    }

    //这里返回你embedded tomcat的地址
    @Override
    protected String getTomcatPath(); {
        return "/home/hongliang/libraries/tomcat/apache-tomcat-5.5.15-embed";
    }
}



EmbeddedTomcatLauncher.java
package embedded;

import org.apache.catalina.Context;
import org.apache.catalina.Engine;
import org.apache.catalina.Host;
import org.apache.catalina.startup.Embedded;


public abstract class EmbeddedTomcatLauncher {
    private Embedded tomcat;

    protected EmbeddedTomcatLauncher(); {
        initEmbedded();;
        initShutdownHook();;
    }

    protected abstract String[] getContextsAbsolutePath();;

    protected abstract String[] getContextsMappingPath();;

    protected abstract String getTomcatPath();;

    protected void startTomcat(); {
        try {
            long startTime = System.currentTimeMillis();;
            tomcat.start();;
            System.err.println(
                "Embedded Tomcat started in "
                + (System.currentTimeMillis(); - startTime); + " ms."
            );;
        } catch (Exception e); {
            e.printStackTrace();;
        }
    }

    private void initEmbedded(); {
        tomcat = new Embedded();;
        tomcat.setCatalinaBase(getTomcatPath(););;

        Host host =
            tomcat.createHost(
                "localhost",
                tomcat.getCatalinaHome(); + "/webapps"
            );;

        String[] contexts = getContextsMappingPath();;
        String[] contextsPath = getContextsAbsolutePath();;
        Context context = null;

        for (int i = 0; i < contexts.length; ++i); {
            context = tomcat.createContext(contexts[i], contextsPath[i]);;
            host.addChild(context);;
        }

        Engine engine = tomcat.createEngine();;
        engine.setName("MyDevAppServer");;
        engine.addChild(host);;
        engine.setDefaultHost(host.getName(););;

        tomcat.addEngine(engine);;
        tomcat.addConnector(
            tomcat.createConnector("localhost", 8080, false);
        );;
    }

    private void initShutdownHook(); {
        Runtime.getRuntime();.addShutdownHook(
            new Thread(); {
                public void run(); {
                    stopTomcat();;
                }
            }
        );;
    }

    private void stopTomcat(); {
        try {
            tomcat.stop();;
        } catch (Exception e); {
            e.printStackTrace();;
        }
    }
}
0 请登录后投票
   发表时间:2006-03-26  
说到底就是classloader的原因。你在eclipse里面运行,项目class的classloader和放在WEB-INF下的classloader不是同一个。
0 请登录后投票
   发表时间:2006-03-26  
crmky 写道
说到底就是classloader的原因。你在eclipse里面运行,项目class的classloader和放在WEB-INF下的classloader不是同一个。


Eclipse里的Run和Debug也是不同的。不过这不是我要问的问题。
0 请登录后投票
   发表时间:2006-04-17  
把eclipse得output path设置到WEB-INF/classes下
0 请登录后投票
   发表时间:2006-04-17  
chenggn 写道
把eclipse得output path设置到WEB-INF/classes下


本来就是
0 请登录后投票
   发表时间:2006-04-18  
看起来是你设置了true之后,他会去读配置文件,然后重写为false。

所以一个简单的办法,修改setReloadable方法的代码,无论传进什么都设置为true。
0 请登录后投票
   发表时间:2006-04-23  
是不是要touch一下什么文件,让tomcat  认为 context有更新?
0 请登录后投票
   发表时间:2006-04-27  
如果你希望Tomcat支持hot replace class这种功能,看我发表的Tomcat资源管理器的帖子。
0 请登录后投票
   发表时间:2006-04-28  
厄,这reload的时间是多少?我记得之前试过在非嵌入式的TOMCAT中,使用reload,但是感觉它咚咚咚reload过来,跟重启动的速度差不多啊
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics