web-dev-qa-db-ja.com

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

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

25
vainolo

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

  • 詳細度

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

  • 難易度

    汎用言語は難しいです。まあ、プログラミングは難しいとは思わないし、だれもが手に入れることはできないと思いますが、要点は、ビルドエンジニアは必ずしもプログラマではないということです。

  • 目的

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

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

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

確かに、あなたのビルドシステムが、あなたが求めているその1つの特別なユースケースに対して十分に柔軟ではないように思える場合は迷惑ですが、ほとんどの人にとっては、代替システムよりもはるかに優れています。

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

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

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

一部の言語は、必ずしもビルドツールを必要としません。たとえば、ほとんどのスクリプト言語はそれを必要とせず、ロード時に解決します。または、コンパイラーがすべてを処理するGoを使用します。これは、Niceカウンターポイントです。gccのようなコンパイラーが突然すべてのフラグ、リンカー、およびメイクファイルを必要としなくなった場合はどうでしょうか。または、javacが何をすべきかを伝えるためにbuild.xmlまたはpom.xmlを必要としなかった場合は?依存関係は最終的なプログラムの一部であるため、依存関係の管理を言語独自のツールの一部にすべきではありませんか?

確かに、ユーザー(ビルダー)にとってははるかに単純なアプローチのようです。それらは内部で行われ、選択と機会を取り除いてビルドプロセスに影響を与えると主張することもできます(ただし、そのようなツールでコンパイラーの拡張機能などを使用できることを望みます)。さらに、私たちはツールと言語を2つの別個のものとして見ていました。そのため、彼は突然それらを緊密に結合させるのは不純に見えるかもしれません。

あなたがあなたのプログラムを構築するために使用する言語は問題ではないと私は思います。重要なのは、プログラミングに使用する言語とその中核となるプラットフォームとツールです。


個人的には、make/gmake/autotools/pmkを使用してCで満足しており、Javaから始めました。これらのすべての選択肢よりも一般的にMavenを優先します。gradleやbuildrなどで値を確認できますが、より大きな変化が生じるまで、これまでのところmavenの普及が好きです。プラスIlike厳格ですが、必要に応じて回避することができます。簡単ではないことは良いことです。

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

21
haylem

Java命令型言語、AntMavenなどは宣言型言語です。

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

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

ビルド言語はビルダーにwhatを行う必要があることを伝えますwhereを行う必要があるなど。runsビルドするエンジン(これは@ElliottFrischが指摘したように、命令型言語で)、これらの指示を読んで実行します。

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

21
Uri Agassi

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

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

いくつかの言語(Java/C#/ Python/etc)を使用して一連のビルドファイルを作成する場合、3回目または4回目の繰り返しで、(a)ほとんどのデータと外部コマンドを何かのデータとして保持することで解決します。 XMLのように(b)「ビルドエンジン」を好きな言語で書く。

また、XMLの一部のデータをインタプリタ言語として扱い、ビルドエンジンのさまざまな機能をトリガーすることも役立つでしょう。また、データ内で一部のマクロを解釈したり、文字列の置換を実行したりする場合もあります。

つまり、Make、Ant、Rake、またはMsBuildで仕上げることになります。正常に機能するための命令型言語、および実行したいことを説明するためのデータ構造。通常はXMLになっています。

4
david.pfx

これらのケースでは、Java/C++/C#の使用に対していくつかの要因が考慮されます。

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

第2に、Java/C++/C#はコードとアルゴリズムを作成することを目的としているのに対し、ビルドファイルはデータ量が多いです。 Javaと友人はあなたが保存したいすべてのデータの非常に簡潔な表現を持っていません。

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

2
Winston Ewert

確かに! 強力なおよび表現力豊かな言語を使用して、人々がしばしば(最初に)考えるよりも複雑ですか?特に問題に直面している人々がすでにそのような言語に堪能である場合。 (ビルドはプログラマー自身の問題であり、プログラマーが最もよく解決します。)

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

[〜#〜]免責事項[〜#〜]:この回答で私は宣伝しています iwant 、私はビルドシステムです現像。しかし、これはとにかく意見の議論なので、大丈夫だと確信しています。

Java(パワーと表現力))の利点や具体的には詳しく説明しません。興味がある場合は、 iwant page で詳細をご覧ください。

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

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

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

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

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

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

"Javaは冗長です"

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

上記のJavaスニペットを想像してみてください。括弧を山括弧で置き換えて移動します。次に、everyキーワードを終了タグとして複製します!Java assyntaxisnotverbose。

(私が知っているように、XMLと比較することは、赤ちゃんからお菓子を奪うようなものですが、非常に多くのビルドがたまたまXMLで定義されています。)

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

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

"Javaには定型があります"

そうだね。クラスをインポートする必要があり、「public」、「class」などについて言及する必要があります。そして、ここでは単純な外部DSLが最初の簡単な勝利をもたらします。

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

しかし、多くのプロジェクトでは、コンパイル、カバレッジレポート、パッケージ化以外にも多くのものが必要です。 Javaの定型文が顧客の問題に受け入れられるなら、なぜ問題を構築しないのですか?なぜ他の子供たちだけのために靴を作るのですか?

0
Ville Oikarinen

他の回答が対処していないと私が思うことの1つは、これらのビルド言語の制限と透過性が、それらを有用にするものの大部分であることです。 Mavenを例にとってみましょう。はい、ビルドを実行しますが、依存関係も定義します。これにより、Mavenビルドでこれらの依存関係をプルダウンし、それらの依存関係などを確認できます。

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

0
JimmyJames