paint-brush
Gradle は本当に Maven よりも優れているのでしょうか? - 私の最終判断by@nfrankel
5,465
5,465

Gradle は本当に Maven よりも優れているのでしょうか? - 私の最終判断

Nicolas Fränkel8m2023/08/09
Read on Terminal Reader

この投稿では、同じ「推論」の誤りを繰り返し暴くのではなく、人々を Gradle に誘導できるように、Gradle について少し説明したいと思います。
featured image - Gradle は本当に Maven よりも優れているのでしょうか? - 私の最終判断
Nicolas Fränkel HackerNoon profile picture
0-item

私は興味深いと思う技術的な内容をツイートしますが、面白いツイートが最もエンゲージメントを集めます。私は 3 月に JavaLand カンファレンスに参加し、偶然 Gradle ブースに行き、次のような逸品を見つけました。

https://twitter.com/nicolas_frankel/status/1638549568957861889


もちろん、ある時点で、ファンボーイがスレッドを乗っ取り、いわゆる Gradle の優位性を主張しました。この投稿では、同じ「推論」を何度も暴くのではなく、人々をそのスタンスに誘導できるように、私のスタンスを少し明らかにしたいと思います。


これに対処するには、時間を戻す必要があります。ソフトウェア開発は急速に変化する分野であり、私たちの理解の多くは個人的な経験に基づいています。それで、これが私のものです。

私の最初のビルドツール: Ant


私は 2002 年にJava で開発を始めました。当時はビルド ツールがありませんでした。IDE を通じてコンパイルとビルドを行いました。記録のために言っておきますが、私は最初に Visual Age for Java を使用しました。その後、Borland JBuilder に移行しました。


IDE を使用したビルドには大きな問題があります。各開発者には専用の設定があるため、アーティファクトの生成は開発者とマシンの組み合わせに依存します。


再現不可能なビルドは長年の問題です。私が反復可能なビルドを初めて体験したのは Apache Ant です。


Apache Ant は、Java ライブラリおよびコマンドライン ツールであり、その使命は、相互に依存するターゲットおよび拡張ポイントとしてビルド ファイルに記述されたプロセスを駆動することです。 Ant の主な既知の用途は、Java アプリケーションのビルドです。 Ant は、Java アプリケーションをコンパイル、アセンブル、テスト、実行できるようにする多数の組み込みタスクを提供します。 Ant は、C アプリケーションや C++ アプリケーションなど、Java 以外のアプリケーションを構築するために効果的に使用することもできます。より一般的には、Ant を使用して、ターゲットとタスクの観点から説明できるあらゆるタイプのプロセスを試行できます。


-- https://ant.apache.org/


Ant は、次の 3 つの主要な抽象化に基づいています。


  • タスクは、Java ファイルをコンパイルするjavac 、Web アーカイブを組み立てるwarなど、原子的な作業単位です。Antはすぐに使用できるタスクを多数提供しますが、カスタム タスクを追加することもできます。
  • ターゲットはタスクのリストです。
  • タスク間の依存関係を定義できます (パッケージ依存する場合)。この点で、Ant はワークフロー実行エンジンとして見ることができます。


私はすぐに Ant を「流暢」に使えるようになりました。私はコンサルタントとして、会社から会社へ、プロジェクトからプロジェクトへと渡り歩きました。最初は主に Ant をセットアップしていましたが、時間が経つにつれて Ant がより普及し、既存の Ant セットアップに出会いました。私のプロジェクトには一貫性がありましたが、他のプロジェクトはそれぞれ大きく異なっていました。


新しいプロジェクトに到達するたびに、カスタム ビルドを理解するために Ant のセットアップを注意深く読む必要がありました。また、それぞれのプロジェクトの構造も異なっていました。ソースをsrcに配置するもの、 sourcesに配置するもの、入れ子構造に配置するものなどがあります。


かつて、組織のプロジェクトのニーズ全体に対応しようとした汎用ビルド ファイルを覚えています。 2,000 行を超える XML で 80 を超えるターゲットを定義しました。ヘルプを使用して使い方を理解するまでにかなりの時間がかかり、プロジェクトを中断することなく調整できるようになるまでにはさらに時間がかかりました。

私の 2 番目のビルド ツール: Maven

上記のプロジェクトは私に多くのことを考えさせました。メンテナーがすでに Ant の限界を超えていたため、状況を改善したいと考えていました。当時、私は友人のフレディ・マレット(ソナーで有名)と一緒に仕事をしていました。私たちが話したところ、彼は私をメイビンに教えてくれました。私はかつてMaven を使用してプロジェクトを構築したことがありましたが、それ以外の経験はありませんでした。私はドキュメントを何時間も研究し、Freddy の指導の下で試行錯誤を繰り返し、Ant ビルド ファイル全体を単純な親 POM に移行しました。


