Tại sao java không được sử dụng làm ngôn ngữ xây dựng?


24

Nếu Java là ngôn ngữ có mục đích chung và xây dựng chương trình là thứ có thể được mô tả bằng ngôn ngữ Java, tại sao đây không phải là cách tốt nhất để viết tệp xây dựng và thay vào đó chúng tôi sử dụng các công cụ như Ant, Maven và Gradle? Điều đó có đơn giản hơn không, và cũng loại bỏ nhu cầu học thêm một ngôn ngữ lập trình khác? (BTW - câu hỏi này cũng có thể được áp dụng cho các ngôn ngữ khác, như C #)


7
Bạn có thể có một câu hỏi thú vị hơn một chút về câu hỏi "tại sao ngôn ngữ mục đích chung không được sử dụng cho ngôn ngữ xây dựng" - ý tôi là, C cũng không phải là ngôn ngữ xây dựng. Tôi cũng đề nghị xem xét buổi lễ xung quanh việc biên dịch một tệp .java duy nhất trong Java

8
Điều này có lẽ có thể được khái quát là "Tại sao phải bận tâm với DSL?"
Thất

1
Một câu hỏi tốt hơn có thể là; tại sao các IDE / trình biên dịch / công cụ lại tệ đến mức các công cụ xây dựng là cần thiết ngay từ đầu.
Brendan

6
@Brendan đó không phải là câu hỏi vì các công cụ xây dựng và IDE phục vụ các mục đích khác nhau.
jwenting

1
Bởi vì các ngôn ngữ "mục đích chung" không bao giờ nên được sử dụng thay vì các ngôn ngữ đơn giản, cụ thể theo miền. Và, nếu nhu cầu học "ngôn ngữ lập trình khác" liên quan đến bạn, bạn không nên thực sự lập trình, hãy thử một số giao dịch khác.
SK-logic

Câu trả lời:


21

Công cụ cụ thể cho một mục đích cụ thể

  • Độ dài

    Ngôn ngữ mục đích chung thường quá dài dòng. Nếu tôi phải quản lý một bản dựng trong Java, tôi sẽ rất chán nản bởi kích thước của con thú. Tuy nhiên, nó có thể dễ dàng quản lý bằng cách sử dụng DSL được viết bằng Java. Và ở một mức độ nào đó, đó là cách bạn có thể thấy Gradle (cho Groovy) và Buildr (cho Ruby).

  • Khó khăn

    Ngôn ngữ mục đích chung là khó. Chà, tôi không nghĩ lập trình là khó và không ai có thể chọn, nhưng vấn đề là: kỹ sư xây dựng của bạn không nhất thiết phải là lập trình viên của bạn!

  • Mục đích

    Đó là ít nhiều ở giao điểm của khó khăndài dòng . Một ngôn ngữ được thiết kế cho một mục đích và ở đây chúng ta đang nói về một thứ rất cụ thể. Vậy tại sao bạn cần hoặc muốn sử dụng một ngôn ngữ có mục đích chung ? Đối với bản dựng, bạn cần:

    • các nhánh và điều kiện để xử lý các cấu hình, môi trường riêng biệt, v.v ...
    • một bộ hướng dẫn để trích xuất dữ liệu từ môi trường của bạn,
    • một bộ hướng dẫn để sản xuất hàng giao.

    Bạn không thực sự cần nhiều hơn nữa.

Chắc chắn điều đó thật khó chịu khi hệ thống xây dựng của bạn có vẻ như không đủ linh hoạt cho một trường hợp sử dụng đặc biệt mà bạn đang theo đuổi, nhưng có lẽ nó tốt hơn nhiều so với giải pháp thay thế cho hầu hết mọi người.

Đó có lẽ là lý do tại sao có sự phân cực giữa những người thích hệ thống xây dựng khai báo hơn hầu hết các lực lượng có thể lập trình: Tôi đoán một nhà phát triển có thể có xu hướng tự nhiên tìm cách thoát ra khỏi hộp.

Đợi đã, chúng ta có thực sự cần một công cụ không?

Một câu hỏi liên quan khác sẽ là: chúng ta có thực sự cần một công cụ xây dựng không? Có phải thực tế là chúng tồn tại trong tất cả các ngôn ngữ là dấu hiệu cho thấy chúng lấp đầy một khoảng trống thậm chí không nên ở đó ngay từ đầu?

Một số ngôn ngữ không nhất thiết phải có công cụ xây dựng. Chẳng hạn, hầu hết các ngôn ngữ script không cần một ngôn ngữ và giải quyết khi tải. Hoặc dùng Go, trình biên dịch sẽ xử lý mọi thứ cho bạn, đó là một điểm đối lập tuyệt vời: nếu trình biên dịch như gcc đột nhiên không cần một loạt cờ, trình liên kết và tệp kết xuất để kết hợp mọi thứ với nhau thì sao? Hoặc nếu javac không cần tệp build.xml hoặc pom.xml để cho anh ta biết phải làm gì? Không nên quản lý phụ thuộc trực tiếp là một phần của công cụ riêng của ngôn ngữ, vì các phụ thuộc là một phần của chương trình cuối cùng?

Nó chắc chắn có vẻ như là một cách tiếp cận đơn giản hơn nhiều cho người dùng (người xây dựng). Mặc dù người ta có thể lập luận rằng họ chỉ đang thực hiện dưới vỏ bọc và lấy đi sự lựa chọn và cơ hội của bạn để tác động đến quá trình xây dựng đó (nhưng sau đó bạn hy vọng một công cụ như vậy cho phép các phần mở rộng trình biên dịch và những thứ tương tự). Thêm vào đó, chúng tôi thường xem các công cụ và ngôn ngữ là hai thứ riêng biệt, vì vậy anh ta có vẻ không chắc chắn khi đột nhiên kết hợp chúng chặt chẽ như vậy.

Tôi không nghĩ rằng ngôn ngữ bạn sử dụng để xây dựng chương trình của mình là vấn đề nghiêm trọng. Đó là ngôn ngữ bạn sử dụng để lập trình, nền tảng và công cụ cốt lõi của nó là vấn đề quan trọng, và chúng tôi vẫn đang tiến tới đó.


Cá nhân, tôi đã sử dụng make / gmake / autotools / pmk và hài lòng với chúng cho C, và tôi bắt đầu với Java khi tất cả chúng ta đã tạo ra, sau đó là kiến, và bây giờ tôi thường thích Maven hơn tất cả các lựa chọn thay thế này. Mặc dù tôi có thể thấy giá trị trong gradle, buildr và những thứ khác, nhưng tôi thích sự phổ biến của maven cho đến khi sự thay đổi đáng kể hơn xảy ra. Thêm vào đó tôi thích điều đó cứng nhắc, nhưng vẫn cho bạn khả năng làm việc xung quanh nếu cần thiết. Điều đó không dễ dàng là một điều tốt.

Đây là một công cụ xây dựng. Chỉ cần học cách nắm lấy nó và không chiến đấu với nó. Đó là một trận thua. Hoặc ít nhất là một rất rất dài.


Thực sự thích chủ nghĩa thực dụng của bạn. Câu hỏi của tôi là ra khỏi sự tò mò. Tôi sử dụng maven (đã từng sử dụng make và ant trong quá khứ) và nó có "ma thuật đen" đôi khi tốt và đôi khi xấu. Nhưng nó vẫn là ma thuật.
vainolo

1
"Hoặc nếu javac không cần build.xml hoặc pom.xml để cho anh ta biết phải làm gì?" - heh. nó không và không bao giờ làm.
dùng253751

@immibis: điều đó gây tranh cãi. Tôi thực sự không thích xây dựng các dự án của mình tại văn phòng chỉ với javac :) Nó chắc chắn sẽ đòi hỏi một chút keo dán với Makefile hoặc shell script hoặc ít nhất là các bí danh shell để đặt mọi thứ lại với nhau. Hoặc một chương trình khổng lồ với mọi thứ trong một thư mục và tất cả các deps trong repo. Không thực sự là một cái gì đó tôi muốn! :) Nhưng đó là một cuộc tranh luận khác hoàn toàn, không liên quan đến câu hỏi của OP.
haylem

