javaがビルド言語として使用されないのはなぜですか?


24

Javaが汎用言語であり、プログラムの構築がJava言語を使用して記述できるものである場合、なぜこれがビルドファイルを記述する最良の方法ではないのか、代わりにAnt、Maven、Gradleなどのツールを使用しますか?それはもっと簡単なことではなく、また別のプログラミング言語を学ぶ必要性を排除しませんか?(ところで-この質問は、C#などの他の言語にも適用できます)


7
「ビルド言語に使用される汎用言語ではない理由」についてもう少し質問があるかもしれません。つまり、Cもビルド言語ではありません。また、私は周りの授賞式を見てお勧めしたいJavaで単一.javaファイルをコンパイル

8
これはおそらく「DSLに煩わされる理由」として一般化できます。
FrustratedWithFormsDesigner 14年

1
より良い質問があります。なぜIDE /コンパイラ/ツールがあまりにも悪いので、そもそもビルドツールが必要なのか。
ブレンダン14年

6
@Brendanは、ビルドツールとIDEの目的が異なるため、疑問ではありません。
14年

1
明確に定義された単純なドメイン固有の言語の代わりに、「汎用」言語を使用しないでください。また、「まだ別のプログラミング言語」を学ぶ必要がある場合は、実際にプログラミングを行うべきではなく、他の取引を試してください。
SKロジック14年

回答:


21

特定の目的のための特定のツール

  • 冗長性

    汎用言語は冗長すぎることがよくあります。Javaでビルドを管理しなければならなかった場合、獣の大きさによって非常に早く落ち込んでしまいます。ただし、Javaで記述されたDSLを使用して簡単に管理できます。そしてある程度、Gradle(Groovy)とBuildr(Ruby)を見ることができます。

  • 困難

    汎用言語は難しいです。プログラミングは難しいとは思いませんし、だれも手に入れることはできませんが、ポイントは、ビルドエンジニアは必ずしもプログラマーではないということです!

  • 目的

    それは多かれ少なかれ難易度冗長性の交差点にあります。言語は目的のために設計されており、ここでは非常に具体的なものについて話しています。なぜあなたは必要とするか、または使用したい一般的な目的の言語を?ビルドには、次のものが必要です。

    • 個別の構成、環境などを処理するためのブランチと条件付き...
    • 環境からデータを抽出するための一連の指示、
    • 成果物を作成するための一連の指示。

    あなたは本当に多くを必要としません。

ビルドシステムが、ある特定のユースケースに十分な柔軟性を持たないように思えるのは面倒ですが、ほとんどの人にとってはおそらく他のシステムよりもはるかに優れています。

それがおそらく、ほとんどのプログラム可能なプログラムよりも宣言型ビルドシステムを好む人々の間で極性がある理由です。開発者は、箱から抜け出す方法を探す自然な傾向があると思います。

待って、本当にツールが必要ですか?

もう1つの関連する質問は、「ビルドツールが本当に必要なのか」ということです。それらがすべての言語に存在するという事実は、そもそもそこにあるべきではないギャップを埋める兆候ではありませんか?

一部の言語では、ビルドツールは必ずしも必要ありません。たとえば、ほとんどのスクリプト言語は1つを必要とせず、ロード時に解決します。または、Goのコンパイラーがすべてを処理してくれるので、これは良い対抗策です。gccのようなコンパイラーが突然すべてのフラグ、リンカー、メイクファイルを必要としなかった場合はどうでしょうか。または、javacがbuild.xmlまたはpom.xmlを必要とせずに、何をすべきかを彼に指示した場合はどうなりますか?依存関係は最終的なプログラムの一部であるため、依存関係の管理を直接言語のツールの一部にすべきではありませんか?

確かに、ユーザー(ビルダー)にとってはるかに単純なアプローチのようです。彼らは内部でやっていることを主張し、そのビルドプロセスに影響を与えるあなたの選択と機会を奪いますが、そのようなツールがコンパイラの拡張などを許可することを望みます。さらに、ツールと言語を2つの別個の要素として見ていました。そのため、突然それらを密接に結び付けるのは不純に思えるかもしれません。

プログラムのビルドに使用する言語が問題ではないと思います。重要なのは、プログラミングに使用する言語とそのコアプラットフォームおよびツールであり、それについてはまだ前進しています。


個人的には、make / gmake / autotools / pmkを使用してCに満足しており、Javaを使い始めてからmakeを実行し、その後antを実行するようになりました。私はgradle、builder、その他に価値を見ることができますが、私はこれまでのところ、より重要な変化が起こるまで、mavenの流行が好きです。プラス私のようなそれは剛性のだが、それでも必要に応じて周りのこと、あなたに仕事する能力を残していること。簡単ではないというのは良いことです。

これはビルドツールです。それを受け入れることを学んで、それと戦ってはいけません。負けの戦いです。または、少なくとも非常に長いもの。


あなたのプラグマティズムが本当に好きです。私の質問は好奇心からです。私はmaven(過去にmakeとantを使用したことがあります)を使用しますが、「黒魔術」を行います。しかし、それはまだ魔法です。
ヴァイノロ14年

1
「または、javacが何をすべきかを伝えるためにbuild.xmlまたはpom.xmlを必要としなかった場合は?」-ほら。それはしませんでした。
user253751

@immibis:それは議論の余地があります。javacのみを使用してオフィスでプロジェクトを構築することはあまり好きではありません。または、すべてが1つのフォルダーにあり、すべてのリポジトリがレポにある巨大なプログラムです。本当に欲しいものではありません!:)しかし、それは別の議論であり、OPの質問とは無関係です。
ヘイレム

