Java가 빌드 언어로 사용되지 않는 이유는 무엇입니까?


24

Java가 범용 언어이고 프로그램을 빌드하는 것이 Java 언어를 사용하여 설명 할 수있는 것이라면 왜 이것이 빌드 파일을 작성하는 가장 좋은 방법이 아닌 대신 Ant, Maven 및 Gradle과 같은 도구를 사용합니까? 더 간단하지 않고 또 다른 프로그래밍 언어를 배울 필요가 없습니까? (BTW-이 질문은 C #과 같은 다른 언어에도 적용될 수 있습니다)


7
"빌드 언어에 범용 언어가 사용되지 않는 이유"에 대해 조금 더 흥미로운 질문이있을 수 있습니다. C는 빌드 언어도 아닙니다. 또한 주변의 시상식에서 찾고 좋을 것 자바로 단일 된 .java 파일을 컴파일

8
이것은 아마도 "DSL을 왜 귀찮게 하는가?"로 일반화 될 수 있습니다.
FrustratedWithFormsDesigner

1
더 좋은 질문은; 왜 IDE / 컴파일러 / 도구가 그렇게 나빠서 빌드 도구가 처음에 필요합니까?
Brendan

6
빌드 도구와 IDE가 다른 목적을 제공하므로 @Brendan은 의문의 여지가 없습니다.
jwenting

1
"일반 목적"언어는 잘 정의 된 간단한 도메인 별 언어 대신 사용해서는 안됩니다. "아직 다른 프로그래밍 언어"를 배울 필요가 있다면, 프로그래밍을해서는 안되며 다른 거래를 시도해보십시오.
SK-logic

답변:


21

특정 목적을위한 특정 도구

  • 다변

    범용 언어는 종종 너무 장황합니다. Java로 빌드를 관리해야한다면 짐승의 크기에 따라 매우 빨리 우울해질 것입니다. 그러나 Java로 작성된 DSL을 사용하여 쉽게 관리 할 수 ​​있습니다. 그리고 어느 정도까지 Gradle (Groovy)과 Buildr (Ruby)를 볼 수 있습니다.

  • 어려움

    범용 언어는 어렵다. 글쎄, 나는 프로그래밍이 어렵다고 생각하지 않으며 누군가가 선택할 수는 없지만 요점은 빌드 엔지니어가 반드시 프로그래머가 아니라는 것입니다!

  • 목적

    난이도 와 세부 정보 의 교차점에서 어느 정도 입니다. 언어는 목적을 위해 설계되었으며 여기서는 매우 구체적인 것에 대해 이야기하고 있습니다. 그럼 왜 필요하거나 사용하려는 것이 일반적인 목적의 언어를? 빌드에는 다음이 필요합니다.

    • 개별 구성, 환경 등을 처리하기위한 분기 및 조건부 ...
    • 환경에서 데이터를 추출하기위한 지침 세트
    • 결과물을 생산하기위한 일련의 지침.

    더 이상 필요하지 않습니다.

빌드 시스템이 특별한 유스 케이스에 충분히 유연하지 않은 것처럼 보일 때 성가 시지만 대부분의 사람들의 대안보다 훨씬 낫습니다.

그렇기 때문에 대부분의 프로그래밍 가능 프로그램보다 선언적 빌드 시스템을 선호하는 사람들 사이에 극성이있는 이유는 아마도 개발자가 상자에서 벗어날 수있는 방법을 찾는 자연스러운 경향이있을 것입니다.

잠깐, 우리는 정말로 도구가 필요합니까?

또 다른 관련 질문은 다음과 같습니다. 실제로 빌드 도구가 필요합니까? 그들이 모든 언어로 존재한다는 사실이 처음부터 거기에 있어서는 안되는 간격을 메운다는 표시가 아닙니까?

일부 언어에는 반드시 빌드 도구가 필요하지 않습니다. 예를 들어, 대부분의 스크립팅 언어는 언어를 필요로하지 않으며로드시 해결됩니다. 또는 컴파일러가 당신을 위해 모든 것을 처리 할 Go를 가져 가십시오 .gcc와 같은 컴파일러에 갑자기 모든 플래그, 링커 및 makefile이 필요하지 않으면 어떻게해야합니까? 또는 javac에 build.xml 또는 pom.xml이 필요하지 않은 경우 어떻게해야합니까? 의존성이 최종 프로그램의 일부이기 때문에 의존성 관리가 언어 자체 툴링의 일부가 아니어야합니까?

분명히 사용자 (빌더)에게는 훨씬 간단한 접근법처럼 보입니다. 비록 그들이 단지 후드 아래에서하고 있고 빌드 프로세스에 영향을 줄 수있는 선택과 기회를 제거한다고 주장 할 수는 있지만 (그러나 그러한 도구는 컴파일러 확장과 비슷한 것들을 허용하기를 바랍니다). 또한 우리는 도구와 언어를 별개의 두 가지로 보았 기 때문에 갑자기 도구가 너무 밀접하게 결합되어 있지 않은 것처럼 보일 수 있습니다.

프로그램을 빌드하는 데 사용하는 언어가 sthe 문제라고 생각하지 않습니다. 프로그래밍에 사용하는 언어와 핵심 플랫폼 및 툴링이 중요하며, 우리는 여전히 진전을 보이고 있습니다.


개인적으로, 나는 make / gmake / autotools / pmk를 사용하여 C에 만족했고, 우리가 만든 모든 것이 개미 였을 때 Java로 시작했으며 이제는 일반적으로 이러한 모든 대안보다 Maven을 선호합니다. gradle, buildr 및 기타에서 가치를 볼 수 있지만 더 큰 변화가 발생할 때까지 지금까지 maven의 보급을 좋아합니다. 또한 나는 그것이 단단하다는 것을 좋아 하지만 여전히 필요한 경우 그 문제를 해결할 수 있습니다. 쉽지 않은 것은 좋은 것입니다.

빌드 도구입니다. 그것을 받아들이는 법을 배우고 싸우지 마십시오. 지는 전투이다. 또는 적어도 매우 긴 것.


실용주의와 똑같습니다. 내 질문은 호기심이 없습니다. 나는 maven (과거에 사용 된 make와 개미를 가졌던)을 사용하며, 때때로 좋고 나쁜 "black magic"을한다. 그러나 여전히 마법입니다.
vainolo

1
"또는 javac가 build.xml 또는 pom.xml이 필요하지 않은 경우 어떻게해야합니까?" -응 하지 않았고 결코하지 않았다.
user253751

@immibis : 논쟁의 여지가 있습니다. 나는 javac 만 사용하여 사무실에서 프로젝트를 빌드하는 것을 정말로 좋아하지 않을 것입니다. 또는 하나의 폴더에있는 모든 항목과 레포에있는 모든 뎁이있는 거대한 프로그램. 내가 정말로 원하는 것이 아닙니다! :) 그러나 그것은 OP의 질문과 관련이없는 또 다른 논쟁입니다.
haylem

