sitelink1  
sitelink2  
sitelink3  
http://wiki.javajigi.net/pages/viewpage.action?pageId=2240&focusedCommentId=2323

2.1 Ant

Ant는 구조적으로는 make를 그대로 이어 받았다. build.xml에 빌드 설정을 해두고 ant 명령을 실행하면 빌드 작업이 수행된다. Ant는 자주 하는 작업인 컴파일, 압축, 복사, 메일, SCM 등의 태스크를 미리 갖추어 놓았기 때문에 make보다 훨씬 간단하게 빌드 설정을 할 수 있다. 전체 태스트 목록은 http://ant.apache.org/manual/tasksoverview.html 에서 확인하기 바란다.

Ant의 표준 빌드 파일인 build.xml의 예를 보자.
test 패키지에 있는 HelloAnt.java 파일을 컴파일하고, jar 압축하고, 배포하고, 실행하는 작업을 수행한다.

build.xml
<?xml version="1.0" encoding="euc-kr"?><project name="Hello Ant" default="dist">       	<!-- 프로퍼티를 지정 합니다. -->        <property file="build.properties"/>        <property name="base.dir"  value="."/>        <property name="dist.dir"  value="dist"/>        <property name="build.dir" value="build"/>        <property name="src.dir"   value="src"/>        <property name="jar.file"  value="${version}_helloworld.jar"></property>        <property name="dist.file"  value="${version}_helloworld.zip"/>        <target name="prepare">        	<tstamp>        		<format property="DSTAMP" pattern="yyyy.mm.dd" />        		<!-- <format property="TSTAMP" pattern="HH:mm" /> -->        	</tstamp>        	<echo message="Build Start!! ======> ${DSTAMP}-${TSTAMP}" />        </target>        <target name="clean" depends="prepare">        	<delete dir="${dist.dir}"/>            <delete dir="${build.dir}"/>        </target>                <!-- 소스 컴파일 -->        <target name="compile" depends="clean">  			<mkdir dir="${build.dir}"/>  			<javac deprecation="off" srcdir="${src.dir}" destdir="${build.dir}"   					listfiles="no" failonerror="true">  				<classpath>  					<pathelement path="${base.dir}/lib" />  					<fileset dir="${base.dir}/lib">  						<include name="*.jar" />  					</fileset>  				</classpath>  			</javac>        </target>                <!-- 빌드 디렉토리에 컴파일이 끝난 클래스를 jar 파일로 묶음 -->        <target name="mkjar" depends="compile">        	<mkdir dir="${dist.dir}"/>        	<jar destfile="${dist.dir}/${jar.file}"                     basedir="${build.dir}" />        </target>                <!-- 배포할 라이브러리와 소스등을 배포용 디렉토리로 복사하고 배포용 디렉토리를 zip으로 묶음 -->        <!-- jar와 소스, lib 아래의 jar를 배포용 디렉토리에 복사 후 zip으로 묶음 -->        <target name="dist" depends="mkjar">        	<copy todir="${dist.dir}/lib">        		<fileset dir="lib" />        	</copy>        	<copy todir="${dist.dir}/src">        		<fileset dir="src" />        	</copy>        	        	<zip destfile="${DSTAMP}_${TSTAMP}_${dist.file}">        		<fileset dir="${dist.dir}/." />        	</zip>        </target>                <!-- HelloWorld 클래스를 호출하여 실행 -->        <target name="run">        	<java classname="test.HelloAnt">        		<classpath>        			<pathelement location="${dist.dir}/${jar.file}" />        			<pathelement path="${base.dir}/lib" />        			<fileset dir="${base.dir}/lib">        				<include name="*.jar" />        			</fileset>        		</classpath>        	</java>        </target>        </project>

build.xml을 이용한 실행은 콘솔창에서

  ant <targe 이름>

식으로 입력하면 된다.

Eclipse 에서는 Ant 과 통합되어 있으므로 다음처럼 실행할 수 있다.

Eclipse 에서 ant 빌드