ビルドシステムと言語の統合は、多言語プロジェクトでも問題があります。言語Aと言語Bの両方を使用し、それらに単一のビルドプロセスを使用したい場合、どの言語のビルドシステムを使用しますか?
セバスチャンレッド

@SebastianRedlそれでは、第三言語を導入することで問題はどのように簡単になりますか?最適な言語を選択してください。(そしてもちろん、第三言語が必要な場合は、Javaでも可能です。)
ヴィルオイカリネン

21

Javaされる不可欠、言語AntMavenなどです宣言型言語:

次のように違いを定義できます。

  • 命令型プログラミング:「マシン」に何かをする方法を伝えると、結果として、あなたが何をしたいのかが起こります。
  • 宣言型プログラミング:「マシン」にをしたいのを伝え、コンピューターにその方法を理解させます。1

ビルド言語は、ビルダーに何を行うべきどこから取るべきかなどを指示します。ビルドを実行するエンジン(@ElliottFrischのような命令型言語で記述されています)がこれらの指示を読み取り、それらを実行します。

宣言タスクはビルドシナリオでより適切に見えるかもしれません。ビルドタスクは全体的に同じであり、本格的なコード形式よりもその形式の方が保守性と可読性が高いと考えられるためです。


3
ただし、命令型言語を使用するビルドシステムが少なくとも1つあります。SconsはPythonを使用します。
user16764 14年

ただし、依存関係のリストを含むことができるクラスと、それらの依存関係を解決するメソッドを記述するよりも、それを必須にすることは難しくありません。おそらくJVMの起動時間など、別の理由があると思います。

2
@Lee:ほとんどすべてのJavaの世界で使用されるビルドツール(Antの、Mavenの、Gradleでは、SBT、...)は、一般的に(熊手、Buildrまたはsconsのの例外、とJVM上で実行するのができますが、していない持っていますする JVM上で実行します)。
ヨルグWミットタグ14年

6
@vainolo「ほとんどの人は本当にAnt / Maven / Makeが好きではありません」?それは大胆な声明です!
ベンサリー14年

1
@BenThurley私が作るのが好きだったのに、なぜアリが作られたのですか そして、もしアリが好きだったら、なぜメイヴンだったのですか?そして今、なぜ人々はGradleを使用していますか?しかし、私はこれが大胆な声明であり、数十人のJava開発者の「逸話的」証拠によってのみ裏付けられていることに同意します
vainolo 14年

4

典型的なビルドシステムの機能を見ると、次のことがわかります。

  1. 多くのデータ:名前、スイッチ、設定、構成アイテム、文字列など
  2. 環境との多くの相互作用:コマンド、環境変数
  3. 依存関係、スレッド、ロギングなどを処理する比較的単純な「ビルドエンジン」

