Java 開発のディレクトリ構成

Copyright (C) 1997-2004 by Haruaki TAMADA All rights reserved.
Last Modified: Mon Jan 10 11:07:29 JST 2005

おしながき

ページのトップへ

序論

はじめに

大規模開発の場合、初期のディレクトリ構成が非常に大切となる。 私は今まで 2 年企業でエンタープライズ系の Java 開発要員として働いてきた実績がある。 その 2 年間で「こうしたら良いのでは」と思えるようなディレクトリ構成が多少なりともわかってきたので、 ここに書こうと思う。ただし、あくまで「私がこうすれば良い」 というディレクトリ構成であるので、 ここで説明する理由が該当しないプロジェクトにおいてはこの限りではない。

とは言え、ここで説明することはあながち的外れではないと思う。jakarta プロジェクトの多くのプロジェクトがここで説明するディレクトリ構成と、 似通ったディレクトリ構成を採用しているためだ。というか、私の方が真似したのが事実であるが。 CVS などを使ってリビジョンコントロールを行う場合には、 ここで説明するディレクトリ構成を一度は試して頂きたい。

最近、私はどんな小さなプロジェクトでも、 このディレクトリ構成が基本となっている。

ビルドツールの選択

プロジェクトの開発において、まず最初にプロジェクトを構築するために、 ビルドツールの選択をしなければならない。 Java の開発の場合、多くは ant であろう。今後、maven が増加していくかもしれないが、どちらにしろ、 大きくは変わらない。

しかし、make や、独自のビルドツールを使う場合はここで述べるノウハウは通用しない場合がある。 ビルドツールの選択が密かにプロジェクトのディレクトリ構成に影響を与えるのだ、と思う。

ページのトップへ

ディレクトリ構成

ディレクトリ構成

私の勧めるディレクトリ構成をまず御覧頂きたい。

root + build.xml
     + build.properties
     + build.properties.sample
     + src + java 
           + conf
           + content
           + web
           + xdocs
           + sql

大体以上のような構成となる。 プロジェクトのルートディレクトリにビルドツールのためのファイルがあり、 src ディレクトリ以下に Java のソースファイルや jsp, html などのファイル、アプリケーションの設定ファイル、 SQL 関連のファイルやドキュメントなど、 それぞれのディレクトリに分けて配置される。 場合によってはスクリプトファイルのディレクトリ script が加わる。

このディレクトリ構成で考えられることは、 アプリケーションを構成するファイルはソースファイルのみではない、 ということだ。一つのアプリケーションを構成するファイルとしてはエンタープライズ系のアプリケーションであると 以下のようなファイルがある。

以上のファイルがあって初めてアプリケーションの初期設定やビルドを行うことができる。 言ってみれば以上のファイルすべてがソースファイルであるということだ。

今までこのような開発に携わっていない方にとって、 最初にここまで考える必要があるのか疑問であるかもしれない。 しかし、ここまで考えないとそのプロジェクトは後々破綻する。

エンタープライズ系など大規模開発の際には、 一人で開発するというプロジェクトはまず存在しない。 複数の人間で開発を行う。そして、バージョン管理システムを必ず使用する。 CVS や VSS を使用することとなる。 CVS を使った場合、ディレクトリ構成の変更は多大なリスクを伴う。 だから、多くの場合、基本的にディレクトリ構成は変更しないという方針となる。 VSS を使った場合はディレクトリ構成を変更することは簡単であるが、 ここで述べる以外の場合において問題が出てくる場合が多い。 (主観である。VSS で開発をしたことはあるし、できないこともないと思うが、 円滑に開発するための事前の決め事が多くなると思うので私は、 VSS で開発はしたくない) なので、ディレクトリ構成の変更は行わないという方針で、これ以降説明する。

失敗例

このようなディレクトリ構成をとることで利点がある。 論理的なファイルの意味がディレクトリにより区別できるのだ。 以前、以下のようなディレクトリ構成でプロジェクトを開発した経験がある。

root + build.xml
     + build.properties
     + src(Java ソースファイル)
     + jsp 
     + conf(設定ファイル)

一見問題ないようにも見える。しかし、conf ディレクトリに問題がある。 ビルドのための設定ファイルや javadoc 用の設定ファイル、 アプリケーションの設定ファイルがそのディレクトリ以下に混在しているのだ。 これはわかりにくい。 そのプロジェクトはビルドツールに ant を採用していたが、ファイルをコピーする際の copy ターゲットにネストされる filesetincludeexclude を設定ファイルを加える度に変更する必要があるのだ。

最初、問題は出てこないだろう。 しかし、3 カ月、4 カ月と開発を続けていくうちに破綻をきたす。 war(Web Archiver) ファイル作成失敗や ejb jar ファイル作成失敗など頻繁に合いたくない。 なので、ビルド時に必要なファイルと運用時に必要なファイルを、 論理的に明確に分けておく必要があると痛感した。

このようなディレクトリ構成の理由

このようなディレクトリ構成にするにはもちろん、理由がある。 先の 失敗例 のようにプロジェクトのルートディレクトリの直下に jsp や src(Java のソースファイル) を置いておくと、 ルートディレクトリのエントリが増加していく。それに伴い、 ルートディレクトリ全体の見通しが悪くなる。