Việc tích hợp hệ thống xây dựng với ngôn ngữ cũng là vấn đề đối với các dự án polyglot. Nếu tôi sử dụng cả ngôn ngữ A và B và muốn có một quy trình xây dựng duy nhất cho chúng, tôi sẽ sử dụng hệ thống xây dựng ngôn ngữ nào?
Sebastian Redl

@SebastianRedl Vậy làm thế nào để vấn đề trở nên dễ dàng hơn bằng cách giới thiệu một ngôn ngữ thứ ba ? Chỉ cần chọn ngôn ngữ phù hợp hơn với bạn. (Và tất nhiên, nếu bạn cần một ngôn ngữ thứ ba, Java cũng có thể là ngôn ngữ đó.)
Ville Oikarinen

21

Javalà một mệnh lệnh ngôn ngữ, Ant, Maven, vv là tường thuật ngôn ngữ:

Chúng ta có thể định nghĩa sự khác biệt như sau:

  • Lập trình bắt buộc: nói với "cỗ máy" cách làm một cái gì đó, và kết quả là những gì bạn muốn xảy ra sẽ xảy ra.
  • Lập trình khai báo: nói với "cỗ máy" những gì bạn muốn xảy ra và để máy tính tìm ra cách thực hiện. 1

Các ngôn ngữ xây dựng cho người xây dựng biết nên làm gì, từ đâu nên thực hiện, v.v. Công cụ chạy bản dựng (được viết bằng ngôn ngữ bắt buộc, như @ElliottFrisch đã lưu ý), đọc các hướng dẫn này và hoàn thành chúng.

