Eclipse プロジェクトの再読み込みなしでリソースを更新する
Eclipse 外で HTML ファイルや prpperties ファイルなどを修正した場合、Eclipse プロジェクトを都度再読み込み(更新)し、修正したリソースファイルを Eclipse に認識させてやる必要があります。WEB アプリ開発などでは頻繁に HTML ファイルやテンプレートファイルを修正するため、その都度 Tomcat を止めて Eclipse プロジェクトを更新する、というのは非常に非効率です。Java クラスについては、メソッドやクラスの定義が変わらない限り Servlet コンテナを止める必要はないのですが、リソースファイルの修正にはまだまだ弱いのが現状です。リソースファイル変更時に Eclipse プロジェクトの更新が必要になるのは、Eclipse プロジェクトのレイアウトとして、リソースファイルが配置されるディレクトリと実行/デバック時に Eclipse がクラスパスを通すディレクトリが異なるためです。例えば Maven プロジェクトでは、リソースが配置されるのは src/main/resources ですが、Eclipse がクラスパスを通してくれるのは target/classes になります。Eclipse は Eclipse プロジェクトの更新時などにリソースファイルを src/main/resources 下から target/classes 下にコピーし直すのですが、逆にいうと、いくら src/main/resources 下のリソースファイルを書き換えても、target/classes 下にコピーされない限り(クラスパスの通ったリソースファイルは古いままなので)プログラムはリソースとして読み込むことができません。
target/classes 下のリソースファイルを修正すれば一応クラスパス上のリソースを変更することはできますが、次にリソースディレクトリからリソースファイルがコピーされた時に上書きされて巻き戻ってしまいます。
これを解決するため、読み込むリソースファイルの場所を任意のディレクトリに切り替える仕組みを作ってみました。
Eclipse Project Loader
https://github.com/momokan/eclipse-project-loader (github)Eclipse Project Loader を使うことで、クラスパス内のリソースファイルをクラスパスの通っていない別のディレクトリから読み込むことができるようになります。そのため、プログラムがリソースファイルを読みにいくたびに、最新のリソースファイルにアクセスすることができるようになります。
Eclipse Project Loader の使い方
プロジェクト管理ツールとして Maven を利用することを前提に、Eclipse Project Loader の使い方を記載します。まずは Eclipse Project Loader のソースコードをチェックアウトし、Maven ローカルリポジトリにインストールしてください。
現時点では Eclipse Project Loader は Maven Central Repository にはないので、利用するにはビルド/インストールしてやる必要があります。
$ git clone -b ver0.1 https://github.com/momokan/eclipse-project-loader.git $ cd eclipse-project-loader $ mvn clean install
次に、Eclipse Project Loader を利用する側の Maven プロジェクトで、以下の依存性を pom.xml に追記します。
<project> ... <dependencies> ... <dependency> <groupId>net.chocolapod</groupId> <artifactId>eclipseprojectloader</artifactId> <version>0.1</version> </dependency> ... <dependencies> ... <project>依存性を追加したら、mvn eclipse:eclipse 実行後に Eclipse プロジェクトに読み込ませてください。
$ mvn clean eclipse:eclipseEclipse 上で、Package Explorer の Referenced Libraries に eclipseprojectloader-0.1.jar があれば OK です。
最後に、実行/デバッグ時に Eclipse Project Loader を適用させるため、VM の実行時引数に
-Djava.system.class.loader=net.chocolapod.eclipseprojectloader.EclipseProjectClassLoader を追加します。Java アプリケーションとして実行する場合は Eclipse の Run メニューから Run Configuration... / Debug Configuration... を開き、実行する Java アプリケーションの VM 引数に書き加えてください。Spring boot では Tomcat 自体も Java アプリケーションとして実行するため、この手順で Eclipse Project Loader を利用することができます。
確認していませんが、Sysdeo Tomcat Launcher Plugin を利用する場合にも、Tomcat への VM パラメーターに設定することで有効化できると思います。
Maven を使っていない場合も大まかな設定は同じです。クラスパスに eclipseprojectloader-0.1.jar を追加し、Eclipse でのデバッグ実行時に VM 引数として -Djava.system.class.loader=net.chocolapod.eclipseprojectloader.EclipseProjectClassLoader を追加してください。
Eclipse Project Loader の仕組み
Eclipse Project Loader は URLClassLoader を拡張して実装されています。Java では java.lang.ClassLoader.getResource(String) によってクラスパス上からクラスファイルやリソースファイルが読み込まれます。Eclipse Project Loader は読み込んだリソースがクラスファイルでなく、target/classes ディレクトリ内のリソースである場合、そのパスを src/main/resources 内のリソースに変換します。これにより、リソースディレクトリ内のリソースファイルを、クラスパスの通ったディレクトリではなく、リソースディレクトリから読み込むことになります。Java はシステムが用意する最初のクラスローダー(Bootstrap Class Loader)を、VM 引数の -Djava.system.class.loader で変更することができます。Java のクラスローダーを Eclipse Project Loader に差し替えることで、リソース検索のしくみ自体を差し替えることができます。
リソースファイルの検索場所を変更する
Eclipse Project Loader は、デフォルトでは Maven のプロジェクトレイアウトで動作するよう設定されています。Maven のレイアウトでは、コンパイルしたクラスファイルなど、実行時に classpath に指定されるディレクトリは target/classes、リソースファイルが配置されているリソースディレクトリは src/main/resources です。例えば、クラスパス上から application.properties を読み込む際には、Eclipse Project Loader はそのリソースのパスを target/classes/application.properties から src/main/resources/application.properties に変換します。Maven を利用しない場合、そのプロジェクトレイアウトに応じて Eclipse Project Loader の設定を変更してください。設定は、プロジェクトのディレクトリ内に .settings/eclipseProjectConfig.properties を作り、以下のように変更することができます。
# Eclipse が実行時にクラスパスを通すディレクトリ target.dir=target/classes/ # リソースディレクトリ resources.dir=src/main/resources/例えば、target.dir 値を compiled、resources.dir 値を etc とした場合、Eclipse Project Loader はクラスパス上のリソースファイル: application.properties のパスを compiled/application.properties から etc/application.properties に変換します。
Eclipse Class Loader コメント (0) 2014/11/29 19:41:00