jar内にプロパティ/構成ファイルを含めることは悪い習慣ですか?
-
05-07-2019 - |
質問
例:
MyAppは、アプリの構成データ(サーバー名など)を説明するプロパティファイル(server.properties)を含むWebアプリです。開発段階では、server.propertiesは独自のIDEプロジェクトフォルダーに配置されます(論理的な場所)。
次は、MyAppを展開するときです。 IDEは、クラスファイルとサポートする構成ファイルをjarすることを非常に簡単にします。これで、適切なWebコンテナにJarをドロップして、先に進みます...
1週間後... MyAppが使用するサーバー構成データを変更する必要があります。どちらがより理にかなっていますか?
A。 IDEランドでserver.propertiesファイルを変更し、完全に新しいjarファイルを生成します。再デプロイします。 (これは、単純な構成変更のためにアプリをバウンスすることを意味します。)
B。既にデプロイされているJarをクラックして開き、server.propertiesファイルを変更しますか? (server.propertiesがキャッシュされている場合、MyAppの更新機能を呼び出す必要がありますが、完全なアプリバウンスを必要としない必要があります。また、将来のデプロイでserver.propertiesが戻らないようにソースserver.propertiesも変更する必要があります古いサーバー名に)。
C。最初に、jarファイルの外部にserver.propertiesを作成します。 Bのプロセスに非常に似ていますが、構成データをjarの外部に保持するというわずかな違いがあります(開発デプロイと実稼働デプロイの間に異なるパスが導入されます)
D。その他:
ありがとう!
解決
Dと一緒に行きます。
.jarの外部からプロパティファイルをロードし、それが失敗した場合は、jarに組み込まれているプロパティをロードします。
これにより、「既製」をプッシュできます。ビルドごとの設定(ファイルが1つだけの場合はデプロイメントの複雑さも軽減します)と同時に、設定のオーバーライドを可能かつ合理的に簡単にします。
他のヒント
Springを使用している場合、プロパティプレースホルダーを使用して作業を行うことができます。
<!-- try and resolve the config from the filesystem first and then fallback to the classpath -->
<context:property-placeholder location="file:config.properties, classpath:config.properties"
ignore-resource-not-found="true"/>
ファイルシステム上およびクラスパス上でリソースを指定できます。Springは最初にファイルシステムのすべてのプロパティを解決しようとし、次にクラスパスにフォールバックします。 &quot; ignore-resource-not-found&quot;を指定することにより、 &quot; true&quot;としての属性ファイルがファイルシステムにない場合にSpringが例外をスローするのを防ぎ、代わりにクラスパスからプロパティを解決できるようにします。
この組み合わせを使用すると、プロパティを2つのファイルに分割することもできます。たとえば、クラスパスのファイルにパスワードを指定したり、ファイルシステムの外部で指定したりすることはできません。ファイルシステムにないプロパティは、クラスパスから解決されます。
以下を含むフォルダ内
application.jar
config.properties
使用できるはずです:
java -jar application.jar
これは参照用のサンプルconfig.propertiesです:
# This file contains properties that are used to configure the application
database.url=127.0.0.1
database.port=3306
database.user=root
database.pass=p4ssw0rd
状況によります。プロパティファイルに、アプリケーションまたはライブラリのユーザーが変更することを意図したデータが含まれている場合は、外部に保存する必要があります。
静的なデータが含まれていて、ソースコード内の値のコーディングを避けるためだけにプロパティファイルを作成した場合、またはファイルがローカライズされた文字列である場合、jarに残します。少なくとも、プロパティファイルは値を変更するように人々を招待するためです;)
D。
jarのプロパティをロードします。次に、jar-edプロパティをデフォルトとして使用して、新しいプロパティを作成します。次に、jarの外部からロードします。これにより、プロパティのカスタマイズを選択できます。
J2EEでは、J2EE環境の外部からファイルにアクセスできることは保証されないことに注意してください(直接ファイルアクセスはできません)。
JNDIを使用して、データを含むデータソース、またはデプロイメントアーティファクトのプロパティファイルを指す必要があります。
たとえば、Websphereは、デフォルトではファイルへの直接アクセスを許可しません。オプションD.さまざまな環境で、データベースやプロキシなどへの接続などの環境プロパティを指定する必要がある場合があります。
注目に値する他のことは、実稼働環境では、jarを事前にパッケージ化したり、jar内のプロパティファイルを置き換えたりすることなく、プロパティをすばやく変更したい場合があることです。
E.g。データベースサーバーが転倒し、別のサーバーを指す必要があります(データベースのロードバランサーを使用していない場合)。したがって、データベースプロパティを置き換えて再起動するだけです。そこで多くの時間を節約できます。
多くの場合、コードをテストから実稼働に変更しないに移行することが基準です。これは、埋め込み構成ファイルを編集できないことを意味します。また、デプロイされた構成を変更する必要がある状況になる場合があります。これは非常に面倒です。したがって、構成はjarの外に残します。
Java EEアプリケーションでは、クラスパス内のJNDIまたはプロパティファイルを考慮してください。
私は、単に2つを分離するために、設定が近隣のWebアプリケーションから取得されるWebアプリケーションを持っています。それははるかに簡単であることが判明しました。
webapps(WAR)でプロパティファイルを使用しますが、ほとんどの場合、デフォルト値および多かれ少なかれ不変のものに使用します(webappsは可能な場合でもWARを更新すべきではないため)。
しかし、あなたが話しているようなものには、JNDIを使用します。 web.xmlファイルでリソースとしてプロパティを定義できます。そうすれば、最悪の場合、アプリ自体ではなくweb.xmlを更新します。
一部のサーバーでは、WARにまったく触れずにこれらのリソース値をオーバーライドする方法があります。たとえば、Tomcatで。
私は通常、テスト、Q / A、および本番用に1つのWARを作成し、TomcatのContext xmlファイルを使用して、まさにこれで環境に依存するリソースをオーバーライドします。私がテストしているアプリは実稼働中のアプリとほとんど同じであるため、複数のWARを構築したり、WARSを変更したりするよりも、これがはるかに優れていると考えています。
答えは、構成のバージョン管理が必要かどうかによって異なると思います。 (本番環境の構成またはリグレッションテストの構成になります...)
- バージョン管理が不要な場合は、プロパティファイルをオーバーライドする外部プロパティファイルを使用するオプションDが適しています。オプションBとCはより詰め込みやすいですが、本当に気にしたい場合はバージョン管理を使用します:-)
- バージョン管理が必要な場合、オプションAを使用するとより多くの管理が可能になりますが、複数の展開の可能性がある場合は、各展開の構成をバージョン管理することもできます。例は、テストプラットフォームと実稼働プラットフォームへの個別の展開です。
MavenモジュールとMaven WARファイル&quot; overlays&quot;を使用してこれを行う方法は次のとおりです。
- Javaコードコンポーネント用の複数のモジュールがあります。これらはJARモジュールです。
- 「ベースwebアプリ」があります。静的コンテンツ、JSP、およびコア構成データ(スプリング配線、デフォルトプロパティ)のモジュール。これはWARモジュールであるため、ビルドの結果は上記+すべてのJARファイルを含むWARになります。
- 個別の「サイト構成」プロパティ、配線ファイル、コンテンツのサイト固有のオーバーライドを含むWARモジュールです。オーバーライドは、Maven WARの「オーバーレイ」を使用して説明されます。メカニズムにより、「ベース」から新しいWARが組み立てられます。 WARおよびオーバーライド。
これらはすべてバージョン管理にチェックインされており、構成を変更するにはMavenビルドとWARデプロイメントを行う必要があります。
同様の質問をしました。私たちはまだすべてを理解していません。しかし、私たちはURLリソースを検討しています。プロパティファイルがSVNから直接読み取られる場所。プロパティファイル以外を更新する必要はありません。
Springを使用してJ2EEアプリケーションを開発しています。私は同じ問題をかなり長い間実行していて、解決策を見つけました。 私の問題は、展開するwarファイル以外のプロパティファイルでデータベースプロパティを指定することでした。私がこれを見つけた解決策は、PropertyPlaceholderConfigurerを使用し、場所のプロパティを指定してシステムの場所をこのように見つけることです
これは非常に簡単で、うまく機能しました!