Developer Tools
JDeveloper
Subversionによるチーム開発Oracle JDeveloperのHow toドキュメント
概要 開発チームでは、たとえ最小規模のチームであっても、それぞれのソース・コードを常に管理された状態にしておく必要があります。 ソース・コードを管理する場合、手作業によるシステムをはじめ、データベース、市販または社内で作成したソース・コード管理(SCM)システムなど、さま ざまな手段があります。 ただし、どのシステムを使用する場合も、以下の基本機能を実行できることが条件となります。
サポート対象のバージョン・コントロール・システムJDeveloper では、数多くのバージョン・コントロール・システムがサポートされています。 このため、JDeveloperをクライアントとして使用して、バージョン管理用の特定のリポジトリに接続し、JDeveloper内でバージョニングさ れたコードを処理できます。 これにより、開発者はSCM(ソフトウェア構成管理)の操作を実行するために別のツールを開いたり各自のIDE(統合開発環境)の外に移動したりする必要 がなくなるため、生産性の大幅な改善が可能です。 JDeveloper 11gのSubversion(SVN)では、IDEへの直接的なサポートが提供されています。 JDeveloper 11gでは、SVNでのソース・コントロールのサポートを重視しながらも、ほかのシステムに対するサポートがさらに強化されており、JDeveloper に統合されているシステム(CVS)や、Clear CaseまたはPerforceなどの製品に対するダウンロード可能な拡張機能までを含め、幅広く対応しています。
なぜSubversionなのかSVNは、アプリケーションのバージョン管理をおこなうための事実上の標準として、急速に普及しているオープンソースの強力なバージョン・コントロール・ システムです。 SVNが導入される前に広く利用され、現在も使用されているオープンソースのシステムとして、Concurrent Versions System(CVS)がありますが、SVNはこのCVSをさらに改善し、その制限の一部を克服できるように開発されたものです。 SVNについては 無料のオンライン書籍が ありますが、ここにはその使用方法だけでなく、CVSと比較した場合の改善点についても詳細な説明が記載されています。 この書籍を読めば、SVNの概念を確認して理解を深められると同時に、JDeveloperのSVNサポートが最高のものであるという確信を得ることもで きます。 CVSとSVN間のおもな変更の1つとして、SVNではアトミック・コミットがサポートされている点が挙げられま す。 SVNでは、ファイルをコミットした場合、コミットされた変更のすべてが実行されるか、まったく実行されないかのいずれかになります。 つまり、ネットワーク障害や変更済みコードの一部に競合があるなどの問題が発生した場合、一部のファイルだけがコミットされてほかのファイルが拒否される ことはありません。 これはCVSの欠点の1つであり、Javaファイルとそれに対応するXMLメタデータ・ファイルなどのように、ファイル間に依存関係があるアプリケーショ ン開発をおこなう場合、とくに重要な問題となります。 SVNを利用するもう1つの利点は、ファイルとフォルダの両方に 対するバージョニングが完全にサポートされていることです。 どちらについても完全な履歴がSVNサーバーに保存され、これによりファイルやフォルダの追加、削除、コピー、および名前の変更が可能となります。 CVSの場合はファイルのバージョニングにしか対応しておらず、ファイルが含まれたフォルダについてはバージョニングされていないため、'本当'の意味で の完全なバージョン履歴はありません。 また、ファイルを同一名の新しいファイル(完全に関係のないファイル)と置き換えても、置換え後の新しいファイルで新規の履歴が作成されることはなく、重 複しているファイルのそれまでの履歴が更新されます。 さらに、CVSでファイル名を変更すると、そのファイルのバージョン履歴は失われてしまいますが、Subversionでは新しい要素に履歴がコピーされ ます。 複数の開発者が同一ファイルで作業をおこなう場合、ほかの開発者の作業を誤って上書きしてしまうことのないようにシ ステムを設定する必要があります。Subversionでは、このような問題への解決策として、コピー・修正・マージ・モデルが用意されています。 このモデルでは、ファイルを使用する開発者それぞれが、そのファイルのコピー(作業用コピー)をとり、そのコピーに対して修正をおこなって、そのあとにリ ポジトリ内の最新コードとマージする処理を実行します。 この方法はファイルの内容に頻繁に競合が発生してしまうように思われますが、実際にはそのようなことはほとんどありません。 また、競合が発生した場合にそれを解消するための効率的な方法も用意されています("コード競合の解消"を参照してください)。 どのような開発プロジェクトでもそうですが、使用するアプリケーションの設定とそのアプリケーションのSVNリポジトリ構造の設定にかかる時間は、費やす価値のある時間です。 バージョニング・レベル開発チームでよく問題となるのが、'どのレベルでコードのバージョニングをおこなえばよいのか'という点です。 その答えは常に同じです。つまり、バージョニングは最上位レベルでおこなうべきです。 JDeveloperを使用している場合であれば、最上位レベルとは アプリケーション・ レベルを指します。 これは、JDeveloperの開発のためにオラクルで内部的に採用されている方法ですが、ベスト・プラクティス実現のための最高のヒントでもあります。 初期インポート新 規の開発に取りかかる際、アプリケーションのSVNリポジトリへの初期インポートを実行しなくてはならない場合があります。 このSVNリポジトリの設定は、開発の初期段階、それも最初のアプリケーションの作成後におこなうことをお勧めします。 推奨される標準のリポジトリ・レイアウトを実現するには、Trunk、Branches、Tagsの3つのフォルダが含まれた<アプリケーション名 >ディレクトリを作成します("ブランチング"を参照)。 JDeveloperでは、Subversionナビゲータを使用すると、リポジトリに新規フォルダを追加して新しいアプリケーションを直接配置できます(図1参照)。また、JDeveloperのインポート・ウィザードを使用してフォルダを作成することも可能です。 このインポート・ウィザードに従うことで、初期アプリケーションをリポジトリにインポートする手順を実行できます。 ウィザードを開くには、アプリケーションのドロップダウン・メニューから「 Versioning」→「 Import Files」 を選択する方法がもっとも簡単です。 インポート終了後、ソース・コードを保存するフォルダの作成、インポートについてのコメントの追加、初期インポートからのファイルまたはファイル・パター ンの除外("ファイルの除外"を参照)のほか、開発作業のためのローカル作業用コピーに対するコードの自動チェックアウトなどが可能となります。 作業用コピーJDeveloper の統合されたSVNナビゲータとアプリケーション・ナビゲータを使用すると、SVNの概念である作業用コピーを簡単に有効利用できます。 たとえば、アプリケーションの作業をする場合には、SVNのリポジトリから各アプリケーションをチェックアウトします。 ここでチェックアウトしたコピーが作業用コピーとなります。 JDeveloperでは、標準のCommitおよびUpdateの2つのSVNコマンドに加え、追加のコマンド
Commit Working Copyと
Update Working Copyが用意されています。 この2つのコマンドを使用すると、アプリケーション・ナビゲータにおいてどのノードからコマンドを呼び出しても、作業用コピー内のファイルすべてをコミットまたは更新できます。 図2は、
アプリケーション・ナビゲータのhome.jspxノードから、Commit Working Copyメニューを呼び出す場合を示しています。
開発チームでJDeveloper以外のツールを使用している場合JDeveloper を使用している場合、アプリケーション・レベルでバージョニングをおこなう必要があります。 これは、.jwsおよび.jpr構成ファイルがソース・コントロールに含まれるようにするためですが、この点はプロジェクト間に依存関係がある場合とくに 重要です。 では、開発チーム全体でJDeveloperを使用していない場合は、どうなるでしょうか。 たとえば、JDeveloperだけでなく、EclipseやほかのIDEを使用しているチーム・メンバーがいてもおかしくはありません。 このような場合であっても、'jws'と'jpr'の両方のファイルをソース・コントロールに置くことが重要なポイントです。 な ぜでしょうか。それは、JDeveloperでは、この2つのファイルのステータスを参照して、使用可能なバージョニング・メニュー・オプションを決定し ているためです。 たとえば、アプリケーションを作成するプロジェクトで、SVNへのインポートは実行済みであるが、ルート・レベルのアプリケーション・フォルダと.jws ファイルが含まれていない場合を考えてみます。 このケースでは、SVNナビゲータのリポジトリ全体でバージョニングされたファイルをチェックすると、アプリケーション・ルート・フォルダに.jwsファ イルがないことがわかります。 この問題を解決するために、空のアプリケーションを新しく作成し、JDeveloperプロジェクトをその新規アプリケーションにチェックアウトしたとし ます。 しかし、アプリケーション・レベルでVersioningメニューにアクセスすると、'Import Files'が表示されます。これは、.jwsファイルがバージョニングされたコードに含まれていないため、JDeveloperはバージョン・コント ロールにアプリケーションを配置するためのオプションを選択するからです。 この現象が発生した場合、リポジトリに戻り、.jwsファイルをバージョン・コントロールに追加することで問題を回避できます。 これにより、IDEの問題が解決され、JDeveloperの統合SVNサポートを引き続き使用できるようになります。 開発プロセスにおいてプロジェクト・レベルのコミットが必要な場合上 記のシナリオでは、プロジェクトを空のアプリケーションにチェックアウトすると、アプリケーション・レベル(ベスト・プラクティス)でのバージョニングの 代わりとなります。 個々のプロジェクトをチェックアウトすると、各プロジェクトの作業用コピーが作成されます。 つまり、個々のプロジェクトを個別のエンティティとしてコミットして更新できます。 ただし、この処理をおこなう場合にはプロジェクト間のあらゆる依存関係を理解しておくこと、そしてほかの開発者も同時に作業をおこなっているプロジェクト については慎重に更新することの2点に注意してください。 また、よりよい方法として、ベスト・プラクティスであるアプリケーション・レベルでのバージョニングの実行を徹底し、JDeveloperの Pending Changesウィ ンドウを使用してプロジェクトごとのコミットをおこなう方法が挙げられます。 Pending Changesウィンドウには以下の3つのタブがあります。これらのタブに、IDEで開かれているバージョン管理対象の個別アプリケーションおよびプロ ジェクトに関する情報が表示されます。
Update コマンドを使用するか、手動で変更の参照と追加をおこなうかは、対象となる変更の数と複雑さ、そしてソースの読みやすさによって異なる可能性があります。 また、その変更自体の性質も、もう1つの重要な考慮事項として挙げることができます。 多くの場合、とくにOracle Application Development Framework(Oracle ADF)などのフレームワークを使用した作業環境においては、Javaファイルとそれに対応するXMLメタデータ・ファイルとの間に依存関係があるケース で、変更を手動でおこなうとエラーが発生しやすくなります。 このため、Historyタブを使用して変更を事前に手動で参照したかどうかにかかわらず、Update Working Copyメカニズムを使用してリポジトリからコードを更新することをお勧めします。 場合によっては、Historyタブを使用すると、変更とその変更の作者を特定できます(図6を参照)。作者を特定することができれば、その変更による コードへの影響について不明な点がある場合に連絡を取ることも可能となります。 アプリケーションにないほかのコードをチェックアウトする必要がある場合この状況は、開発組織において'標準'のコードまたはライブラリ以外の読取りがおこなわれていない場合に発生します。 このような場合、各開発者が該当するコードをチェックアウトして各自のアプリケーションに手作業で追加するよりも、 svn:externalsプ ロパティを使用することをお勧めします。 この方法を使用すると、1度アプリケーションでプロパティを設定すれば、SVNからアプリケーションをチェックアウトするユーザーすべてが正確に同じコー ド・セットと関連するライブラリを取得できるメリットがあります。 SVNのプロパティについては、前述のSVNについての書籍に詳細な説明が記載されています。 図4は、JDeveloperの Add Subversion Propertyダイアログを示しています。 この例では、ライブラリadflibStoreFrontService.jarがSVNリポジトリ内のURLからexternal_jarsと呼ばれるフォルダにチェックアウトされることを示す値のペアが、 Value Stringフィールドに入力されています。 フォルダexternal_jarsは、ダイアログの Resource Fileで 指定されているリソース・ファイルで作成されます。 これは、アプリケーション・ナビゲータのこのノードでダイアログを呼び出すと設定されます。 ライブラリの正しいURLは、Subversionナビゲータの該当するノードでCopy URLコマンドを使用して取得したものです(図1参照)。 バージョン管理からのファイルの除外SVN リポジトリからファイルを除外するにはいくつかの方法があります。 まず、初期インポート時にファイルを除外し、特定のパターンのファイル名がリポジトリに追加されないようにする、または除外する特定のファイルをマークす る方法があります。 JDeveloperでは、これにより、特定のファイル・タイプが管理の必要がないものと認識されるようになります。また、JDeveloperには、 Subversionのプロパティ svn:ignoreを使用する機能も用意されています。 初期インポート時の除外処理前述のとおり、アプリケーションの初期インポート時にフィルタを追加してファイルを除外できます。 JDeveloperでは、 無視するファイルのリストを 使用して、コンパイルされたJavaクラス(.classファイル)などのバージョニングの必要がないと思われるファイルやファイル・タイプについて事前 入力されたリストが提供されます。 無視するファイルのリストは、インポート・ウィザードの手順5で表示されます。 表示されたリストには、フィルタを追加できます。 ただし、ここで追加したフィルタは、無視するファイルのリストに追加されることはなく、JDeveloperセッション間で引き継がれることもありませ ん。 所属する開発チームで使用しているフィルタに特定のパターンがあることに気づいた場合は、開発プロセスでそのパターンを文書化し、コードの初期インポート をおこなうチーム・メンバーに確実に知らせる必要があります。 次のようなシナリオについて考えてみましょう。 いくつかのコンパイル済みJavaクラスが含まれた新しいアプリケーションを作成します。 無視するファイルのリストは、表示されたアイテムを制限するためにアプリケーション・ナビゲータでも使用されています。 したがって、コンパイルされているクラスはアプリケーション・ナビゲータでは表示されませんが、当然、ファイル・システムには存在します。 ここで、SVNにアプリケーションをインポートし、同じフィルタをアプリケーションに適用します。 この場合、インポート・ウィザードの一部として、インポートしたアプリケーションのチェックアウトを選択します。 これにより、デフォルトで、ファイル・システムにおけるアプリケーションの元の位置にチェックアウト済みアプリケーションが含まれます。つまり、除外した ファイルはなくなります。 実際には、オリジナルのファイルがJDeveloperでバックアップされているため、ファイルを元に戻すこともできます。 しかし、この時点から先は、必要なコードすべての管理をリポジトリを使用しておこなうべきでしょう。 新規ファイルの除外ア プリケーション開発時には、特定のファイル・タイプや個別のファイルを作業用コピーでそのまま使用しながら、リポジトリからは削除する必要が生じることが あります。 このような状況に対応するにはsvn:ignoreプロパティを使用します。 このプロパティは、以下のようにさまざまな場所から使用できます。
コード競合の解消あ らゆる開発プロジェクトの場合と同様に、開発者間のコード競合を解消するには、複数の方法があります。 どんなツールでも、競合が絶対に発生しないことはありません。 競合が発生する要因の大半は、チームの開発プロセスや開発手法、そして常に問題として取り上げられる開発者同士のコミュニケーション不足にあります。 開発チームによっては、主要コードに'ロック'を設定している開発者が'ロック'のステータスを示すことで、そのコードの更新は本人以外できないことをほ かのチーム・メンバーに示しているところもあります(この方法は、チームが分散している場合、あまり有効に機能しません)。 JDeveloperの開発プロセスと開発手法を取り入れることで競合は最小限になりますが、何よりも開発者同士で日常的にコミュニケーションを図り、新 機能の開発やリファクタリングにおいて生じる可能性のある競合、そのほか数多くの競合発生要因について積極的に連絡しあい、調整をおこなっていく必要があ ります。 とはいえ、SVNとJDeveloperを使用することで、こうした競合を最小限に抑えると同時に、発生してしまった競合を解消するための戦略や回答を手 に入れられることは間違いありません。 バージョンの比較チーム環境では、ほかの開発者 によるコードの変更を避けることはできません。 ただし、その変更によって自分が変更しているコードとの競合が発生する場合もあれば、発生しない場合もあります。 Pending Changes Incomingタブを使用すると、ほかの開発者が変更したファイルを確認できます。 図5は、別のチーム・メンバーがhome.jspx.の新しいバージョンをチェックインしたことを示しています。この段階では、そのメンバーがおこなった 変更が自分の作業用コピーの変更と競合する可能性があるかどうかはわかりません。 この例を使用して、Incoming changesで使用できるさまざまなオプションについて、以下に例を挙げます。
図6. ファイルのHistoryタブ Update コマンドを使用するか、手動で変更の参照と追加をおこなうかは、対象となる変更の数と複雑さ、そしてソースの読みやすさによって異なる可能性があります。 もう1つの重要な考慮事項は変更自体の性質です。 多くの場合、とくにOracle Application Development Frameworkなどのフレームワークを使用した作業環境においては、Javaファイルとそれに対応するXMLメタデータ・ファイルとの間に依存関係が あるケースで変更を手動でおこなうとエラーが発生しやすくなります。 このため、Historyタブを使用して変更を事前に手動で参照したかどうかにかかわらず、Update Working Copyメカニズムを使用してリポジトリからコードを更新することをお勧めします。 場合によっては、Historyタブを使用すると、変更と変更者を特定できます(図6を参照)。変更者を特定できれば、その変更によるコードへの影響につ いて不明な点がある場合に連絡を取ることも可能となります。 別のアプローチ上記 に代わる方法として、ロック・修正・ロック解除モデルがあります。これは、ファイルをロックして、それを修正してからリポジトリに再度追加し、そのあと ロックを解除する方法です。 ファイルをロックしても、そのファイルのコピーで別の開発者が作業できなくなるわけではありません。これは、ロックが解除されるまで、別の開発者がそのコ ピーの内容をリポジトリに戻すことができないようにするものです。 このため、このモデルを使用しても作業が無駄となる可能性は残っています。 ロック・修正・ロック解除モデルは、競合する変更をマージできないバイナリ形式のファイルで作業をおこなう場合に適しています。 開発者がファイルへの変更の送信を厳密な順序に従って実行するためです。 JDeveloperでは、ファイルにおけるSubversionプロパティ svn:needs-lockのサポートと、コミットしようとしているファイルのロックを維持する機能が提供されています。 競合の解消競 合は、2つのファイルに異なる内容が含まれた同一のエントリがある場合に発生します。 JDeveloperの比較ツールとマージ・ツールは、XMLを認識します。 つまり、競合を回避するための処理では、XML要素、プロパティ、および空白の読取りと分析がおこなわれます。 ファイルがXMLではない場合、2つのファイルに異なる内容が含まれた同一の行があると競合が発生します。 JDeveloperでは、固有のマージ・アルゴリズムにより非常に多くの潜在的な競合を解消できますが、解消できない競合についての最終的な判断を下す のはユーザー自身です。 作業用コピーのリポジトリへのコミットを実行する前に比較ツールを使用しない場合には、コミッ ト時に1つ以上のファイルで競合が発生する事態に陥る可能性があります。 この場合、コミットが禁止され、リポジトリから作業用コピーまたは特定のファイルを更新したあとに、競合しているファイルの重複コピー(競合しているファ イルの異なるバージョンを示すファイル)がアプリケーション・ナビゲータに作成されます。 これに対応するには、横に感嘆符(!)アイコンが表示されているファイル・バージョンから「 Versioning」->「 Resolve Conflicts」 メニューを選択すると、Resolve Conflictsウィンドウが開きます。 図7は、このウィンドウの例です。 ここには、3つのペインがあります。左側のペインには対象ファイルの現在使用しているバージョン、右側のペインにはリポジトリのバージョン、そして中央の ペインには競合解消後の結果ファイルが表示されます。 この例では、右側と左側のペインは、内容を表示するために拡張されています。 この図からわかるとおり、ファイルはXMLファイルであり、ファイルの両方のバージョンで使用可能な同一要素に差異が含まれていることが JDeveloperによって認識されています。 この例では、ラベルのプロパティが異なっています。 ここで表示されているファイル内の競合すべてを解消すると、ウィンドウ上部のSaveおよびMergeボタンを使用して、結果ファイルの保存とマージが可能となります。 これで、更新されて競合がなくなったファイルをリポジトリにコミットする準備が整ったことになります。 ブランチングブ ランチングは、一般的に考えられているとおり、実際に幅広く使用される可能性はありませんが、ソース管理システム要件の1つとみなされています。 ブランチングの仕組みは'単純'ですが、その機能がどれだけ使えるものとなるかは、開発チームが使用するプロセスによって決まります。 ブランチングをおこなう場合、開発者は、チェックアウト、更新、およびマージの対象となるコードとその実行先を常に監視下に置いておく必要があります。 Subversionでは、ブランチとはコードのコピーを指します。ブランチの管理およびバージョニングは個別におこなわれますが、各ブランチには常にそ の祖先に関する情報が含まれています。 開発プロセスでは、ブランチを使用する正確な時期と方法を文書化する必要があります。 たとえば、チームに対し、メインの開発に加えたくないプロトタイプでの作業が求められるケースも考えられます。 このような場合、ブランチングをおこなうことで、この開発を個別に管理しながら必要に応じてメインの開発からコードを更新できるようにしたり、プロトタイ プの最後にコードの破棄またはメインのコード・ラインへのマージのいずれかを実行できるようにしたりすることが可能となります。 ブランチ・コードには、短期的なプロジェクトと長期的なプロジェクトがあります。 どちらの場合も、ある段階でブランチがメインのコード・ラインにマージされる場合、メインの開発ラインからの更新を頻繁におこなうことをお勧めします。 ブランチに関する設定と処理の手順は単純ですが、プロセスの各段階で何が起こるかをよく理解しておく必要があります。 JDeveloperでは、Subversionのブランチング・ソリューションに関する仕組みについての支援策として、以下のような機能が提供されてい ます。
ブランチの作成Subversionでは、ブランチと はコード・リビジョンのコピーか、ある時点での作業用コピーのことを指します。 図8は、Branch/Tagダイアログを示しています。 このダイアログで、作業用コピーまたはリポジトリの任意のリビジョンからブランチを作成できます。 この例では、リポジトリのHEAD Revisionがブランチとして使用されます。 作業用コピーは、ToフィールドのURLで指定されたリポジトリ・ロケーションにコピーされます。 Fromで指定されたリポジトリ内のロケーションに保存されている作業用コピーの履歴は、すべて新規ブランチとそのまま関連づけられます。 Subversion には、ブランチの機能に加え、タグ・オプションも用意されています。 この2つのオプションは非常によく似ていますが、一般的に、タグ・オプションは特定の時点におけるコードのスナップショットを取得するために使用され、ブ ランチ・オプションは独自の開発をおこなう場合に使用されます。 Subversionリポジトリの管理者は、タグとブランチの2つのオプションの違いを維持するため、Tagディレクトリで使用できるアクセスと編集の機 能を大幅に制限する傾向があります。 ブランチの操作ブランチを作業用コピーと特定のリ ビジョンのどちらから作成した場合でも、作成後にブランチ・コードで処理をおこない、引き続きそのコードの変更とコミットを実行する必要が生じる可能性が あります。 作業用コピーがリポジトリ内の適切な場所にコミットされるようにするには、Switchコマンドを使用します。 図9は、作業用コピーからブランチを作成し、それを使用して処理をおこなう場合の手順を示しています。
図9. 一般的なブランチング・シナリオ まとめOracle JDeveloperとSubversionを使用することで、開発者は統合されたチーム開発環境を手にすることができます。 この文書では、JDeveloperでSubversionを使用する場合のクライアント・サイドの統合とベストプラクティスについて説明しました。 SVNリポジトリの管理や接続プロトコルの問題などについては、この文書の範囲外であるため、ここでは取り上げていません。 |