ルートディレクトリの中のエントリが 15 以上あると、これは見通しが悪い。 しかも見通しが悪いため、論理的なファイル管理ができない場合が多い (少なくとも私はそうだった)。

「それならば、jakarta のプロジェクトのようにやってみようか」 と思った次第である。この構成の場合、アプリケーションを構成するファイル群は src 以下に必ず置かれている。 (ライブラリは後述) そして、src 以下に存在するのはアプリケーションの初期設定を行うための SQL が書かれたファイルや、javadoc のための overview.html など、運用時には必要のないファイルも存在する。 これらも src ディレクトリ以下のディレクトリに置くのだ。

私の場合、src ディレクトリ以下は次のように考えている。

src/java
Java のソースファイルをパッケージ階層毎のディレクトリに置く。 JUnitTestCase であっても、この src/java ディレクトリ以下に置く。
src/web
Web アプリケーションで View に当たるファイルを格納するディレクトリ。 格納されるファイルは html かもしれないし、php かもしれない。 また、jsp や vm かもしれない。しかし、このディレクトリには html でも js でも css でも View に該当するファイルを置く。
src/sql
SQL DDL ファイルや Jakarta Torqueproject-schema.xml など、SQL に関するものを置く。 ファイル数が多くなるようならば、このディレクトリも考えた方が良いかも。 アプリケーション構築の際にしか使わない場合は無視しても良いだろう。
src/conf
アプリケーションの設定ファイルを置く。 もし、複数のサーバにインストールし、 サーバにより設定が少しでも変わる場合は、 サーバ毎にディレクトリをこの src/conf 以下に掘り、 その下に設定ファイルを置く。その時、各サーバ共通で使うファイルは src/conf/common ディレクトリに置いておいても良いかもしれない。
src/content
javadoc 用のファイルや MANIFEST.MF など直接アプリケーションに関係しないファイルを置く。 余り多くないようならば、 アプリケーションに与えるためのサンプルファイルも置いておいても 良いかもしれない。
src/script
なくても構わないが、 あると数段便利というスクリプトを置いておくディレクトリ。 プログラム起動用スクリプトもこのディレクトリに置くのが良いだろう。
src/sample
サンプルファイル。このサンプルも論理的にディレクトリを分けて管理する
src/xdocs
ドキュメント関連ファイル。私は多くの場合、 anakia でドキュメントを書くので、このディレクトリには ドキュメントの元となる xml や vsl ファイルがある。 Velocityanakia、 xslt、 Cocoon を使わないのであれば src/docs になるだろう。

ライブラリ

私はライブラリをプロジェクトのルートディレクトリ直下の lib ディレクトリに置いている。

今までと矛盾する。アプリケーションを構成するファイルであるのに、 src/lib ではない。src 以下に置くべきと 言ったのは確かに私だ。しかし、依存ライブラリは少し話が違ってくる。

war ファイルの場合、WEB-INF/lib 以下に置けば、 コンテナが自動的にクラス検索パスに加えてくれる。 また、ear(Enterprise Archiver; war + ejb jar) ならば ejb jar ファイルの MANIFEST 属性に Class-path を加えておけば良い。

しかし、以上のライブラリの区別は人がするしかない。 加えて、昨日まで WEB-INF/lib に置いていたファイルが、 今日は ear からも使うようになったので WEB-INF/lib に置くようになるということもある。(余り起こってはいけないことだが) ビルド時のみに必要なライブラリもある。(JUnit や xml 関連ライブラリ。 xml 関連ライブラリはアプリケーションサーバなどが同じライブラリを 使っている場合は WEB-INF/lib 以下には置かない方が良いと思う。 以前それで NoClassDefFoundError というものに 1 時間ほど悩んだ経験がある) しかも、maven を使うと、このディレクトリは必要なくなってしまう。

ライブラリはややこしいのだ。確かに私も現状の構成が良いとは思っていないが、 正直、そこまで突っ込んで考えてないだけなのだ。

ページのトップへ

まとめ

個人的にはここで説明したように、ソースファイルを src ディレクトリ以下にファイルの種類ごとにディレクトリを分割するという構成が最適だと思う。 実際に Jakarta プロジェクトの 多くのプロジェクトが似たような構成を取っている。私が真似したのだから当たり前だ。

プロジェクトのディレクトリ構成を考えるのは実は非常に奥が深い。 Eclipse のデフォルトのディレクトリ構成は上記で勧めた構成にはならない。 Eclipse のみを使っているのであれば別に構わないし、私自身もここで書いていることが絶対だとは思わない。 しかし、私は Eclipse などの IDE を使わない場合はこの構成が良いと思う。

もちろん、この構成だとディレクトリが深くなり、Windows の Explorer を使っている人は辿りにくくなるだろう。 私は Explorer は使っていない。というか、Windows を良く知らず、cygwin を使っている。 cygwin を使っていると tab で補完されるので、あまりディレクトリ移動に苦労を感じたことがない。 とは言うものの、この構成は cygwin を知らない私の元同僚の評価は悪くはなかった。 (文句を言われなかっただけかもしれないが)

ディレクトリ構成は突き詰めれば好みの問題である。今までの提案を無に帰すような結論だが、 結局は好みの問題なのだ。 好みの問題ではあるが、色々なディレクトリ構成でしっくり行かないと感じている人は少なくないと個人的に思う。 そのような方はここで書いたディレクトリ構成を一度実践してもらいたい。

ページのトップへ