Các ngôn ngữ khai báo có vẻ phù hợp hơn trong các kịch bản xây dựng, vì các tác vụ xây dựng thường giống nhau và được coi là dễ bảo trì và dễ đọc hơn ở dạng đó so với dạng mã đầy đủ.


3
Có ít nhất một hệ thống xây dựng sử dụng ngôn ngữ bắt buộc. Scons sử dụng Python.
dùng16764

Làm cho nó bắt buộc không khó hơn viết một lớp có thể chứa một danh sách các phụ thuộc và một phương thức để giải quyết các phụ thuộc đó. Tôi nghi ngờ có một lý do khác --- chẳng hạn như thời gian khởi động JVM, có lẽ.

2
@Lee: Hầu như tất cả các công cụ xây dựng được sử dụng trong thế giới Java (Ant, Maven, Gradle, SBT, mật) cũng thường chạy trên JVM (ngoại trừ Rake, Buildr hoặc Scons, có thể , nhưng không có để chạy trên JVM).
Jörg W Mittag

6
@vainolo "Hầu hết mọi người không thực sự thích Ant / Maven / Make" thực sự? Đó là một tuyên bố táo bạo!
Ben Thurley

1
@BenThurley Tôi thích mọi người làm, tại sao kiến ​​được tạo ra? và nếu con kiến ​​thích, tại sao lại là maven? Và bây giờ tại sao mọi người sử dụng Gradle? Nhưng tôi đồng ý rằng đó là một tuyên bố táo bạo và nó chỉ được hỗ trợ bởi bằng chứng "giai thoại" của hàng chục nhà phát triển java
vainolo

4

Nếu bạn nhìn vào các tính năng của một hệ thống xây dựng điển hình bạn tìm thấy:

  1. Rất nhiều dữ liệu: tên, công tắc, cài đặt, mục cấu hình, chuỗi, v.v.
  2. Rất nhiều tương tác với môi trường: các lệnh, biến môi trường
  3. Một "công cụ xây dựng" tương đối đơn giản xử lý phụ thuộc, luồng, ghi nhật ký, vv

