web-dev-qa-db-ja.com

TomcatでWebアプリケーションのコンテキスト構成を提供する方法は?

JDBC接続のように、インストール後に構成されるいくつかのリソースとパラメーターに依存するWebアプリケーションがあります。

私が思いついたのは、アプリケーションをデプロイするときにTomcatによってMETA-INF/context.xmlにコピーされる[engine-name]/[server-name]/[app-name].xmlを提供することです。このように、私が提供しているのは、appBaseフォルダー(webapps)にコピーできるwarファイルのみです。 Tomcatのドキュメント says このようなファイルが存在する場合、それは上書きされません。これは、展開後に行われた変更が失われないためです。

ただし、ここには微妙な問題があります。webappsディレクトリにコピーしてアプリケーションをデプロイするため、Tomcatは最初に既存のアプリケーションと設定ファイルをアンインストールします。これにより、構成ファイルが失われたり上書きされたりしますが、これは望ましくありません。 Tomcat しません 私の知る限り、この動作を変更します。

問題は、Tomcatが既存の構成ファイルを削除しないようにアプリケーションをインストールすることで、この問題を回避する方法はありますか?または、アプリケーションをパッケージ化するより良い方法はありますか?

AutoDeployをfalseに設定したくはないことに注意してください。また、Tomcat Manager Webアプリケーションの使用を除外する人為的なインストールをインストールに使用することはできません。

.warファイルから構成ファイルを取得し、[engine-name]/[server-name]/[app-name].xmlとして個別にコピーした場合、Tomcatはそれをアプリケーションに関連付け、新しい.warファイルをコピーしたら削除します。

もう1つの前提は、構成の値が事前にわからないことです。サンプル構成(必要に応じてプレースホルダー)のみを提供しますが、実際の構成はしばらくしてから実行されます(インストール時ではありません)。

ありがとう

49
n0rm1e

何とかこの問題を解決できました。

1-展開されたWARディレクトリをどこかにインストールします外部 TomcatのappBase、/usr/local/MyAppにあると仮定しましょう。 [アプリケーションが未展開のwarから実行される場合、WARディレクトリの代わりにこのステップにWARファイルを使用できます。]

2-コンテキスト構成ファイルを[Tomcat.conf]/[engine]/[hostname]ディレクトリにコピーし、MyApp.xmlと呼びましょう。このファイルは、アプリケーションの場所を指します。

<?xml version="1.0" encoding="UTF-8"?>
<!-- Context configuration file for my web application -->
<Context docBase="/usr/local/MyApp" privileged="true" antiResourceLocking="false" antiJARLocking="false">
        <Resource name="jdbc/myapp-ds" auth="Container" type="javax.sql.DataSource"
                maxActive="100" maxIdle="30" maxWait="10000" username="XXX" password="XXX"
                driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb" />
</Context>

3-これで、構成ファイルを自由に変更できます。

4-/usr/local/MyAppにアプリケーションの新しいバージョンをコピーして、アプリケーションを更新します

ノート:

a)このソリューションは、未展開の.warファイルにも適用されますが、SpringのLog4JConfigListenerを使用しているため、未展開の.warファイルからは実行されません。 Tomcatは、appBase(webapps)フォルダー外にある.warファイルを爆発させません。

b)このアプローチは、この構成ではTomcatによって使用されないため、context.xmlが/usr/local/MyApp/META-INF/context.xmlにあることを妨げません。開発環境で使用できます。開発環境では、.warファイルをappBase(webapps)フォルダーにダンプします。

これは私がこれまでに得たもので、より良い解決策を探しています。

11
n0rm1e

解決策は簡単です。context.xmlに構成を入れないでください。

私たちが使用するソリューションは次のとおりです(多くの多様な外部顧客に適しています)。

複数の環境で使用されるwebapp.warという単一のwarがあります。開発、統合、本番の3つの環境があります。統合と生産は顧客サイトにあります。クライアント統合および本番サイトのパスワードとファイルパスはわかりません。

データベースのものと外部プロパティファイルのJNDIルックアップの2つを組み合わせて使用​​します。

戦争で配信されるcontext.xmlには、ResourceLinkがあります

<ResourceLink name="jdbc/webapp"
     global="uk.co.farwell.webapp.datasource.MySqlDataSource" />

