組み込みの Tomcat 7 を使用して Web アプリケーションをホストしています。
わずかな例外を除いて、非常にうまく機能します。
組み込みの Tomcat を使用している理由は、複数のプラットフォームで運用する必要があり、アーキテクトがその判断を下したためです。
問題
ラッパー/コンテナー 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();
}
}