web-dev-qa-db-ja.com

EARまたはWARの外部にJava EE構成パラメーターを格納するにはどうすればよいですか?

Webプロジェクトの構成をWebプロジェクトの外部(ear/warファイル)に保存したい。アプリケーションは、実行中のコンテナー(WebSphere/JBossなど)を認識してはなりません。

これを処理するための最良の方法は何ですか?

JNDIはクリーンな方法ですか? JNDIで問題を解決できる場合、どのように構成すればよいですか? (カスタムオブジェクト?)

私の場合、SOAP/WSエンドポイントには単純なKey =>値のペア(String、String)しかありません。

37
Martin K.

WARファイルの外部のプロパティファイルを読み取るには、これを参照してください 質問

JNDIから変数値を読み取るには、これを参照してください 質問 。これが最善の解決策だと思います。次のコードで文字列変数を読み取ることができます。

Context initialContext = new InitialContext();
String myvar = (String) initialContext.lookup("Java:comp/env/myvar");

上記のコードはすべてのコンテナで機能します。 Tomcatでは、conf /server.xmlで次のように宣言します。

<GlobalNamingResources ...>
  <Environment name="myvar" value="..."
         type="Java.lang.String" override="false"/>
</GlobalNamingResources>

上記はグローバルリソースを作成します。アプリケーションのコンテキストでリソースを定義することもできます。ほとんどのコンテナでは、JNDIリソースはMBeans管理コンソールから利用できます。それらのいくつかは、それらを編集するためのグラフィカルインターフェイスを提供します。変更が加えられた場合、せいぜいアプリケーションの再起動が必要です。

JNDIリソースの定義および編集方法は、コンテナー固有です。適切な設定を適用するのは、コンフィギュレーター/管理者の仕事です。

JNDIが提供する利点は次のとおりです。

  • パラメータのデフォルト値は、WAR/EARファイルで定義できます。
  • パラメータはコンテナで簡単に設定できます。
  • パラメータの値を変更するときに、コンテナを再起動する必要はありません。
27
kgiannakakis

さまざまな開発者向けにWebアプリをデプロイする場合、およびAmazonのEC2で同様の構成要件がありました。構成をバイナリコードから分離するにはどうすればよいですか?私の経験では、JNDIは複雑すぎて、使用するにはコンテナー間で大きく異なります。また、XMLを手動で編集すると、構文エラーの影響を非常に受けやすいため、アイデアは破棄されました。いくつかのルールに基づいた設計でこれを解決しました。

1)単純なname = valueエントリのみを使用する必要があります

2)新しい構成は、1つのパラメーターのみを変更することでロード可能である必要があります

3)WARバイナリは、再パッケージせずに再構成可能である必要があります

4)機密パラメータ(パスワード)がバイナリにパッケージ化されることはありません

すべての構成に.propertiesファイルを使用し、System.getProperty("domain");を使用して適切なプロパティファイルをロードすることで、要件を満たすことができました。ただし、システムプロパティはファイルのURLを指していません。代わりに、使用する構成を指定するために「ドメイン」と呼ばれる概念を作成しました。構成の場所は常に次のとおりです。
$HOME/appName/config/$DOMAIN.properties

したがって、独自の構成を使用してアプリを実行する場合は、ドメインを自分の名前に設定してアプリを起動します。
-Ddomain=jason
起動時に、アプリはファイルをロードします:
/home/jason/appName/config/jason.properties
これにより、開発者は構成を共有できるため、再コンパイルや再パッケージ化を行わなくても、テストとデプロイのためにアプリの同じ状態を再作成できます。次に、ドメイン値を使用して、バンドルされたWARの外部の標準の場所から.propertiesをロードします。

次のような本番構成を使用して、ワークステーションで本番環境を完全に再作成できます。
-Ddomain=ec2ロードします:
/home/jason/appName/config/ec2.properties

この設定により、環境ごとに異なる構成を使用して、コンパイルされたバイナリの正確に1セットで開発/ QA /リリースサイクルを実行できます。パスワードなどがバイナリにバンドルされるリスクはなく、ユーザーは構成を共有して、発生している問題を再現できます。

11
Jason Thrasher

環境変数を使用して、構成が含まれているURL(おそらくfile:// URL)をポイントします。これはセットアップが非常に簡単で、JNDIインフラストラクチャを必要としません。

ここにいくつかのサンプルコードがあります(メモリから入力されました-私はこれをコンパイル/テストしていません):

public void loadConfiguration() {
   String configUrlStr = System.getenv("CONFIG_URL"); // You'd want to use a more
                                                      // Specific variable name.
   if(configUrlStr == null || configUrlStr.equals("") {
       // You would probably want better exception handling, too.
       throw new RuntimeException("CONFIG_URL is not set in the environment."); 
   }


   try {
       URI uri = new URI(configUrlStr);
       File configFile = new File(uri);
       if(!configFile.exists()) {
          throw new RuntimeException("CONFIG_URL points to non-existant file");
       }
       if(!configFile.canRead()) {
          throw new RuntimeException("CONFIG_URL points to a file that cannot be read.");
       }
       this.readConfiguration(configFile);
   } catch (URISyntaxException e) {
       throw new RuntimeException("Malformed URL/URI in CONFIG_URL");
   }



}
10
Jared

クラスパス上にある通常のJavaプロパティファイルで、プロパティをロードするだけですか?

それは簡単でとてもシンプルです..何かが足りない場合を除いて

9
Aaron Saunders

私のお気に入りの場所は次のとおりです。環境変数とプロパティファイル(上記のJaredとkgiannakakisによって提案されたように)。

環境プロパティを格納するデータベーステーブル

ただし、もう1つの簡単な解決策は、データベーステーブルに環境プロパティを格納することです。

アプリケーションがデータベースを使用する場合

  • これは比較的簡単にセットアップできます
  • 値を制御/変更するための本当に簡単な方法を提供します
  • DBスクリプトの一部にすることで、プロセスにうまく統合できます。
4
Kartik Shah