Ant では、各プロジェクトですべてを定義する必要があります。たとえば、Ant では、コンパイル用に Java ファイルの場所を構成する必要があります。 Maven は、それらがsrc/main/javaの下にあると想定しますが、これをオーバーライドすることは可能です。 Maven は、構成よりも規約のアプローチによって Java ビルド分野に革命をもたらしました。現在、多くのソフトウェアがデフォルトで賢明な構成を提供しています。


私がそうであったように、プロジェクトからプロジェクトへと渡り歩く開発者にとって、それは新しいプロジェクトに参加するときの認知的負荷がはるかに少ないことを意味します。 Java ソースはsrc/main/javaの下にあると思います。 Maven の規約は、プロジェクトの構造を超えて継続されます。また、コンパイルから単体テストと統合テストを介したリモート レジストリへのアーティファクトのアップロードまで、プロジェクトのライフサイクルも定義します。


最後に、若手開発者はそれに気づかない傾向がありますが、Maven は依存関係管理という用語を定義しました。これは、不変の依存関係をダウンロードしたり、アーティファクトをプッシュしたりできるアーティファクト レジストリのアイデアを導入しました。それまでは、各プロジェクトは依存関係を専用のリポジトリに保存する必要がありました。


記録のために言っておきますが、上記のプロジェクトにはいくつかの依存関係が保存されていました。 Ant から Maven に移行したとき、正確な依存関係のバージョンを見つける必要がありました。ほとんどの場合、それはファイル名または JAR マニフェストにあるため、簡単でした。ただし、1 つは追加のクラスで更新されていました。


不変性についてはこれくらいです。


Maven は、その後のすべてのビルド ツールに大きな影響を与えました。それらは、Maven を参照して自らを定義しました。

私のビルドツールはありません: Gradle


Gradle の主な主張は、Maven の欠点、または少なくとも Maven が認識している欠点を修正することでした。 Maven も非難を免れないわけではありませんが、Gradle は最も重大な問題は柔軟性の欠如であると考えました。それはまさに Maven が Ant よりも改良した点だったため、これは驚くべき仮定です。 Maven プロジェクトは同様の構造を持ち、同じライフサイクルを使用します。これは事実上、最小の驚きの原則です。逆に、Gradle では、ライフサイクルを含むビルドのほぼすべての側面をカスタマイズできます。


柔軟性の議論に取り組む前に、Maven がその後実装した 2 つの優れたオリジナルの Gradle 機能、つまり Gradle デーモンと Gradle ラッパーを認めておきます。


Maven と Gradle はどちらも JVM 上で実行される Java アプリケーションです。 JVM の起動には、時間とリソースの点でコストがかかります。利点は、長時間実行される JVM が JIT 化されたコードを時間の経過とともに最適化することです。短期的なタスクの場合、JVM の起動時間を考慮するとメリットはゼロどころか、有害ですらあります。 Gradle は Gradle デーモンを思いつきました。 Gradle を実行すると、実行中のデーモンが検索されます。そうでない場合は、新しいものが開始されます。コマンドライン アプリはすべてをデーモンに委任します。名前が示すとおり、デーモンはコマンド ラインが終了しても停止しません。デーモンは JVM の利点を活用します。


おそらく、あなたのアプリケーションは現在のビルドツールよりも長持ちするでしょう。今から 5 年後にバグを修正する必要があるときに、プロジェクトのビルド ツールがオンラインで利用できないことに気づいた場合はどうなるでしょうか? Gradle のラッパーの背後にある考え方は、正確な Gradle バージョンをプロジェクトとともに保持し、インターネット経由でフル バージョンをダウンロードするのに十分なコードを保持することです。副作用として、開発者は Gradle をローカルにインストールする必要がありません。すべて同じバージョンを使用し、不一致を回避します。

Gradle の柔軟性を暴く

Gradle は、Maven に統合された上記 2 つの優れた機能をもたらし、競争が良好であることを証明しました。それにもかかわらず、私はまだ Gradle のメリットを感じていません。


感情的な面を押しのけようとします。当初、Gradle マーケティングはあらゆる機会に Maven を貶めようとし、クレイジーな比較表を公開し、一般的にコミュニケーションにおいて非常に攻撃的でした。この段階が、市場での地位を確立しようとしている若い企業にとって許容できるよりもはるかに長く続いたとしましょう。 Gradle は、Maven の「父親」を殺そうとするというアプローチにおいて、非常にエディピアン的だったと言えるでしょう。長い年月を経て、ようやく賢くなったようで、今では「Maven を愛している」ようです。