사실 Ant 개발자들은 Ant가 make보다 훨씬 선언적으로 빌드를 정의할 수 있다는 점을 장점으로 내세우지만 이건 사실 javac, copy와 같은 태스크를 미리 자바 클래스로 코딩해 놓았기 때문에 그런 것일 뿐 실제적으로는 Make의 메커니즘과 큰 차이가 없다. 그런 반면 build.xml을 선언적으로 작성할 수 있게 하기 위해 build.xml의 문법에 스크립트적인 요소를 최소한으로 줄였고 또 XML 자체가 프로그래밍이 필요한 부분을 기술하기에는 적합하지 않기 때문에 Ant의 파워는 오히려 make보다 낮아진듯 하다.

그리고 실제로 자바 클래스 컴파일에 파일 몇 개 복사하는 정도라면 아주 간단하게 빌드 파일을 작성할 수 있지만, 복잡해지기 시작하면 build.xml은 점점 이해하기 힘든 코드가 됩니다. 그래서 Ant에서는 build.xml에 주석을 충분히 달아놓을 것을 권고하고 있다.

하지만 복잡해서 주석을 많이 필요로 하는 상황은 좋지 않다. 주석은 Sun 에서도 권장하고 있지 않고, 마틴파울러의 리팩토링에서는 나쁜 냄새라고 얘기한다. 되도록 주석없이 쉽게 이해할 수 있도록 빌드 스크립트를 유지 해야 한다.

하지만 프로젝트 규모가 커지고 기능들의 추가/제거가 많아지면 빌드의 구조도 바뀌고 확장 된다. 결국 Ant도 make보다는 조금 사정이 나아졌지만 본질적으로는 make와 동일한 문제를 갖고 있다.

2.2 Maven 2

