메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

한빛랩스 - 지식에 가능성을 머지하다 / 강의 콘텐츠 무료로 수강하시고 피드백을 남겨주세요. ▶︎

IT/모바일

Raven 소개: 자바를 멋있게 빌드하기(2)

한빛미디어

|

2007-12-28

|

by HANBIT

11,294

제공 : 한빛 네트워크
저자 : Matthieu Riou
역자 : 백기선
원문 : Introducing Raven: An Elegant Build for Java

조금 더

컴파일과 패키징은 좋다. 그러나 그것들은 단지 빌드 과정 중의 시작일 뿐이다. 예를 들어, Commons Net Ant 스크립트는 테스트와 Javadoc도 다루고 있다. 이런 것들을 Raven을 사용하여 어떻게 할 수 있을까? 자 다시 한 번 보자. 매우 간단하다. 그렇지 않은가.
junit "test"=>["compile", "compile_deps", "test_deps"] do |task|
  task.build_path << "src/test"
  task.test_classes << "**/*Test.java"
end

javadoc "jdoc" do |task|
  task.build_path << "src/java"
end
이 코드가 무엇을 하는지 이해하기 위해서는 그리 많은 설명이 필요하지 않을 것 같다. 태스크 안에 위치한 설정들은 Commons Net이 Raven의 기본 디렉터리 구조를 따르고 있지 않기 때문이라는 것만 알아두자. 만약에 모든 테스트들이 src/test/java 폴더에 있고, 해당 클래스들이 Test* 패턴으로 구성되어 있다면, 태스크는 비어있을 것이다.

자세하게 설명하지는 않겠지만 반드시 알아야 하는 태스크들이 조금 남아있다. 그러한 태스크들은 다음과 같다.

jar_source
프로젝트 소스 파일을 포함하고 있는 jar 파일 생성

war
Src/main/webapp에 위치한 웹 애플리케이션 자원들과 컴파일 한 클래스를 가지고 WAR 파일 생성

lib_dir
라이브러리 디렉터리를 만들고 프로젝트가 필요로 하는 의존성들을 그 안에 위치시킨다. 그렇게 함으로써 실행 스크립트(bat 또는 sh)에서 클래스패스를 구성하기 쉽게 해준다.

거인의 어깨 위에서

완전해지기 위해서, 실제 예제는 배포 빌드를 포함하고 있어야 한다. Commons Net 원래 빌드는 dist 태스크를 가지고 있으며, 그렇지 않더라도 배포는 대부분의 경우에 매우 흔히 사용한다. 그럼, Raven을 사용해서 배포를 어떻게 할 수 있을까? 흠, 글쎄. 할 수 없다. Raven에는 배포를 빌드 해주는 것이 아무것도 없다. 배포를 하는 표준적인 방법이 존재하지 않다는 것을 알고 있을 것이다. 그러나 그런 사람이 혼자는 아니니까 걱정할 필요는 없다. 본 글을 시작할 때 얘기했듯이, Raven은 Rake를 기반으로 만들어졌기 때문에, Ruby 인터프리터를 실행할 수 있다. 따라서 dist 태스크는 Rake 태스크로 간단하게 처리할 수 있다.
lib_dir("dist:libs" => "compile_deps") do |task| 
  task.target = "dist/lib"
end

task "dist" => ["commons-net.jar", "dist:libs"] do
  cp ["LICENSE.txt", "NOTICE.txt", "target/commons-net.jar"], "dist"
  File.open("dist/README.txt", "w") { |f| f << "Built on #{Time.now}" }
end
예제 코드 첫 번째 줄은 앞에서 설명했던, lib_dir 태스크 사용법을 보여주고 있다. 그 뒤에 재미있는 부분이 있다. Dist 태스크는 Rake 표준 태스크로써, 선수 조건을 확인하고 그 후에 코드 몸체 부분을 실행한다. 여기서는 jar 를 만들어야 하며 라이브러리들이 lib 서브 디렉터리에 있어야 한다는 것을 설정했다. 나머지 부분은 간단한 순수 Ruby다.

Rake는 기본 파일 기능인 cp(복사), mv(이동), mkdir(디렉터리 생성), rm(삭제)와 같은 것들을 수행하는 Ruby 모듈을 미리 포함시킨다. 이런 것들은 일반적으로 많은 파일 조작을 해야 할 빌드에서 매우 유용하다. 따라서, 내가 작성한 태스트 블럭의 첫 번째 줄은 라이선스, 공지 그리고 dist 디렉터리에 생성한 jar 파일을 복사한다. 대부분의 것들과 비슷하게 cp 메소드는 배열을 받아들인다.

두 번째 줄은 몇몇 파일 내용을 열어보는 것에 관한 것이다. 새로운 README 파일을 생성하고 그 안에 간단한 타임스탬프를 집어 넣는다. 문자열 안에 있는 #{..} 구문을 빼지 말아야 한다. 이 것을 사용하면 문자열 안에 변수 값의 계산 결과를 추가할 수 있다. (“Built on” + new Date().toString()과 동일하다.). 이런 종류의 데이터를 README에 추가할 때 w+ 플래그를 사용할 것이다. 하지만 README가 없기 때문에 비어있는 파일을 생성했다.

Dist 태스크를 끝으로 빌드를 완성했다. 지금까지 살펴본 것들은 모두 원래 Ant 스크립트에 있던 것들을 대체 했다. 170 줄의 빌드를 20 줄로 줄였다. 대략 10배 정도의 관리해야 하는 코드를 줄인 것이다. 하지만 좀 더 높은 곳에 다다르기 위해서 흐름 제어 문법 사용법을 설명해야겠다.
MODULES = ["web", "business", "persistence"]

