Java 重新启动嵌入式Tomcat7服务器
我们使用嵌入式Tomcat7来托管一个web应用程序 它工作得很好,只有一个小小的例外 我们之所以使用嵌入式Tomcat,是因为我们需要在多个平台上操作,而我们的架构师已经做出了决定Java 重新启动嵌入式Tomcat7服务器,java,tomcat,tomcat7,embedded-tomcat-7,Java,Tomcat,Tomcat7,Embedded Tomcat 7,我们使用嵌入式Tomcat7来托管一个web应用程序 它工作得很好,只有一个小小的例外 我们之所以使用嵌入式Tomcat,是因为我们需要在多个平台上操作,而我们的架构师已经做出了决定 问题 我们希望让用户能够在包装器/容器Java应用程序运行时检查WAR更新(实时更新)。 目前,他们必须重新启动我们的应用程序,这是不可取的 基本上,我们的代码只是在远程服务器上检查更新的WAR文件,如果它们存在,则下载它们。 问题是,我们似乎无法让Tomcat服务器关闭或释放它对已爆炸的WAR文件夹的锁定 如果
问题 我们希望让用户能够在包装器/容器Java应用程序运行时检查WAR更新(实时更新)。 目前,他们必须重新启动我们的应用程序,这是不可取的 基本上,我们的代码只是在远程服务器上检查更新的WAR文件,如果它们存在,则下载它们。 问题是,我们似乎无法让Tomcat服务器关闭或释放它对已爆炸的WAR文件夹的锁定 如果我们完全销毁Tomcat实例,那么我们可以部署WAR文件并删除分解后的WAR文件夹,但是Tomcat不会分解并托管它们,直到我们完全杀死包装器/容器JAVA应用程序并重新启动。 一旦我们重新启动,Tomcat就会分解WAR文件并很好地托管应用程序
我在找什么 我希望有一种方法可以取消部署正在更新的应用程序,或者正确关闭/停止Tomcat服务器
代码示例 我简化了下面的代码示例,没有包括下载的实现,因为这样做很好 Tomcat实例不是公共的,但只是为了便于使用才这样做的。 此外,线程中的睡眠只是为了简化示例而引入的 这个样本刚刚加入了无止境的循环
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.LifecycleState;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
...
public class Testing123
{
public static void main(String[] args)
{
final Testing123 test = new Testing123();
test.createTomcat();
test.downloadUpdate();
(new Thread())
{
public void run()
{
Thread.sleep(10000);
test.downloadUpdate();
}
}.start();
while (true)
{
// this loop is just for this example...
}
}
public Tomcat tomcat = null;
private String webappsPath = "c:\\tomcat\\webapps";
private void createTomcat()
{
this.tomcat = new Tomcat();
this.tomcat.setBaseDir(this.webappsPath);
this.tomcat.setPort("5959");
this.tomcat.getServer().setPort("5960");
this.tomcat.getServer().setShutdown("SHUTDOWN");
this.tomcat.getHost().setCreateDirs(true);
this.tomcat.getHost().setDeployIgnore(null);
this.tomcat.getHost().setDeployOnStartup(true);
this.tomcat.getHost().setAutoDeploy(true);
this.tomcat.getHost().setAppBase(this.webappsPath);
Context ctx = this.tomcat.addWebapp(null, "/app1", "APP1");
ctx.setLoader(new WebappLoader(Testing123.class.getClassLoader()));
ctx.setReloadable(true);
}
private boolean isTomcatRunning()
{
if ((this.tomcat == null) || (LifecycleState.STARTED == this.tomcat.getServer().getState()))
{
return true;
}
return false;
}
private void shutdownTomcat() throws Exception
{
if (this.isTomcatRunning())
{
if ((this.tomcat!= null) && (this.tomcat.getServer() != null))
{
this.tomcat.stop();
while ((LifecycleState.STOPPING == this.tomcat.getServer().getState()) || (LifecycleState.STOPPING_PREP == this.tomcat.getServer().getState()))
{
// wait for the server to stop.
}
}
}
}
private void startTomcat() throws Exception
{
if (this.isTomcatRunning())
{
if ((this.tomcat!= null) && (this.tomcat.getServer() != null))
{
try
{
this.tomcat.init();
while (LifecycleState.INITIALIZING == this.tomcat.getServer().getState())
{
// wait for the server to initialize.
}
}
catch (Throwable e)
{
// ignore
}
this.tomcat.start();
while ((LifecycleState.STARTING == this.tomcat.getServer().getState()) || (LifecycleState.STARTING_PREP == this.tomcat.getServer().getState()))
{
// wait for the server to start.
}
}
}
}
private void downloadUpdate()
{
this.shutdownTomcat();
// Download the WAR file and delete the exploded WAR folder...
this.startTomcat();
}
}
你有可能在另一条路径下部署新的战争并运行它吗?谢谢你的快速回复,但不,这对我们不起作用。我们有需要特定路径的servlet。这不是我的意思;)我在问你是否可以按程序做。如果可以的话,有可能让TOmcat也通过编程“别名”成为新运行的war所需的路径。我不知道如何做到这一点。你能提供一个如何让Tomcat创建别名的例子吗?不,我想你会有主意;)我脑子里突然冒出一个非常疯狂的想法,那就是为那些只会传递数据的应用程序制作一个webapp,你可以自动地将重定向到的路径写入其中。。。但我相信还有其他解决办法