これは、Tomcatのserver.xmlで定義されているグローバルに定義されたデータソースへの参照を提供します。

<Resource auth="Container" 
          driverClassName="com.mysql.jdbc.Driver" 
          name="uk.co.farwell.webapp.datasource.MySqlDataSource" 
          password="xxx" url="xxx" username="fff" />

したがって、server.xmlを変更せずにwebapp.warを編集することにより、データベースの詳細を変更できます。重要なことは、これはサーバーごとに1回だけ行う必要があり、再デプロイ時ではありません。

スプリング構成では、dataSourceを定義するために次のものがあります。

<jee:jndi-lookup id="dataSource" jndi-name="jdbc/webapp" />

その他のプロパティについては、webapp.warとともに配信されるグローバルなapplication.propertiesファイルがありますが、これは戦争の一部ではありません。これは、Tomcatを起動するためのコマンドラインで-Dによって参照されます。 -Duk.co.farwell.webapp.applicationDir="/usr/xxx/fff"。定義を取得し、プロパティファイルを読み取ります。データベースの処理もこの方法で行うことができますが、Tomcatによるプーリングは失われます。

もう1つ:サーバーが移動した場合、または何らかの理由でマシンが変更された場合、再構築する必要はありません。これは、顧客とそのインフラストラクチャの人々の問題です。

42
Matthew Farwell

これが、.WARファイルからwebappコンテキストを外部化する方法です。

  1. Tomcat以外の場所に.WARファイルを配置します
  2. $ Tomcat_HOME/conf/[Engine]/[Host] /ディレクトリに$ APP_NAME.xmlファイルを作成します。
  3. ここで作成したファイル「$ APP_NAME.xml」には、コンテキスト定義とパラメーター+そのコンテキストに固有の任意のEnvironmentVariableが必要です。

例えばVirtualWebAppというwebappがあります。

以下のコンテキスト定義でVirtualWebApp.xmlのようなファイルを作成します。

<Context docBase="/home/appBase/VirtualWebApp" path="/VirtualWebApp" reloadable="true">
    <Environment name="webservice.Host" type="Java.lang.String" value="1.2.3.4" />
    <Environment name="webservice.port" type="Java.lang.String" value="4040" />
</Context>

これらの環境変数にアクセスするには、以下のコードを記述する必要があります(参照のみ)。

InitialContext initialContext = new javax.naming.InitialContext();

Host = (String)initialContext.lookup("Java:comp/env/webservice.Host");
port = (String)initialContext.lookup("Java:comp/env/webservice.port");
5
srv

Apache Tomcat 5.5 Documentation を参照することにより:

$ CATALINA_HOME/conf/context.xmlファイル内:コンテキスト要素情報はすべてのwebappsによってロードされます

このアプローチを簡単に試すことができますが、うまくいくかもしれませんが、Tomcatで複数のwebappsを実行している場合は特に、これが良いソリューションかどうかはわかりません。

4
user591593

@ n0rm1e:Tomcatが何らかの問題の解決策を提供しているかどうかはわかりません。ただし、考えられる解決策の1つは次のとおりです。

i)[engine-name]/[server-name]ディレクトリの.xmlファイルの存在を確認します。存在する場合は、これをバックアップするか、名前を変更します。

ii)warファイルをTomcat webappsにコピーします。 Tomcatサーバーを再起動します。

iii)バックアップされた構成ファイルを[engine-name]/[server-name]ディレクトリにコピーします

1
ag112

Tomcatの動作を変更する方法はわかりませんが、2つの異なるソリューションが考えられます。

  1. 環境ごとに異なる(パラメーター化された)ビルドスクリプト。そのため、ビルドスクリプトにenvというパラメーターを定義し、値に応じて、ビルド中にWARに環境固有のcontext.xmlを配置します。
  2. 環境ごとにinstallスクリプトを作成し、最初にWARファイルを再デプロイ(webappsディレクトリに配置)してから、環境に応じてTomcatインストールに変更を加えます。 context.xmlのJDBC DataSourceの異なるホスト名。

エンタープライズ環境で機能するため、後者のアプローチを多用します。多くの場合、職務分離ポリシーにより、開発チームは本番データベースのパスワード。オプション2は、ITオペレーションのみが作成された後、環境固有のインストールスクリプトにアクセスできるため、この問題を解決します。

1
home