빌드 시스템을 언어와 통합하는 것도 폴리 글 로트 프로젝트에서 문제가됩니다. 언어 A와 B를 모두 사용하고 단일 빌드 프로세스를 원하는 경우 어떤 언어의 빌드 시스템을 사용합니까?
Sebastian Redl

@SebastianRedl 그렇다면 제 3의 언어 를 도입함으로써 문제가 어떻게 더 쉬워 집니까? 자신에게 가장 적합한 언어를 선택하십시오. (물론, 제 3 언어가 필요한 경우 Java도 가능합니다.)
Ville Oikarinen

21

Java되는 필수 , 언어 Ant, Maven등이다 선언적 언어 :

차이점을 다음과 같이 정의 할 수 있습니다.

  • 명령형 프로그래밍 : "기계" 에게 무언가를 수행 하는 방법 을 알려 주면 결과적으로 원하는 일이 발생합니다.
  • 선언적 프로그래밍 : "기계" 에게 무슨 일이 일어나고 있는지 말하고 컴퓨터가 어떻게해야하는지 알아 내십시오. 1

빌드 언어는 빌더 에게 수행해야 할 작업, 수행 위치 등을 알려 줍니다. 빌드 를 실행 하는 엔진 (@ElliottFrisch와 같이 명령형 언어로 작성 됨)은이 지침을 읽고이를 이행합니다.