MODULES.each do |mod|
  javac "#{mod}:compile" => ["#{mod}_deps", "common_deps"]
end
이 태스크는 주어진 모듈 목록에 대한 컴파일을 수행한다. 반복할 필요 없이 순환하면 되는 것이다. 태스크에서 메소드를 생성할 수도 있으며 그것을 태스크에서 특정 파라미터와 함께 호출할 수도 있다. 이는 프로그래밍을 할 때는 매우 기본적으로 사용했었던 것이지만, 현재 대부분의 빌드 도구에서는 사용할 수 없었다.

이제 여러분들이 Ruby와 같은 스크립트 언어에 기반했기 때문에 Raven이 얼마나 큰 힘을 얻었는지 알게 되었기를 바란다. 이제 Raven이 제공하는 매우 강력하고 간결한 자바를 위한 태스크들을 가지게 되었다. 프레임워크에 맞지 않는 것들을 위해서 멋진 안전망이 (플러그인 프레임워크 내부에) 제공된다.

차선책

Raven이 유일한 빌드 도구는 아니다. 근래에 이용할 수 있었던 도구들에 대한 실망과 빌드 문제에 대해 필자가 내린 대답일 뿐이다. 다른 사람들은 같은 문제에 대해 다른 해결책을 가져올 수도 있으므로, 필자가 제시한 해결책이 모두에게 최선이라고 주장하진 않겠다. Raven과 같은 것을 기반으로 한, 즉 Rake를 기반으로 한 다른 대안들도 존재한다. 그러나 상이한 철학을 가지고 있다.

첫 번째 대안은 Antwrap이 될 수 있다. 실제로 Raven의 대체제로 생각하진 않지만, 꽤 좋은 보완제가 될 수는 있다. 이 것을 사용하면, 기존에 작성했던 Ant 태스크를 XML 보다 훨씬 간결한 문법을 사용하여 재사용할 수 있다. 따라서, 똑 같은 스크립트가 있을 때 그 안에 모든 것이 포함되어 있다면 Raven을 사용하고, 기존에 존재하는 Ant 태스크들에 만족한다면 Antwrap을 사용하면 된다.

두 번째 도구는 Buildr이다. 이것은 아파치 인큐베이터 프로젝트이며 Raven와 완전하게 겹친다. 따라서 완전한 대체제가 될 수 있다. 차이점은 철학에 있다. Raven은 명시적으로 프로젝트를 어떻게 빌드해야 하는지 여러분이 꼭 작성해야 한다. Buildr은 그 보다는 좀더 선언적으로 여러분의 빌드가 어떤 형태를 띄는지 기술하도록 한다. 따라서, 다르게 이야기하자면, Maven보다 Ant 스타일을 선호하는 사람들에게는 Raven이 좋을 것이며, Maven 모델이 좀 더 마음에 드는 분들에게는 아마도 Buidr가 더 맘에 들 것이다. 이런 것이 문제가 되지는 않는다고 본다. 소프트웨어는 취향과 선호도 문제이기도 하니까 여러분에게 좀 더 편한 도구를 선택하는 것이 좋겠다.

결론

이번 아티클에서, 여러분들은 기존에 존재하는 자바 프로젝트를 위한 빌드 스크립트를 Raven을 사용하여 작성하는 방법을 익혔다. 의존성, 컴파일, 패키지 그리고 대부분의 자바 소프트웨어 빌드에서 필요로하는 작업들을 어떻게 다루는지 살펴보았다. 하지만, 이번 글에서 필자가 설명한 것 이외에도 Raven에는 훨씬 많은 기능이 있다. 특히 의존성 관리 쪽이 그러하다. Raven 웹 사이트와 책(참조에 있슴)을 통해서 좀 더 살펴보길 권장한다. 추가적으로 Rake와 Ruby언어에도 재미를 느꼈으면 좋겠다.

Raven과 별개로, 필자는 여러분들이 빌드 시스템에 요구사항이 좀 더 많아졌으면 좋겠다. 풍부한 스크립트 환경이 최소한 갖춰져야 한다. 너무 많은 시간을 XML 작성에 소비한 것 같다.

리소스
  • 본 글에서 Rakefile과 관련된 소스코드
  • Raven 배포판, 간단하게 설치할 수 있는 JRuby로 패키징한 것을 다운로드.
  • Apache Commons Net 본 글에서 빌드한 소스 배포한을 다운로드.
  • Raven 웹 사이트에 보다 많은 정보와 예제가 있슴.
  • Raven 책. 좋은 레퍼런스
  • Rake 문서
  • Antwrap
  • Buildr

저자 Matthieu Riou는 여러 회사의 컨설턴트, 프리랜서, 개발자, 엔지니어로 일하고 있다. 그는 아파치 소프트웨어 재단의 부사장이자, 몇몇 오픈 소스 프로젝트를 창시했다.


역자 백기선님은 AJN(http://agilejava.net)에서 자바 관련 스터디를 하고 있는 착하고 조용하며 점잖은 대학생입니다. 요즘은 특히 Spring과 Hibernate 같은 오픈소스 프레임워크를 공부하고 있습니다. 공부한 내용들은 블로그(http://whiteship.tistory.com)에 간단하게 정리하고 있으며 장래 희망은 행복한 개발자입니다.
TAG :
댓글 입력
자료실

최근 본 상품0