Nếu bạn bắt đầu viết một loạt các tệp xây dựng bằng một số ngôn ngữ (Java / C # / Python / etc), thì đến lần lặp thứ ba hoặc thứ tư, bạn sẽ giải quyết (a) giữ hầu hết dữ liệu và các lệnh bên ngoài dưới dạng dữ liệu trong một thứ gì đó như XML (b) viết "công cụ xây dựng" bằng ngôn ngữ yêu thích của bạn.

Bạn cũng sẽ thấy hữu ích khi coi một số dữ liệu trong XML của mình là ngôn ngữ được dịch, để kích hoạt các tính năng khác nhau trong công cụ xây dựng. Bạn cũng có thể diễn giải một số macro hoặc thực hiện thay thế chuỗi, trong dữ liệu.

Nói cách khác, bạn sẽ kết thúc với Make, hoặc Ant, hoặc Rake hoặc MsBuild. Một ngôn ngữ bắt buộc cho những thứ nó làm tốt và cấu trúc dữ liệu để mô tả những gì bạn muốn làm, thường là bằng XML.


2

Một số yếu tố được tính chống lại việc sử dụng Java / C ++ / C # trong những trường hợp này.

Trước tiên, bạn phải biên dịch tập lệnh xây dựng của mình trước khi có thể chạy nó để xây dựng ứng dụng của mình. Làm thế nào bạn sẽ chỉ định bất kỳ gói, cờ, phiên bản trình biên dịch, đường dẫn công cụ cần thiết để xây dựng tập lệnh xây dựng của bạn? Chắc chắn, bạn có thể tìm ra cách giải quyết, nhưng đơn giản hơn nhiều là có một ngôn ngữ không cần bước xây dựng đó (ví dụ python) hoặc ngôn ngữ mà công cụ xây dựng của bạn thực sự hiểu.

Thứ hai, các tệp xây dựng là dữ liệu nặng trong khi Java / C ++ / C # lại thiên về viết mã và thuật toán hơn nhiều. Java và bạn bè không có cách trình bày tất cả dữ liệu bạn muốn lưu trữ.

Thứ ba, Java và bạn bè cần rất nhiều mẫu soạn sẵn để có hiệu lực. Tệp xây dựng sẽ phải nằm trong một phương thức bên trong một lớp với tất cả các lần nhập của nó. Khi sử dụng ngôn ngữ kịch bản hoặc ngôn ngữ tùy chỉnh, bạn có thể tránh tất cả các bản tóm tắt đó và chỉ cần có các chi tiết xây dựng.


0

Thật! Tại sao không sử dụng một ngôn ngữ mạnh mẽbiểu cảm cho một vấn đề phức tạp hơn mọi người thường nghĩ (ban đầu)? Đặc biệt là khi những người phải đối mặt với vấn đề đã có năng lực với ngôn ngữ như vậy. (Tòa nhà là vấn đề của lập trình viên và được các lập trình viên giải quyết tốt nhất.)

Tôi cũng đã tự hỏi mình câu hỏi này nhiều năm trước và quyết định rằng Java là một ngôn ngữ tốt để xác định các bản dựng, đặc biệt là cho các dự án Java. Và, kết quả là, tôi bắt đầu làm một cái gì đó về nó.

TUYÊN BỐ TỪ CHỐI : Trong câu trả lời này, tôi đang quảng bá cho iwant , một hệ thống xây dựng mà tôi đang phát triển. Nhưng vì dù sao đây cũng là một cuộc thảo luận có ý kiến, tôi chắc chắn rằng nó ổn.

Tôi sẽ không giải thích chi tiết về lợi ích của Java (sức mạnh và tính biểu cảm) hoặc cụ thể. Nếu bạn quan tâm, bạn có thể đọc thêm trên trang iwant .

Thay vào đó, tôi sẽ xem xét tại sao Java (và các GPL khác) lại dễ dàng bị loại bỏ như vậy là không phù hợp để xây dựng. Nhiều câu trả lời và bình luận ở đây là những ví dụ tốt về suy nghĩ như vậy. Chúng ta hãy xem xét một số đối số điển hình:

"Java là bắt buộc, nhưng các bản dựng được xác định tốt nhất theo cách khai báo" , họ có thể nói.

Thật. Nhưng khi sử dụng ngôn ngữ làm ngôn ngữ kim loại cho DSL bên trong , điều thực sự được tính là cú pháp của nó . Ngay cả một ngôn ngữ bắt buộc như Java cũng có thể bị lừa để khai báo. Nếu nó trông và cảm thấy khai báo, đó là (cho mục đích thực tế) khai báo. Ví dụ:

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

Đây là một ví dụ thực tế từ dự án demo của iwant .

Trong thực tế, so sánh điều này với một số hệ thống xây dựng được cho là khai báo cho phép người dùng của họ tiếp xúc với các động từ bắt buộc như "thử nghiệm" hoặc "biên dịch". Tuyên bố trên chỉ chứa danh từ, không có động từ. Biên dịch và kiểm tra là các tác vụ được iwant xử lý ngầm để cấp cho người dùng các danh từ mà anh ấy / cô ấy muốn. Đó không phải là ngôn ngữ. Đó là cách bạn sử dụng nó.

"Java dài dòng"

Vâng, rất nhiều mã Java ngoài kia là dài dòng. Nhưng một lần nữa, đó không phải là ngôn ngữ, đó là cách bạn sử dụng nó. Nếu một triển khai dài dòng, chỉ cần gói gọn nó đằng sau một sự trừu tượng tốt đẹp. Nhiều GPL cung cấp các cơ chế đầy đủ cho việc này.

Chỉ cần tưởng tượng đoạn mã Java ở trên được viết bằng XML. Thay thế dấu ngoặc đơn bằng dấu ngoặc góc và di chuyển chúng xung quanh. Và sau đó sao chép mọi từ khóa dưới dạng thẻ đóng! Java là một cú phápkhông dài dòng.

(Tôi biết, so sánh với XML giống như lấy kẹo từ bé, nhưng rất nhiều bản dựng chỉ được định nghĩa trong XML.)

"Bạn sẽ phải biên dịch tập lệnh xây dựng của mình"

Đây là một điểm hợp lệ. Tuy nhiên, đó chỉ là một vấn đề kỹ thuật nhỏ cần giải quyết. Tôi có thể giải quyết nó bằng cách sử dụng beanshell hoặc một số trình thông dịch khác. Thay vào đó, tôi đã giải quyết nó bằng cách coi nó như một vấn đề xây dựng khác và bootstrapping iwant với một tập lệnh shell hoặc ant đơn giản để biên dịch và chạy một bootstrapper Java đơn giản.

"Java có bản tóm tắt"

Thật. Bạn phải nhập các lớp, bạn phải đề cập đến "công khai", "lớp", v.v. Và ở đây DSL đơn giản bên ngoài ghi được một chiến thắng dễ dàng ban đầu.

Và nếu dự án của bạn tầm thường đến mức cái nồi hơi này rất có ý nghĩa, xin chúc mừng. Vấn đề của bạn không phải là một vấn đề khó khăn và nó thực sự không quan trọng bằng cách bạn giải quyết nó.

Nhưng nhiều dự án cần nhiều hơn là biên soạn, báo cáo bảo hiểm và đóng gói. Nếu bản tóm tắt của Java được chấp nhận cho các vấn đề của khách hàng, tại sao không xây dựng các vấn đề? Tại sao chỉ làm giày cho trẻ em của người khác?


0

Một điều tôi không nghĩ rằng các câu trả lời khác đã giải quyết là những hạn chế và tính minh bạch của các ngôn ngữ xây dựng này là một phần rất lớn trong những gì làm cho chúng hữu ích. Hãy lấy Maven, ví dụ. Vâng, nó thực thi các bản dựng nhưng nó cũng xác định các phụ thuộc. Điều này cho phép xây dựng Maven để kéo các phụ thuộc đó xuống và xem xét các phụ thuộc của chúng, v.v.

Hãy xem xét nếu điều này được thực hiện với Java trực tiếp. Công cụ xây dựng sẽ thấy rằng có một sự phụ thuộc. Sau đó, nó sẽ cần phải kéo xuống để ứng dụng Java khác và thực thi nó để xác định các phụ thuộc của nó là gì. Nhưng đối với Maven, nó chỉ đơn giản là nhìn vào các tuyên bố phụ thuộc. Các tập tin xây dựng maven là trong suốt. Một ngôn ngữ hoàn chỉnh Turing vốn không minh bạch và do đó kém hơn đối với một số mục đích như ngôn ngữ này.


Làm thế nào để Gradle phù hợp trong việc này? Nó định nghĩa các phụ thuộc theo kiểu khai báo, sử dụng ngôn ngữ mục đích chung (Groovy). Trong công cụ dựa trên Groovy, JavaScript hoặc Lisp, việc sử dụng trình biên dịch hoặc trình thông dịch của ngôn ngữ để phân tích các khai báo, cho dù bạn chỉ muốn đọc chúng hay 'thực thi' chúng (áp dụng một số chức năng). Tính hai mặt của mã và dữ liệu không phải là một phần của thành ngữ Java được chấp nhận chung, mặc dù không phải là không thể. Turing hoàn thiện không ngăn chặn đại diện dữ liệu tốt. Nó mở ra khả năng dữ liệu của bạn sẽ làm điều gì đó mà bạn không mong đợi nó sẽ làm.
joshp

@joshp Tôi không quen với Gradle. Nó được mô tả như một DSL và mọi thứ trông khá khai báo. Dựa trên Groovy không nhất thiết có nghĩa là nó tương đương với Groovy về sức mạnh của nó. Có lẽ bạn sẽ ở vị trí tốt hơn để nói nếu Gradle thực tế là một ngôn ngữ hoàn chỉnh Turing. Các ví dụ phụ thuộc tôi nhìn có vẻ khá đơn giản. Bạn có thể sử dụng các biểu thức Groovy tùy ý trong những thứ như khai báo phụ thuộc không?
JimmyJames

Cá nhân tôi thậm chí không thích phụ thuộc quá độ. Thường thì chúng chỉ gây ra sự ngạc nhiên trong đường dẫn lớp (nhiều phiên bản thư viện không tương thích). Đó là lý do tại sao maven có yếu tố loại trừ, nhưng rắc rối không chỉ đáng giá. Phụ thuộc rõ ràng làm cho cuộc sống đơn giản hơn. Tuy nhiên, các phụ thuộc bắc cầu có thể được thực hiện với Java. Tôi đã làm một cái gì đó tương tự với iwant bằng cách sử dụng lại các định nghĩa xây dựng của các dự án khác.
Ville Oikarinen

@VilleOikarinen Tôi tình cờ đồng ý với bạn. Tôi nghĩ rằng nó cũng gây ra rất nhiều phiền toái vì không có chi phí cảm nhận để kéo theo nhiều phụ thuộc hơn ngay cả khi bạn không sử dụng chúng. Tuy nhiên, trong bối cảnh của câu trả lời này, tôi không bình luận về giá trị hoặc sự khôn ngoan của tính năng đó mà là cách sử dụng DSL hữu ích trong việc đạt được nó.
JimmyJames

1
@VilleOikarinen Tôi nghĩ rằng chúng tôi đã đạt đến cuối của điều này nhưng tôi chỉ muốn làm rõ rằng tôi không nói về pom / maven. Đây là một ví dụ về DSL xây dựng nhưng tôi không nghĩ nhiều về nó. Tôi sử dụng nó một cách bừa bãi và tôi nghĩ nó thật rắc rối. Nhưng những gì có pom nên một ưu thế là tuyên bố phụ thuộc. Tôi đã sử dụng Buildr một thời gian và nó đọc pom cho các phụ thuộc nhưng nó không sử dụng chúng cho các thông số kỹ thuật xây dựng. Có một số công cụ không dựa trên Java hiểu được pom này mà là AFAIK, tất cả những gì họ quan tâm là sự phụ thuộc.
JimmyJames
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.