빌드 작업은 일반적으로 완전히 동일하기 때문에 선언적 언어는 빌드 시나리오에서 더 적절 해 보일 수 있으며 본격적인 코드 형식보다 해당 형식으로 유지 관리가 쉽고 읽기 쉬운 것으로 간주됩니다.


3
명령형 언어를 사용하는 빌드 시스템이 하나 이상 있습니다. 스콘은 파이썬을 사용합니다.
user16764

의존성을 만드는 것은 의존성 목록을 포함 할 수있는 클래스와 이러한 의존성을 해결하는 방법을 작성하는 것보다 어렵지 않습니다. 아마도 JVM 시작 시간과 같은 다른 이유가 있다고 생각합니다.

2
@Lee : 거의 모든 자바 세계에서 사용되는 빌드 도구 (개미, 메이븐, Gradle을, SBT, ...) 일반적 (레이크, Buildr 또는 SCons는의 예외와 JVM에서 실행의 있지만하지 않는 JVM 에서 실행).
Jörg W Mittag

6
@vainolo "대부분의 사람들은 개미 / 모자 / 만들기를 정말로 좋아하지 않습니다"? 대담한 말입니다!
Ben Thurley

1
@BenThurley 내가 사람들이 만드는 것을 좋아했는데 왜 개미가 만들어 졌습니까? 개미가 마음에 들었다면 왜 메이븐이 되었습니까? 그리고 왜 사람들은 Gradle을 사용합니까? 그러나 나는 그것이 대담한 진술이라는 것에 동의하며, 수십 명의 자바 개발자에 대한 "
비극적 인

4

일반적인 빌드 시스템의 기능을 살펴보면 다음을 찾을 수 있습니다.

  1. 많은 데이터 : 이름, 스위치, 설정, 구성 항목, 문자열 등
  2. 환경과의 많은 상호 작용 : 명령, 환경 변수
  3. 종속성, 스레딩, 로깅 등을 처리하는 비교적 간단한 "빌드 엔진"