Maven が引き継ぐ前は、Ant プロジェクトはすべてその場限りのものであったことを思い出してください。メイブンはそれに終止符を打った。これにより、西部開拓時代にカスタム プロジェクトの法がもたらされました。法律に反対することもできますが、いずれにしても法律ですので、誰もが法律を守る必要があります。 Maven 標準は非常に定着しているため、ソースの場所などの一部のパラメーターをオーバーライドすることは可能ですが、誰もそれを行いません。


私は、Gradle の柔軟性に関する 2 つの症状を経験しました。もっとたくさん存在するのではないかと思います。

カスタムライフサイクルフェーズ

Maven は、統合テストを 4 つのフェーズで管理し、次の順序で実行します。


  1. pre-integration-test : テストに必要なものをすべて設定します
  2. integration-test : テストを実行します
  3. post-integration-test : リソースがあればクリーンアップします。
  4. verify : テストの結果に基づいて行動する


各テストには専用のセットアップとティアダウンのロジックがあったため、前フェーズと後フェーズは使用しませんでした。


一方、 Gradle には統合テストの概念がまったくありません。それでも、Gradle ファンは、必要なフェーズを追加できると喜んで説明します。実際、Gradle ではライフサイクルの「カスタマイズ」が可能です。通常のライフサイクルに必要なだけ追加のフェーズを追加できます。


これは面倒です。プロジェクトごとに、必要なフェーズの数とその名前の両方を考え出す必要があります。integration integration-testintegration-testsintegration-testingit (怠け者向け) などです。オプションは無限です。

スノーフレーク症候群

Maven は、すべてのプロジェクトを通常の標準プロジェクトとして扱います。特定のニーズがある場合は、そのためのプラグインを作成することが可能です。 Maven プラグインの作成は決して楽しいものではありません。したがって、法律が自分に適用されないと判断したからという理由だけでなく、必要な場合にのみ文書を作成する必要があります。


Gradle は、柔軟性の欠如が問題だと主張しています。したがって、それを修正したいと考えています。私はその逆の立場をとっています。つまり、ビルド ツールの柔軟性の欠如は機能であって、バグではありません。 Gradle を使用すると、ビルドを簡単にハッキングできます。したがって、自分のプロジェクトが特別なスノーフレークであり、カスタマイズする価値があると考える人は、喜んでそうするでしょう。現実の確認: そのようなことはめったにありません。その場合、それはフレームワーク用であり、通常のプロジェクト用ではありません。 Gradle の支持者らは、簡単な構成を可能にしながら標準を提供していると述べています。問題の核心は、誰かの気まぐれで変更できるものは標準ではないということです。


Gradle は、 Android プロジェクト事実上のビルド ツールです。私が働いていた会社の 1 つでは、誰かが Sonar を実行して内部 Sonar インスタンスにメトリクスを送信するためのカスタム Groovy コードを Gradle ビルドに記述していました。当時はすぐに使える Sonar プラグインがなかったか、それが役に立たなかったのだと思います。ここまでは順調ですね。


別のチームが会社の 2 番目の Android プロジェクトを作成したとき、最初のプロジェクトの構造とビルド ファイルをコピーして貼り付けました。現時点で賢明なのは、Sonar 固有のコードから内部 Gradle プラグインを作成することでした。しかし、Gradle によってビルドのハッキングが非常に簡単になったため、彼らはそれをしませんでした。そして、Gradle 嫌いの私は、自らプラグインを作成することにしました。控えめに言っても、開発者エクスペリエンスはさらに向上したはずです。質の高いドキュメントが不足しており、型なし言語 (Groovy) を使用しているため、コンソールを使用してオブジェクトの構造を出力して作業を進めました。

結論

競争は良好で、Gradle は Maven とラッパーとデーモンを統合した新しいアイデアをもたらしました。ただし、Gradle は柔軟性が良いという前提に基づいて構築されていますが、私の経験ではその逆であることがわかりました。 Ant は非常に柔軟性があり、あるプロジェクトから次のプロジェクトに移る際の認知負荷は高かった。


私たち開発者は人間です。私たちは自分のプロジェクトが他のプロジェクトとは異なると考えたいと考えています。ほとんどの場合、そうではありません。カスタマイズは私たちのエゴを満たすための手段にすぎません。柔軟なビルド ツールを使用すると、保証の有無にかかわらず、このようなカスタマイズを実装できます。


無関係なカスタマイズは何の利益ももたらさず、開発は簡単ですが、維持費が高くつきます。ソフトウェア資産の管理が私の責任の一部である場合、私は常にビルド ツールの柔軟性よりも安定性を選択します。


初出は 2023 年 8 月 6 日にA Java Geekで公開されました