Maven은 이런 점들을 해결하고 나아가 종합적인 *프로젝트 관리*까지 지원한다. Maven은 현재 버전 2.2까지 나와 있다, Maven 1.x 버전과 2.x 버전간에는 개념을 제외한 파일 호환성이 없으므로, 기존 프로젝트 유지보수 등 특별한 이유가 있지 않는 한 2.x를 사용하길 권장하고 있다. 여기서도 Maven 2를 기준으로 설명한다. (Maven 1 보다 달라진 점은 http://maven.apache.org/maven1.html#changed 에서 보기 바란다.)

Project object model(POM)

Maven 2 프로젝트의 핵심은 POM(project object model)이다. POM 은 프로젝트에 대한 상세한 설명과 버전 정보, SCM, 의존성, 리소스, 팀 멤버, 구조 등을 포함한다. POM은 프로젝트의 홈디렉토리에 XML 파일(pom.xml) 형식으로 저장된다.

pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   http://maven.apache.org/maven-v4_0_0.xsd">   <modelVersion>4.0.0</modelVersion>   <groupId>com.javaworld.hotels</groupId>   <artifactId>HotelDatabase</artifactId>   <packaging>war</packaging>   <version>1.0-SNAPSHOT</version>   <name>Maven 2 Quick Start Archetype</name>   <url>http://maven.apache.org</url>   <dependencies>      <dependency>         <groupId>junit</groupId>         <artifactId>junit</artifactId>         <version>3.8.1</version>         <scope>test</scope>      </dependency>   </dependencies></project>

Maven 2 디렉토리 구조

Maven은 대부분의 것을 표준화 하기 위해 노력하는데, 이것이 장점이다. 다른 Maven 프로젝트에서 일했던 개발자라도 쉽게 구조와 조직에 익숙해 질수 있도록 해준다. 디렉토리 구조나 코딩 규칙 등를 다시 만드느라 시간을 쓸 필요가 없다.

Maven 2는 디렉토리 구조를 꼭 지켜주기를 권고하는 데, 이유는 다음과 같다.

  • POM 파일을 작고 간단하게 해준다.
  • 프로젝트를 이해하기 쉽게 하고, 인수 인계를 편하게 해준다.
  • plug-ins 과 통합을 쉽게 해준다.

Maven 2 의 표준 디렉토리 구조는 다음과 같다. 프로젝트의 홈디렉토리에 pom.xml 이 존재하고 두 개의 하위 디렉토리가 있다. src 에는 모든 source가, target 에는 생성된 모든 것이 들어간다.

Maven 2 표준 디렉토리 구조

src의 하위 폴더는 명확한 목적이 있다.

  • src/main/java: Your Java source code goes here (strangely enough!)
  • src/main/resources: Other resources your application needs
  • src/main/filters: Resource filters, in the form of properties files, which may be used to define variables only known at runtime
  • src/main/config: Configuration files
  • src/main/webapp: The Web application directory for a WAR project
  • src/test/java: Unit tests
  • src/test/resources: Resources to be used for unit tests, but will not be deployed
  • src/test/filters: Resources filters to be used for unit tests, but will not be deployed
  • src/site: Files used to generate the Maven project Website

프로젝트 라이프사이클(Project lifecycles)

프로젝트 라이프사이클은 Maven 2 의 핵심영역이다. 대부분의 개발자는 컴파일(compile), 테스트(test), 배포(deploy)등의 빌드 단계(phase) 개념은 알 것이다. Ant에는 이같은 이름의 target 이 있다. Maven 1 에서는 이와 관련되 plug-in 을 직접 호출한다. 예를 들어 소스를 컴파일하려면 java plug-in 을 사용한다.

 $maven java:compile

Maven 2 에서는, 이 개념이 잘 알려지고 잘 정의된 라이프사이클 단계(phase)의 집합으로 표준화 되었다. Maven 2 사용자는 plug-in 호출없이 라이프사이클 단계(phase)를 호출하면 된다.

 $mvn compile
Maven 2 라이프사이클 단계(phase)

중요한 라이프사이클 단계는 다음과 같다.

  • generate-sources: Generates any extra source code needed for the application, which is generally accomplished using the appropriate plug-ins
  • compile: Compiles the project source code
  • test-compile: Compiles the project unit tests
  • test: Runs the unit tests (typically using JUnit) in the src/test directory
  • package: Packages the compiled code in its distributable format (JAR, WAR, etc.)
  • integration-test: Processes and deploys the package if necessary into an environment where integration tests can be run
  • install: Installs the package into the local repository for use as a dependency in other projects on your local machine
  • deploy: Done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects

다른 단계에 대해서는 여기 를 참조하기 바란다.

Maven 2 의 라이프사이클 단계에 익숙해지면, 어떤 Maven 프로젝트에 가더라도 두렵지 않을 것이다.

라이프사이클의 단계를 호출하면 이전의 단계도 역시 호출한다. 따라서 라이프사이클 단계는 갯수에 제한은 있지만, 이해하기 쉽고, 잘 조직되었으며, Maven 2 프로젝트에 쉽게 적응할 수 있게 도와 준다.

Transitive dependencies

Maven 2 에서 눈에 띄는 부분이 transitive dependency 관리이다. Linux의 urpmi 를 사용해 봤다면 어떤 개념인지 알것이다. Maven 1 에서는 필요한 모든 JAR 파일을 직/간접적으로 선언해 줬어야 한다. Hibernate 을 쓰려면 에 어떤 JARs 들이 필요한지 알고 있는가? Maven 2 에서는 이런 걸 몰라도 된다. 그냥 어떤 라이브러리가 필요한지 Maven 에게 알려주기만 하면 알아서 처리해준다.

프로젝트에 Hibernate 을 사용한다고 생각해 보자. 그냥 다음처럼, pom.xml 의 dependencies 섹션에 새로운 dependency 를 추가하기만 하면 된다.

<dependency>      <groupId>hibernate</groupId>      <artifactId>hibernate</artifactId>      <version>3.0.3</version>      <scope>compile</scope></dependency>

이게 전부다. Hibernate 3.0.3 을 실행하기 위해 다른 JARs(버전에 따라)를 찾아다닐 필요가 없다. Maven 이 알아서 해 준다.

Maven 2 의 dependencies 부분은 Maven 1 과 유사하다. 가장 중요한 차이점은 다음에 설명할 scope 태그이다.

Dependency scopes

실제 엔터프라이즈 애플리케이션에서 보면, dependencies 있는 모든 것이 배포될 필요는 없다. 어떤 JARs 는 유닛 테스트에만 필요할 수 있고, 또 어떤 것은 애플리케이션 서버에서 런타임 시에만 필요할 수 있다. Maven 2 에서는 dependency scoping 이라는 테크닉을 이용해서 특정 JARs 가 정말 필요할 때만 사용될 수 있게 한다. 필요하지 않을 때는 classpath 에서 제거된다.

Maven 은 4가지의 dependency scopes 를 제공한다 :

  • compile: A compile-scope dependency is available in all phases. This is the default value.
  • provided: A provided dependency is used to compile the application, but will not be deployed. You would use this scope when you expect the JDK or application server to provide the JAR. The servlet APIs are a good example.
  • runtime: Runtime-scope dependencies are not needed for compilation, only for execution, such as JDBC (Java Database Connectivity) drivers.
  • test: Test-scope dependencies are needed only to compile and run tests (JUnit, for example).

프로젝트 커뮤니케이션(Project communication)

어느 프로젝트에서나 중요한 부분은 내부 커뮤니케이션이다. 만병통치약은 아니지만, 프로젝트 웹사이트에 정보를 집중화시키면 팀내의 가시성을 향상시킬 수 있다. Maven은 프로젝트에 대한 각종 문서가 집약된 사이트를 생성하도록 해준다. 적은 노력으로 수준높은 프로젝트 웹사이트를 재빠르게 만들어 올릴 수 있다.

보통 Maven 사이트는 다음 정보를 만든다 :

  • General project information such as source repositories, defect tracking, team members, etc.
  • Unit test and test coverage reports
  • Automatic code reviews and with Checkstyle and PMD
  • Configuration and versioning information
  • Dependencies
  • Javadoc
  • Source code in indexed and cross-referenced HTML format
  • Team member list
  • And much more

Maven 으로 관리되는 프로젝트는 여기 http://maven.apache.org/powered.html 에서 볼수 있다.

3. 토론

  • 이 외의 다른 방법으로 관리를 하고 있는가?
  • 팀내에 이런 툴을 도입하는데 따른 문제는 없었는가?
  • 진정 효율적인가?
  • 전사적으로 또는 모든 개발자가 사용하기 위해 어떤 노력을 해야 하는가?

참고문헌

문서에 대하여

최초작성자 : 김중곤
최초작성일 : 2006년 2월 3일
버전 : 0.1

문서이력 :

  • 2006년 2월 8일 김중곤 : version 0.9 : Ant, Mave 추가
  • 2006년 2월 7일 김중곤 : version 0.3 : CVS 내용 및 eclipse 내용 추가
  • 2006년 2월 6일 김중곤 : version 0.4 : 목차 수정, CVS 내용 추가
  • 2006년 2월 3일 김중곤 : version 0.1 : 뼈대 작성

번호 제목 글쓴이 날짜 조회 수
18 Eclipse의 Ajax Toolkit Framework에서 지원되는 툴 (한글) 황제낙엽 2007.03.03 54
17 MyEclipse 유저 가이드 황제낙엽 2007.01.31 8
16 MyEclipse을 활용한 효율적인 개발 방법 2차 황제낙엽 2007.01.30 81
15 Eclipse을 활용한 효율적인 개발 방법 1차 황제낙엽 2007.01.30 22
14 이클립스 다국어 설정 (UTF-8) file 황제낙엽 2006.09.20 280
13 Web Tools Platform 0.7 - Web 개발하기 개요 황제낙엽 2006.10.04 31
12 이클립스와 Struts 환경셋팅 황제낙엽 2005.09.07 12
» Eclipse를 활용한 효율적인 팀 개발 및 배포 전략 (2) 황제낙엽 2007.03.16 91
10 Eclipse를 활용한 효율적인 팀 개발 및 배포 전략 (1) 황제낙엽 2007.03.16 120
9 java.net과 이클립스를 이용한 오픈소스 자바 어플리케이션 개발 (2부. 이클립스와 CVS를 이용한 팀 작업) file 황제낙엽 2007.02.28 152
8 java.net과 이클립스를 이용한 오픈소스 자바 어플리케이션 개발 (1부. 이클립스에서 새로운 프로젝트 생성하기) file 황제낙엽 2007.02.28 254
7 MyEclipse에서 XML, JSP 페이지의 실시간 Validation 옵션 끄기 황제낙엽 2007.01.26 156
6 Eclipse Loader 황제낙엽 2005.10.28 19
5 (KeepResident Eclipse plugin) 하드스와핑이 일어나지 않게 황제낙엽 2006.02.14 22
4 Velocity 용 플러그인 황제낙엽 2005.12.05 11
3 Log4J 용 이클립스 플러그인 (log4e) 황제낙엽 2005.11.30 29
2 이클립스3.1용 문서 에디터 플러그인 (JSP, XML, HTML) 황제낙엽 2005.11.30 35
1 Eclipse 관련 FAQ 황제낙엽 2005.10.13 188