いくつかの言語(Java / C#/ Python /など)を使用して一連のビルドファイルを作成する場合は、3番目または4番目の反復までに(a)ほとんどのデータと外部コマンドを何かのデータとして保持します。 XML(b)のように、お気に入りの言語で「ビルドエンジン」を記述します。

また、ビルドエンジンのさまざまな機能をトリガーするために、XMLのデータの一部をインタープリター言語として扱うと便利です。データの一部のマクロを解釈したり、文字列の置換を実行することもできます。

言い換えると、Make、Ant、Rake、またはMsBuildで終わることになります。それが上手くいくための命令型言語と、やりたいことを記述するデータ構造。通常はXMLで。


2

これらの場合、Java / C ++ / C#の使用には多くの要因が考慮されます。

まず、ビルドスクリプトを実行してアプリをビルドする前に、ビルドスクリプトをコンパイルする必要があります。ビルドスクリプトのビルドに必要なパッケージ、フラグ、コンパイラバージョン、ツールパスをどのように指定しますか?確かに、あなたはそれを回避する方法を思いつくことができますが、そのビルドステップを必要としない言語(例えばpython)を持っているか、ビルドツールがネイティブに理解する言語を持っている方がはるかに簡単です。

第二に、ビルドファイルはデータ量が多いのに対し、Java / C ++ / C#はコードやアルゴリズムの作成により適しています。Javaや友人は、保存したいすべてのデータを非常に簡潔に表現しているわけではありません。

第三に、Javaと友人は有効であるために多くの定型文を必要とします。ビルドファイルは、すべてのインポートを含むクラス内のメソッド内になければなりません。スクリプト言語またはカスタム言語を使用する場合、その定型文をすべて回避し、ビルドの詳細のみを保持できます。


0

確かに!人々がしばしば(当初)考えているよりも複雑な問題に、強力表現力豊かな言語を使用してみませんか?特に問題に直面している人々がすでにそのような言語に精通している場合。(構築はプログラマー自身の問題であり、プログラマーによって最もよく解決されます。)

私もこの質問を数年前に自問し、Javaはビルド、特にJavaプロジェクトの定義に適した言語であると判断しました。そして、結果として、私はそれについて何かを始めました。

免責事項:この回答では、開発中のビルドシステムであるiwantを推進しています。しかし、これはとにかく意見を述べる議論なので、大丈夫だと確信しています。

Javaの利点(パワーと表現力)や具体的な欠点については詳しく説明しません。興味がある場合は、iwantページで詳細を読むことができます

代わりに、Java(および他のGPL)がビルドに適さないとしてすぐに却下される理由を検討します。ここでの多くの回答とコメントは、そのような考え方の良い例です。典型的な議論のいくつかを考えてみましょう:

「Javaは必須ですが、ビルドは宣言的な方法で定義するのが最適です」と彼らは言うかもしれません。

本当です。しかし、内部DSLのメタ言語として言語を使用する場合、本当に重要なのはその構文です。Javaのような命令型言語でさえ、だまされて宣言型になることがあります。宣言的に見えると感じる場合、それは(実際的な目的のために)宣言的です。例えば:

JacocoTargetsOfJavaModules.with()
    .jacocoWithDeps(jacoco(), modules.asmAll.mainArtifact())
    .antJars(TestedIwantDependencies.antJar(),
            TestedIwantDependencies.antLauncherJar())
    .modules(interestingModules).end().jacocoReport(name)

これは、iwantのデモプロジェクトの実際の例です

実際、これを「テスト」や「コンパイル」などの命令型の動詞にユーザーをさらす宣言型ビルドシステムと比較してください。上記の宣言には名詞のみが含まれ、動詞は含まれません。コンパイルとテストは、ユーザーに必要な名詞を付与するために、iwantによって暗黙的に処理されるタスクです。それは言語ではありません。それがあなたの使い方です。

「Javaは冗長です」

はい、多くのJavaコードは冗長です。しかし、繰り返しになりますが、それは言語ではなく、使用方法です。実装が冗長な場合は、素敵な抽象化の背後にカプセル化します。多くのGPLは、このための適切なメカニズムを提供します。

上記のJavaスニペットがXMLで記述されていることを想像してください。括弧を山括弧で置き換え、それらを移動します。そして、すべてのキーワードを終了タグとして複製します構文としてのJava 冗長ではありません

(XMLと比較することは、赤ちゃんからキャンディーを奪うようなものですが、非常に多くのビルドがたまたまXMLで定義されています。)

「ビルドスクリプトをコンパイルする必要があります」

これは有効なポイントです。それにもかかわらず、それは解決すべき小さな技術的問題にすぎません。beanshellまたは他のインタープリターを使用して解決できました。代わりに、単に別のビルドの問題として扱い、単純なJavaブートストラップをコンパイルして実行する単純なシェルまたはantスクリプトでブートストラップを行うことで解決しました。

「Javaには定型文があります」

本当です。クラスをインポートする必要があり、「public」、「class」などに言及する必要があります。そして、ここでは単純な外部DSLが最初の簡単な勝利を記録します。

そして、プロジェクトが非常に些細なもので、この定型句が重要な場合、おめでとうございます。あなたの問題は難しいものではなく、あなたがそれをどう解決するかは本当に問題ではありません。

しかし、多くのプロジェクトでは、コンパイル、カバレッジレポート、パッケージング以上のものが必要です。Javaのボイラープレートが顧客の問題に受け入れられる場合、問題を作成してみませんか?なぜ他人の子供専用の靴を作るのですか?


0

私が他の答えに取り組んでいないと思うことの一つは、これらのビルド言語の制限と透明性が、それらを有用にするものの大きな部分であるということです。たとえば、Mavenを見てみましょう。はい、ビルドを実行しますが、依存関係も定義します。これにより、Mavenビルドでこれらの依存関係を取得し、依存関係などを確認できます。

これがJavaで直接行われたかどうかを検討してください。ビルドツールは、依存関係があることを確認します。次に、他のJavaアプリケーションをプルダウンして実行し、依存関係を判断する必要があります。しかし、Mavenの場合は、依存関係の宣言のみを参照します。Mavenビルドファイルは透過的です。チューリング完全言語は本質的に非透過的であるため、このような一部の目的では劣っています。


Gradleはこれにどのように適合しますか?汎用言語(Groovy)を使用して、宣言型の依存関係を定義します。Groovy、JavaScript、またはLispベースのツールでは、宣言を解析するために言語のコンパイラまたはインタープリターを使用するのが自然です。読みたいだけなのか、それを「実行」する(関数を適用する)かは関係ありません。コードとデータの二重性は、一般的に受け入れられているJavaイディオムの一部ではありませんが、不可能ではありません。チューリングの完全性は、適切なデータ表現を妨げません。それは、あなたのデータがあなたが期待していないことをする可能性を開きます。
-joshp

@joshp私はGradleに慣れていません。DSLとして記述されており、物事はかなり宣言的に見えます。Groovyをベースにしているからといって、Groovyのパワーが同等であるとは限りません。Gradleが実際にチューリング完全言語であるかどうかを言うには、おそらくより良い立場にいるでしょう。私が見た依存関係の例は、かなり単純に見えます。依存関係宣言などで任意のGroovy式を使用できますか?
ジミージェームズ

個人的には、推移的な依存関係も好きではありません。多くの場合、クラスパス(ライブラリの複数の互換性のないバージョン)で驚きを引き起こします。そのため、mavenにはexcludeエレメントがありますが、面倒なだけの価値はありません。明示的な依存関係により、作業が簡単になります。それでも、推移的な依存関係 Javaで実装できます。他のプロジェクトのビルド定義を再利用することで、iwantでそのようなことをしました。
ヴィルオイカリネン

@VilleOikarinen私はたぶんあなたに同意します。また、依存関係を使用しなくても、依存関係を引き込むためのコストが知覚されないため、それは膨大な量になると思います。ただし、この回答の文脈では、その機能の価値や知恵についてではなく、DSLの使用がそれを達成するのにどのように役立つかについてコメントしています。
ジミージェームズ

1
@VilleOikarinen私たちはこれで終わりに近づいたと思いますが、pom / mavenについて話していないことを明確にしたいだけです。これはビルドDSLの例ですが、あまり考えていません。しぶしぶ使用しますが、不格好だと思います。しかし、pomが支配的なのは、依存関係の宣言です。私はしばらくの間Buildrを使用し、依存関係のpomを読み取りますが、ビルド仕様にはそれらを使用しません。このpomを理解するJavaベースではないツールがいくつかありますが、彼らが気にするのは依存関係だけです。
ジミージェームズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.