일부 언어 (Java / C # / Python / etc)를 사용하여 일련의 빌드 파일을 작성하기로 설정 한 경우 약 3 ~ 4 회 반복하여 (a) 대부분의 데이터와 외부 명령을 데이터로 유지 (b) 좋아하는 언어로 "빌드 엔진"을 작성하십시오.

또한 XML의 일부 데이터를 해석 된 언어로 취급하여 빌드 엔진의 다양한 기능을 트리거하는 것이 유용하다는 것을 알 수 있습니다. 데이터에서 일부 매크로를 해석하거나 문자열 대체를 수행 할 수도 있습니다.

즉, Make 또는 Ant, Rake 또는 MsBuild로 마무리합니다. 잘하는 일을위한 명령형 언어, 그리고 현재 XML로하고 싶은 것을 설명하는 데이터 구조.


2

이 경우 Java / C ++ / C # 사용에 대한 여러 가지 요소가 있습니다.

먼저, 빌드 스크립트를 실행하여 앱을 빌드하기 전에 빌드 스크립트를 컴파일해야합니다. 빌드 스크립트를 빌드하는 데 필요한 패키지, 플래그, 컴파일러 버전, 도구 경로를 어떻게 지정 하시겠습니까? 확실히, 당신은 그 주위에 방법을 생각해 낼 수 있지만, 그 빌드 단계를 필요로하지 않는 언어 (예 : 파이썬) 또는 빌드 도구가 기본적으로 이해하는 언어를 갖는 것이 훨씬 간단합니다.

둘째, 빌드 파일은 데이터가 많은 반면 Java / C ++ / C #은 코드 및 알고리즘 작성에 훨씬 적합합니다. Java와 친구는 저장하려는 모든 데이터를 간결하게 표현하지 못합니다.

셋째로, Java와 친구는 유효하려면 많은 상용구가 필요합니다. 빌드 파일은 가져 오기가 모두 포함 된 클래스 내의 메소드 내에 있어야합니다. 스크립팅 언어 또는 사용자 정의 언어를 사용할 때 모든 상용구를 피하고 빌드 세부 정보를 가질 수 있습니다.


0

과연! 사람들이 종종 (초기) 생각하는 것보다 복잡한 문제에 강력 하고 표현력있는 언어를 사용하지 않겠습니까? 특히 문제에 직면 한 사람들이 이미 그러한 언어에 능숙 할 때. (빌딩은 프로그래머 자신의 문제이며 프로그래머가 가장 잘 해결합니다.)

또한 몇 년 전에이 질문을 저에게 물었고 Java는 특히 Java 프로젝트의 빌드를 정의하기에 좋은 언어라고 결정했습니다. 결과적으로 나는 그것에 대해 무언가를 시작했습니다.

면책 조항 :이 답변에서 나는 개발중인 빌드 시스템 인 iwant을 홍보 하고 있습니다. 그러나 이것은 어쨌든 의견이 많은 토론이므로 괜찮습니다.

Java (power and expressiveness) 또는 iwant의 이점에 대해 구체적으로 설명하지 않겠습니다. 관심이 있으시면 iwant 페이지 에서 더 많은 것을 읽을 수 있습니다 .

대신 Java (및 기타 GPL)가 구축하기에 부적합한 것으로 쉽게 해산되는 이유를 살펴 보겠습니다. 여기에 많은 답변과 의견이 그러한 사고의 좋은 예입니다. 일반적인 주장 중 일부를 고려해 봅시다.

"자바는 필수적이지만 빌드는 선언적인 방식으로 정의하는 것이 가장 좋습니다 ."

참된. 그러나 언어를 내부 DSL 의 금속 언어로 사용할 때 실제로 중요한 것은 구문 입니다. Java와 같은 명령형 언어조차도 선언적 으로 속일 수 있습니다. 선언적으로 보이고 느껴지면 (실제적인 목적으로) 선언적입니다. 예를 들면 다음과 같습니다.

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

이것은 iwant 데모 프로젝트의 실제 예입니다 .

실제로, 이것을 "테스트"또는 "컴파일"과 같은 명령형 동사에 사용자를 노출시키는 일부 선언적 빌드 시스템과 비교하십시오. 위의 선언에는 명사 만 있고 동사는 없습니다. 컴파일 및 테스트는 사용자가 원하는 명사를 부여하기 위해 iwant에 의해 암시 적으로 처리되는 작업입니다. 언어가 아닙니다. 당신이 그것을 사용하는 방법입니다.

"자바는 장황하다"

예, 많은 Java 코드가 상세합니다. 그러나 다시, 그것은 언어가 아니며, 그것이 당신이 그것을 사용하는 방법입니다. 구현이 장황한 경우 멋진 추상화 뒤에 캡슐화하십시오. 많은 GPL이이를위한 적절한 메커니즘을 제공합니다.

XML로 작성된 위의 Java 스 니펫을 상상해보십시오. 괄호를 꺾쇠 ​​괄호로 바꾸고 움직이십시오. 그런 다음 모든 키워드를 닫기 태그로 복제하십시오 ! 구문 으로서의 Java 는 장황 하지 않습니다 .

(XML과 비교하면 아기에게서 사탕을 먹는 것과 같지만 많은 빌드가 XML로 정의 되기만합니다.)

"빌드 스크립트를 컴파일해야합니다"

이것은 유효한 포인트입니다. 그럼에도 불구하고 해결해야 할 사소한 기술적 문제 일뿐입니다. 나는 콩 껍질 이나 다른 통역사를 사용하여 해결할 수있었습니다 . 대신 다른 빌드 문제로 처리하고 간단한 Java 부트 스트 래퍼를 컴파일하고 실행하는 간단한 쉘 또는 개미 스크립트로 iwant을 부트 스트랩하여 문제를 해결했습니다.

"자바는 상용구가있다"

참된. 클래스를 가져와야하며 "public", "class"등을 언급해야합니다. 그리고 여기에 간단한 외부 DSL이 초기에 쉽게 승리합니다.

그리고 프로젝트가 너무 사소한 경우이 상용구가 중요하다면 축하합니다. 당신의 문제는 어려운 문제가 아니며 실제로 어떻게 해결하든 문제가되지 않습니다.

그러나 많은 프로젝트는 컴파일, 커버리지 보고서 및 패키징 이상의 기능을 필요로합니다. Java의 상용구가 고객의 문제에 허용되는 경우 문제를 해결하지 않으시겠습니까? 왜 다른 사람의 아이들을 위해서만 신발을 만드나요?


0

다른 답변에서 언급하지 않은 한 가지는 이러한 빌드 언어의 한계와 투명성이 유용한 언어의 큰 부분이라는 것입니다. 예를 들어 Maven을 보자. 예, 빌드를 실행하지만 종속성도 정의합니다. 이를 통해 Maven 빌드가 해당 종속성을 풀고 해당 종속성 등을 볼 수 있습니다.

이것이 Java로 직접 수행되었는지 고려하십시오. 빌드 도구는 종속성이 있음을 알 수 있습니다. 그런 다음 다른 Java 응용 프로그램을 풀다운하여 실행하여 종속성이 무엇인지 확인해야합니다. 그러나 Maven의 경우 단순히 종속성 선언을 살펴 봅니다. maven 빌드 파일은 투명합니다. 튜링 완성 언어는 본질적 으로 투명하지 않으므로 이와 같은 일부 목적에서는 열등합니다.


Gradle은 이것에 어떻게 적합합니까? 범용 언어 (Groovy)를 사용하여 선언적 스타일로 종속성을 정의합니다. Groovy, JavaScript 또는 Lisp 기반 도구에서 언어의 컴파일러 또는 인터프리터를 사용하여 선언을 읽거나 '실행'(일부 함수 적용) 여부에 관계없이 선언을 구문 분석하는 것이 당연합니다. 코드와 데이터의 이중성은 일반적으로 인정되는 Java 관용구의 일부가 아니지만 불가능하지는 않습니다. 튜링 완성도는 우수한 데이터 표현을 방해하지 않습니다. 데이터가 예상치 못한 일을 할 가능성을 열어줍니다.
joshp

@joshp Gradle에 익숙하지 않습니다. DSL로 설명되어 있으며 다소 선언적입니다. Groovy에 기반을 둔다고해서 그것이 Groovy와 동등하다는 것을 의미하지는 않습니다. Gradle이 실제로 Turing-complete 언어인지 말하기에 더 나은 위치에있을 것입니다. 내가 본 의존성 예제는 상당히 단순 해 보입니다. 의존성 선언과 같은 것에 임의의 Groovy 표현식을 사용할 수 있습니까?
JimmyJames

개인적으로 나는 전이 의존성을 좋아하지 않습니다. 종종 그들은 클래스 패스 (다수의 호환되지 않는 버전의 라이브러리)에서 놀라움을 유발합니다. 그렇기 때문에 maven에 exclude 요소가 있지만 번거 로움은 그만한 가치가 없습니다. 명시 적 종속성은 삶을 더 단순하게 만듭니다. 여전히 전이 종속성 Java로 구현할 있습니다. 다른 프로젝트의 빌드 정의를 재사용 하여 iwant 과 같은 것을 했습니다.
Ville Oikarinen

@VilleOikarinen 나는 주로 당신에게 동의합니다. 나는 그것을 사용하지 않더라도 더 많은 의존성을 끌어들이는 데 드는 비용이 없기 때문에 엄청난 팽창을 유발한다고 생각합니다. 그러나이 답변의 맥락에서 나는 그 기능의 가치 또는 지혜에 대해 언급하지 않고 DSL 사용이 그것을 달성하는 데 어떻게 유용한 지에 대해 언급하고 있습니다.
JimmyJames

1
@VilleOikarinen 나는 우리가 이것의 끝에 도달했다고 생각하지만, 나는 내가 pom / maven에 대해 이야기하고 있지 않다는 것을 분명히하고 싶다. 이것은 빌드 DSL의 예이지만 많이 생각하지는 않습니다. 나는 그것을 어리석게 사용하고 그것이 어수선하다고 생각합니다. 그러나 pom이 지배적 인 것은 종속성 선언입니다. 나는 Buildr를 잠시 동안 사용했고 의존성에 대해서는 pom을 읽지 만 빌드 스펙에는 사용하지 않습니다. Java 기반이 아닌이 pom을 이해하는 여러 도구가 있지만 AFAIK는 그들이 의존하는 모든 것입니다.
JimmyJames
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.