Step by Step Ant

IDE & Build/Ant 2012. 11. 6. 15:59


글을 적기 전 Ant카테고리를 만든 이유를 잠시 적을까 한다. Ant를 사용한 것은 지난 09년 INLIBS라는 프로젝트를 시작하면서, 빌드 자동화 및 테스트를 위해 처음 Ant를 사용하고 티스토리 블로그에 포스팅했었지만, 블로그를 이전하면서 언젠가 Ant카테고리의 데이터를 지워버렸고, 다시 Ant를 사용하려니 몇 가지 어려운 점이 있어, 다시는 잊어버리지 않기 위해 이렇게 다시 카테고리를 생성하고, Ant에 대해 Step by Step 형식으로 작성하리라 마음을 먹었다.

아무튼 Ant란 무엇일까? Ant에 대한 개인적인 생각은 매우 훌륭한 빌드 도구라는 것이다. 아마 학생이거나, 빌드라는 개념이 정확하지 않은 사람은 우선 빌드가 무엇인지 알아야 한다. 빌드란 간단하게 우리의 프로세스를 살펴보면 알 수 있다. 우리는 소스 코드 파일을 작성하면, 컴파일 하고, 유닛 테스트를 하거나, 패키지화, 배치 등 다양한 작업을 손 수(수작업) 하게 된다. 하지만 공장도 자동화되는 시점에 우리 개발자들이라고 “난 손으로 하는게 좋아!”라며 수작업을 즐기고 싶어하는 개발자는 아마 없을 것 이다. 이러한 개발자를 위해 Ant 빌더가 존재하는다. 간단한 XML로 Ant 문서를 제작해 컴파일, 업로드, 파일 압축 등의 다양한 작업들을 일괄적으로 처리하는 역할을 담당 한다.

실제로, Java Development With Ant (Erik Hatcher)라는 책에 보면, 왜 Ant가 뛰어난 빌드 도구 인지 설명 하고 있다. (아, 원서라서 번역에 상당한 에러가 있을 수 있다.) 먼저 Ant는 Java 컴파일러나 Jar파일을 만드는 것과 같은 로직을 별도의 JVM에서 구동하는 것이 아니라, Ant자체의 JVM상에서 실행하므로, 매우 빠르다. 또한, Java를 사용하여 확장이 가능하고, FTP, 텔넷, SQL 등의 명령어를 배치 자동화에 사용할 수 있다라는 것을 큰 장점으로 설명하고 있다.

사실 이보다는 Ant의 핵심 컨셉이 중요한데, 우선 Ant는 매우 간경하고, 이해하기 쉬우며, 확장성이 뛰어나다. 이런 이야기는 아직 크게 이해하기 힘든 부분일 수도 있지만, 아마 이 포스팅이 10개 정도 작성된 후 부터는 Ant가 매우 편리하다라는 생각을 누구나 하게 될 것이다.

아무튼 이렇게 긴 글들은(웅장한 설명들…) 위키피디아에 가보면 수많은 글들이 아주 멋지게 작성되어 있으므로, 이쯤에서 생략하기로 하고 실제 하나의 프로젝트를 만들고 Ant를 통해 빌드하는 작업을 첫 번째 핵심 주제로 다루어보려 한다. 우선 몇 가지 확인해야 할 것이 있는데, Ant가 정상적으로 동작하는지 알아야봐야 한다는 것이다. 당연한 소리일 수 도 있지만, 실제로 소스파일을 만들어 둔 후 Ant가 실행되지 않아서, 빌드를 하지 못했던 기억이 있기 때문에 가장 먼저 다루는 것이니 양해해주기 바란다.

우선 터미널을 실행시키고, ant -version이라는 명령어를 입력해본다. 정상적으로 구동된다면 Apache Ant version 1.8.1 compiled on September 21 2010 (뭐 버전은 다를 수도 있다만)와 같은 문구가 출력되고, 설치가 되어 있지 않다면, ‘ant’는 내부 또는 외부 어쩌고 저쩌고라는 문구가 출력된다.

정상적으로 출력된다고 가정하에 본격적으로 Ant를 사용해볼 수 있는데, 추후에 본인 스스로도 다시 이 포스팅을 읽어야 할 것이기 때문에 최대한 간단하고 쉬운 예로 포스팅을 작성하려 한다. 아래와 같은 Java 소스파일을 하나 만들어 보자.(파일의 내용은 이 글을 읽는 사용자들의 코드여도 관계 없다.)

1
2
3
4
5
6
7
public class Main {
    public static void main(String [] ar) {
        for(int i =0; i < 5; i++){
            System.out.println("hello, Kim eunseok");
        }
    }
}

위 코드를 해석할 수 없다면, 지금 Ant를 볼 것이 아니라, Java를 봐야한다.(물론, 농담이다.) 아무튼 위와 같은 코드를 작성했다면 이제 컴파일을 담당하는 간단한 Ant문서를 작성해보도록 하자. 아! 이 예는 그렇게 권하고 싶은 예는 아니지만, 아무튼 Step by Step이라는 주제이므로, 아마 처음 Ant를 사용한 개발자라면 꽤나 편하게 사용할 수 있는 예이기도 하니 한번 작성해보도록 하겠다. ant는 xml로 작성된다고 위에서 설명했다.

1
2
3
4
5
6
7
<?xml version="1.0"?>
<PROJECT default="compile" name="build">
    <TARGET name="compile">
        <JAVAC srcdir="." />
        <ECHO>Kimeunseok:Compile Test!</ECHO>
    </TARGET>
</PROJECT>
1
  

그리고, 작성한 xml파일을 build.xml이라고 저장하고, 위에서 작성한 Java 소스파일이 있는 디렉토리에 저장한 후 다시 터미널을 실행시켜서 위 디렉토리(Main.Java와 Build.xml,파일이 있는 디렉토리)로 이동하여, ant 라는 명령어를 실행하면 컴파일이 성공적으로 진행될 것이다. 그런데 여기서 혹시 아래와 같은 문제가 발생하는 경우도 있다.

$ ant
Buildfile: build.xml

compile:
    [javac] build.xml:4: warning: 'includeantruntime' was not set,
            defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 1 source file
     [echo] Kimeunseok:Compile Test!

BUILD SUCCESSFUL
Total time: 0 seconds

이 경우 build.xml 중 javac 엘리먼트에 includeantruntime=”false”를 추가해주면 되는데, 수정한 파일은 아래와 같은 코드로 작성되어 있다.

 

1
2
3
4
5
6
7
<?xml version="1.0"?>
<PROJECT default="compile" name="build">
    <TARGET name="compile">
        <JAVAC srcdir="." includeantruntime="false" />
        <ECHO>Kimeunseok:Compile Test!</ECHO>
    </TARGET>
</PROJECT>

 

 

그 후 java Main을 실행해보면 정상적으로 컴파일 되었다는 것을 확인 할 수 있다. 비록 간단한 예였지만, 실제로 컴파일하고 성공했다는 메세지까지 출력해주고 있다. 물론 이것이 ant의 전부는 절대 아니다. 이제 막 커튼(요즘 부쩍 시적 표현이 늘었다…갠적인 생각.)을 열고 햇빛을 받을 준비를 한 것 뿐이고, 다음 포스팅 부터 본격적인 구조화, 자동화 등 Ant의 다양한 기능을 소개하고, 같이 해보는 시간을 가지도록 하겠다

Buildfile: build.xml

compile:
     [echo] Kimeunseok:Compile Test!

BUILD SUCCESSFUL
Total time: 0 seconds

위와 같이 추가 후 다시 실행을 해보면 아래와 같이 정상적인 컴파일과 함께 컴파일이 성공했다는 echo 메세지를 출력해준다.

Written by Eunseok

2월 16th, 2012 at 12:38 pm



출처 - http://kimeunseok.com/archives/188






Step by Step : Ant Structured.

이전 포스팅을 실행 한 후 해당 디렉토리를 열어보면, 소스 파일, 클래스 파일, 빌드 파일 모두 같은 디렉토리에 들어있다보니, 파일 관리하기도 불편하다고 느끼게 될 것이고, 이전에 제작한 빌드 파일이 상당히 불편하다는 느낌을 받을 수 있다. 아마 소스 파일이 10개만 넘어가도 이제는 관리하기 힘들다는 마음이 들고 그 순간 “아, Ant를 사용하지 않는게 좋겠다”라는 생각이 들 수도 있다. 이는 이전 포스팅만을 사용했을 때 발생하는 고민이고, 이제 빌드를 구조화하여 보다 편리한 Ant빌드를 만드는 방법을 포스팅하려 한다.

우선 Ant를 구조화 하는 이유가 궁금할텐데, 가장 큰 이유는 어디서나 “위험요소를 최소화하고 깔끔한 소스 파일과 생성된 파일을 관리하기 위함”이라고 설명하거 있다. 이를 클린 빌드라고 하는데, 클린 빌드는 이전에 생성된 파일을 지우고 다시 빌드하는 것을 의미한다. 그러기 위해서는 먼저 디렉토리 자체 레이아웃을 조금 설정해야하는데 큰 규칙은 없지만, 관습상 총 4개의 디렉토리를 생성하고, 해당 구조는 아래와 같이 배치된다.

위에서 src는 소스 파일들을 모아둔 디렉토리고, build의 경우 빌드된 클래스 파일들, dist는 배포본을 저장하는 공간이라고 가정하도록 하겠다. Ant를 사용하는 거의 모든 사람들(갠적 생각)은 위와 같이 디렉토리 레이아웃이 아닌가 한다. 우선 이전 포스팅에서 만들었던 Main.java파일을 src폴더로 이동하도록 한다. 다음으로 build 디렉토리 레이아웃 설정 부분인데 본인의 경우 class를 따로 모아두기 위해 classes라는 하위 디렉토리를 생성하기로 했다. 마지막으로 dist 디렉토리에는 배포파일(예를 들면 jar과 같은)을 저장할 것이니 별도의 레이아웃 설정 없이 디렉토리 그대로를 사용하기로 한다.

이렇게 모든 디렉토리 레이아웃을 설정했다면, 이제 빌드파일을 생성해야 한다.이전의 경우 해당 디렉토리의 모든 java파일을 컴파일하므로 지금의 구조화된 빌드를 하기 위해서는 새로 빌드를 작성하는 것은 어쩌면 당연한 일이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0"?>
<PROJECT default="archive" name="build">
    <TARGET name="init">
        <MKDIR />
        <MKDIR />
    </TARGET>
    <TARGET name="compile" depends="init">
        <JAVAC srcdir="src" includeantruntime="false" destdir="build/classes" />
    </TARGET>
    <TARGET name="archive" depends="compile">
        <JAR basedir="build/classes" destfile="dist/test.jar" />
    </TARGET>
    <TARGET name="clean" depends="init">
        <DELETE />
    </TARGET>
</PROJECT>


이번에는 위 xml의 설명이 필요할지 모르겠다. 우선 코드 자체는 어렵지 않다. mkdir은 디렉토리를 생성하는 것이고, destdir의 경우 결과물을 저장할 디렉토리를 설정한다. 그리고 destfile은 배포본(jar)파일의 디렉토리와 이름을 지정하고, basedir은 배포하기 위한 클래스 파일들이 있는 위치며, delete를 통해 디렉토리를 삭제한다. 이 부분은 사실 모든 것이 영단어로 구성되어 있어 어렵지 않게 이해할 수 있지만, 여기서 가장 중요한 내용은 타겟 간의 종속성이다.

타겟 간의 종속성은 Ant가 타겟을 실행 할 때 배포본을 생성하기까지 올바른 순서로 처리할 수 있도록 설정하는 부분이라고 할 수 있다. 즉, 위의 종속구조를 보자면 아래와 같이 구성할 수 있다.

결국 위 구조를 Ant가 실행하기 위해서는 compile하기 앞서 init를 실행해야 하고, archive를 하기 위해서는 compile을 거쳐야 한다는 의미가 된다. 또한 이렇게 구조화 된 빌드의 경우 직접 타겟을 선택하여 Ant를 실행할 수 도 있는데 앞서 말한 것 처럼 현재 구조는 종속성을 가지고 있으므로, ant compile을 한다고 가정했을 때 반드시 init을 실행한다. 이를 확인하기 위해서 실제로 $ant compile을 실행해보면 아래와 같은 결과를 출력한다.

Buildfile: build.xml

init:

compile:

BUILD SUCCESSFUL
Total time: 0 seconds

즉, 위를 통해 종속관계를 적용할 경우 어떻게 ant에서 처리하는지 알수있다. 또 추가적으로 -verbose 라는 옵션을 추가하면, Ant가 어떻게 동작하는지 상세하게 확인 할 수 있다. 만약 다수의 타겟을 실행하고 싶다면,(어쩌면 벌써 파악했는지도 모르지만…)ant compile clean과 같은 방식으로 사용할 수 있다. 그 결과는 아래와 같다.

Buildfile: build.xml

init:

compile:

init:

clean:
   [delete] Deleting directory /dist

BUILD SUCCESSFUL
Total time: 0 seconds


이제 점점 Ant 빌드가 재미있어지고, 편리해지기 시작했지만, 아직 시작에 불과하다. 다음 포스팅에는 Ant에서 직접 파일을 실행하는 방법을 포스팅할까 하는데, 현재 공부하고 있는 내용이 꽤나…많아서…언제쯤 포스팅할지 모르겠지만, 아무튼 곧! 빠르게! Ant 빌드에 대한 내용을 업데이트 할 계획이니 많은 관심을 바란다.

add. 시간이 있어, 타겟으로 직접 프로그램을 실행하는 Ant빌드 파일을 만들어볼까합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0"?>
<PROJECT default="archive" name="build">
    <TARGET name="init">
        <MKDIR />
        <MKDIR />
    </TARGET>
    <TARGET name="compile" depends="init">
        <JAVAC srcdir="src" includeantruntime="false" destdir="build/classes" />
    </TARGET>
    <TARGET name="archive" depends="compile">
        <JAR basedir="build/classes" destfile="dist/test.jar" />
    </TARGET>
    <TARGET name="clean" depends="init">
        <DELETE />
    </TARGET>
    <TARGET name="execute" depends="compile">
        <JAVA classpath="build/classes" classname="Main" />
    </TARGET>
</PROJECT>


execute는 build/classes를 classpath로 하여, Main 클래스를 실행한다. 이 빌드를 통해 $ant execute를 실행하게 되면, compile에 종속적이므로, 컴파일이 실행되고, 또 컴파일은 init에 종속적이므로 init 역시 실행된다. 정상적으로 실행이 되었다면, 콘솔창에 아래와 같은 결과가 출력된다.

Buildfile: build.xml

init:
    [mkdir] Created dir: dist

compile:

execute:
     [java] hello, Kim eunseok
     [java] hello, Kim eunseok
     [java] hello, Kim eunseok
     [java] hello, Kim eunseok
     [java] hello, Kim eunseok

BUILD SUCCESSFUL
Total time: 0 seconds

Written by Eunseok

2월 16th, 2012 at 12:41 pm



출처 - http://kimeunseok.com/archives/190





'IDE & Build > Ant' 카테고리의 다른 글

Ant 소개  (0) 2012.11.06
Apache Ant  (0) 2012.03.03
Posted by linuxism
,

Ant 소개

IDE & Build/Ant 2012. 11. 6. 14:32


출처 - www.infopub.co.kr/info/ebook/pdf/8054-514.pdf

Ant 소개.pdf






Ant 는 JAVA 기반 빌드 툴로서 C나 C++ 에서 사용되는 make, nmake와 유사한 유틸리티입니다.

좀 더 JAVA에 적합하게 만들어져 있고 자동화에 유리합니다.

주요 기느으로는 자바 소스 컴파일, 파일이나 폴더의 이동 및 복사, 삭제, jar, war, ear, zip 파일의 생성, DB 스크립트 실행, 외부 프로그램 실행 등 언급한 것 외에도 여러가지 작업을 수행할 수 있습니다.

 

Ant 를 다운로드 받을 수 있는 URL 은 http://ant.apache.org/bindownload.cgi 이다. 하지만 Eclipse의 경우에는 이미 Ant가 포함되어 있으므로 따로 설치할 필요는 없습니다.

 

속성(attribute)

설명(Description)

필수(Required)

name

Project의 이름.

아니오.

default

Ant를 수행할 때 Targer을 지정하지 않을 경우 default로 수행할 Target

네.

basedir

Ant가 수행 될 기본 디렉토리

아니오.

Project의 정의에 따라 build.xml 파일의 유효한 xml 의 첫 라인을 살펴보면 다음과 같습니다.

 

<project name = "Crown" default = "build">

 

build란 target을 default 로 지정한 Crown 이라는 프로젝트입니다. target이란 수행할 작업의 set을 위미하는데, 모든 project는 하나 이상의 target을 가집니다.

 

타겟(Targets)

타겟은 다음과 같은 속성을 가지고 있습니다:

속성(attribute)

설명(Description)

필수(Required)

name

타겟의 이름.

depends

이 타겟이 의존하는, 타겟의 이름의 콤마로 단락지어진 리스트

아니오

if

이 타겟을 실행하기 위해 설정되어야만 하는 프로퍼티의 이름.

아니오

unless

이 타겟을 실행하기 위해서 설정되어선 안 되는 프로퍼티의 이름.

아니오

description

이 타겟의 기능에 대한 간단한 설명.

아니오

타겟(target)은, 다른 여러 타겟에 의존할 수 있습니다.

그러나, 주의해야 할 것은, Ant의 depends 속성은 어느 타겟이 실행되어야 할 것인가의 순서를 지정하기 때문에 의존하고 있는 다른 타겟이 실행되는데에는 큰 영향을 주지 않습니다. (참고 주소 : http://flashcafe.org/java_study/6901/page/6)

 

Ant는 depends 속성의 타겟을, 보이는 순서(왼쪽에서 오른쪽으로) 실행하려고 합니다. 먼저 출현하는 타겟을 의존하고 있는 경우에는, 그것을 먼저 실행됩니다.

<target name="A"/>

<target name="B" depends="A"/><target name="C" depends="B"/><target name="D" depends="C,B,A"/>

예를 들어서 위의 예제처럼 타겟 D를 실행하고 싶다고 가정해 봅시다. 이 depends 속성(의존 속성)으로부터, 최초로 타겟 C를, 다음에 B를, 그리고 A를 실행해야 한다고 생각한다면 잘못된 생각입니다.

C는 B에 의존해, B는 A에 의존하고 있으므로, 최초로 A, 다음에 B, 다음에 C, 그리고 마지막에 D가 실행됩니다.

타겟은 어느 프로퍼티가 설정되어 있는 (또는 되어 있지 않은) 경우에, 그것을 실행하거나 실행하지 못하게 막을 수도 있습니다.

 

<target name="build-module-A" if="module-A-present"/>

<target name="build-own-fake-module-A" unless="module-A-present"/>

 

만약 module-A-present 프로퍼티가 설정되어 있다면, 타겟이 실행됩니다. 두번째의 예에서는, 만약 module-A-present 프로퍼티가 설정되어 있는 경우에는, 타겟은 실행되지 않습니다. (자세한 것은 위의 속성을 참조하세요.)

만약 if 와 unless 속성이 존재하지 않는다면, 타겟은 항상 실행될 겁니다.

추가적인 description 속성은 타겟에 붙는 간단한 설명을 제공하기 위해 사용할 수가 있습니다.

프로퍼티(Property)

속성(attribute)

설명(Description)

필수(Required)

name

프로퍼티의 이름.

value

프로퍼티의 value

name attribute가 사용될 경우 이 중 한 가지

location

주어진 파일의 파일이름으로 프로퍼티 설정

refid

다른 곳에 정의된 Object를 refid로 참조

resource

프로퍼티 파일의 리소스 명

name attribute가 사용되지 않을 경우 이 중 한가지

 

file

프로퍼티 파일의 파일이름

url

프로퍼티 파일을 읽는 url

environment

환경변수에 붙는 prefix

classpath

리소스를 찾을 때 사용될 클래스패스

아니요

classpathref

다른 곳에 Path로 정의된 classpath의 reference

아니요

prefix

로드 된 파일이나 리소스에 붙는 prefix

아니요

 

프로젝트는 프로퍼티의 집합을 가질 수가 있습니다. 이것들은 property 태스크에 의해 빌드파일 중에서 설정될 수도 있고, Ant 의 밖에서 설정될 수도 있습니다. 프로퍼티는, 이름(name)과 값(value)을 가지고 있습니다. 이름은 대·소문자를 구별합니다. 

프로퍼티는 태스크의 속성의 값으로 해서 사용할 수가 있습니다. 이것은 속성의 값 중에서 "${" 와 "}" 의 사이에 프로퍼티명을 쓰는 것으로 사용가능합니다. 예를 들면, 값 "build" 를 가지는 "builddir" 라고 하는 프로퍼티가 있다면, 속성 내에서 "${builddir}/classes" 와 같이 사용할 수가 있습니다. 이것은, 실행시에, "build/classes" 로서 처리됩니다.

 



실 전

참조 주소 : http://decoder.tistory.com/8

 앞에서 설명했지만 Ant는 아파치 프로젝트의 하위 프로젝트로서 자바 기반의 빌드 도구로, Ant를 사용하였을 때의 장점은 다음과 같습니다.

- Ant 빌드 파일은 이식 가능함 : 플랫폼 독립적

- Ant는 파일 간 의존성 정보를 계속 추적함 

- Ant에는 자바 소스 파일을 컴파일 하는 기능 이외에도 갖가지 일을 할 수 있는 태스크(task)가 많이 들어있음. 


Ant 빌드 파일을 작성하기 위해 위에서 설명한 대로 Ant를 다운로드하여 적당한 곳에 압축을 풉니다.

환경변수의 classpath와 path에 각각 %ANT_HOME%\lib와 %ANT_HOME%\bin을 추가해 준다. 이클립스와 같은 IDE를 사용하면 Ant가 이미 내장되어 있습니다. Ant를 이용하여 빌드 파일은 보통 build.xml 로 줍니다. 인터넷으로 build.xml 이라고 검색하면 괜찮은 예제들을 많이 볼 수 있습니다. 하지만, 집적 프로젝트를 뛰면, 그 프로젝트에 맡는 build.xml을 사용해야겠지요.


1. 프로젝트 정의

가장 먼저 할 일은 프로젝트를 정의하는 것입니다.

<?xml version="1.0"?>

<project name="Crown" default="compile" basedir="."> 

Ant 빌드 파일은 하나의 프로젝트를 정의합니다.

<project>요소의 이름은 Crown 으로 지정하였고, default 속성 값은 compile로 하였는데, 이는 명령행에서 매개변수 없이 ant를 입력했을 때, 기본적으로 컴파일을 수행함을 뜻합니다(나중에 타겟으로 compile을 만들어 줍니다). basedir은 . 으로 했는데, 이는 이 빌드 파일에서 사용되는 다른 모든 경로는 build.xml 파일이 들어있는 디렉터리를 기준으로 한 상대경로라는 것을 의미합니다.


2. 각종 property 정의

다음으로는 디렉터리 구조를 정의하는 프로퍼티(property)를 정의하여 Ant에 프로젝트 디렉터리 구조를 알려줍니다.

       <property name="build.dir" location="build"/>

       <property name="build.prod.dir" location="${build.dir}/prod"/>

       <property name="src.dir" location="src"/>

       <property name="lib.dir" location="lib"/>

이렇게 작성한 것의 의미를 살펴보면 <property> 요소의 location 속성값(baesdir 속성값을 기준으로 한 상대 경로)과 name 속성값을 연결한 것인데, ${build.dir}의 경우 프로퍼티의 이름을 변수처럼 사용하여 다른 디렉터리를 참조하여 사용할 수 있습니다. 이건 많이 해보면서 숙달되어가면 익숙해집니다. 그냥 별명을 준다고 생각하시면 될 듯 싶네요.


3. 자바 클래스 경로 정의

       <path id="project.classpath">

             <pathelement location="${build.prod.dir}" />

             <fileset dir="${lib.dir}">

                    <include name="*.jar" />

             </fileset>

       </path>

path 요소는 project.classpath라는 경로를 생성한다. 이 경로는 나중에 컴파일시에 사용됩니다. pathelement 요소에서는 빌드 디렉터리를 클래스 경로에 추가해서 자바 컴파일러가 모든 클래스 파일을 찾을 수 있게 합니다. 그리고 fileset 요소에서는 .jar 파일들을 클래스 경로에 추가하여 우리가 작성한 클래스 파일에서 사용되는 라이브러리 또한 쉽게 찾을 수 있도록 합니다. 위에서 설명한 것처럼 대부분 여기에서도 ${}를 이용하여 디렉터리 경로에 참조를 이용합니다. 이렇게 하면 빌드 실행시마다 컴퓨터에 CLASSPATH 환경변수를 설정할 필요가 없으며, 필요할 때마다 fileset 요소만 수정하면 됩니다만, 거의 대부분 한번 설정하고나서는 이 build.xml을 수정하지 않습니다. 이는 완전한(Complete) 빌드를 유지하기 쉽게 하기 때문입니다.


4. 타겟 정의

       <target name="prepare">

             <mkdir dir="${build.prod.dir}" />

       </target>

      

       <target name="compile" depends="prepare">

             <javac srcdir="${src.dir}" destdir="${build.prod.dir}">

                    <classpath refid="project.classpath" />

             </javac>

       </target>

타겟(target)은 빌드 단계로서 지정한 순서에 따라 실행될 일련의 '태스크(task)'들을 정의하는 빌드 단계입니다. prepare 타겟은 빌드 출력 디렉터리를 만들기 위하여 <mkdir> 태스크를 사용합니다. compile 타겟은 소스 파일을 컴파일 하고 prepare 타겟에서 생성된 디렉터리에 결과 클래스 파일들을 저장합니다. 타겟의 실행 순서는 중요하므로 depends 속성을 통해 타겟 간의 의존성을 만들어 순서를 지정한다. 의존성은 여러 개를 지정할 수 있으며, 타겟 이름을 콤마(,)로 구분하여 나열합니다. prepare 실행이 완료되면 javac 태스크를 실행하여 자바 컴파일러를 호출합니다. 컴파일러는 srcdir 속성의 값에 명시된 소스 폴더내의 자바 소스 파일들을 모두 컴파일 하고, 그에 상응하는 클래스 파일들을 destdir이 가리키는 디렉터리에 생성합니다. classpath 요소는 project.classpath가 가리키는 클래스 패스를 사용하라고 알려주는 역할을 합니다. 위에서 작성한 전체 build.xml 파일은 다음과 같습니다.

<?xml version="1.0"?>

<project name="spring_example" default="compile" basedir=".">

       <property name="build.dir"             location="build"/>

       <property name="build.prod.dir"         location="${build.dir}/prod"/>

       <property name="src.dir"                location="src"/>

       <property name="lib.dir"                location="lib"/>

      

       <path id="project.classpath">

             <pathelement location="${build.prod.dir}" />

             <fileset dir="${lib.dir}">

                    <include name="*.jar" />

             </fileset>

       </path>

      

       <target name="prepare">

             <mkdir dir="${build.prod.dir}" />

       </target>

      

       <target name="compile" depends="prepare">

             <javac srcdir="${src.dir}" destdir="${build.prod.dir}">

                    <classpath refid="project.classpath" />

             </javac>

       </target>

</project>

실제로 프로젝트에 참여하게 되면, 이보다 더욱 복잡하고 난해하게 짜여져있습니다만,
어떤식인지 이해할필요도없이 그냥 사용하면 되니, 그다지 문제될것 없습니다.
집적짜야한다면, 문제가 되겠지만서도 ^^;


출처 - http://c36wn.egloos.com/4235824












'IDE & Build > Ant' 카테고리의 다른 글

Step by Step Ant  (0) 2012.11.06
Apache Ant  (0) 2012.03.03
Posted by linuxism
,


Hazelcast
Hazelcast logo.png
Developer(s)Hazelcast Team
Stable release2.4 / October 17, 2012; 13 days ago
Development statusActive
Written inJava
Operating systemCross-platform
TypeIn memory data grid
LicenseApache License 2.0
Websitehttp://www.hazelcast.com/


Hazelcast is an open source in memory data grid for Java.

Hazelcast architecture is peer-to-peer. It supports dynamic discovery using multicast or TCP/IP. After discovery, node communication is only TCP/IP using Java NIO.

Contents

  [hide

[edit]Hazelcast Features

  • Distributed Java data structures (Queue, Set, List, Map, Lock, Topic)
  • Distributed Executor Service
  • Distributed Multimap
  • Support for transactions
  • J2EE container integration via JCA
  • Hibernate 2nd level cache
  • Index and Query support
  • Dynamic clustering, scaling and partitioning
  • WAN (Wide Area Network) Replication
  • Decentralized. Each node in the cluster has the same role.
  • Data is distributed across the cluster (so each node contains different data).

[edit]Getting Started

Following is the sample usage of distributed hash map using Hazelcast.

import java.util.Map;
import java.util.Collection;
import com.hazelcast.core.Hazelcast;
 
Map<String, Person> mapPeople = Hazelcast.getMap("people");
mapPeople.put("1", new Person("Jack"));
mapPeople.put("2", new Person("Avi"));
 
Collection<Person> colPeople = mapPeople.values();
for (Person person : colPeople) {
    // print person
}

[edit]See also

[edit]External links







정의
Hazelcast 문서의 첫 줄에는 이를 다음과 같이 설명하고 있다.

Hazelcast is a clustering and highly scalable data distribution platform for Java.

조금 풀어서 써보면...
(1) 일단은 자바에서 사용할 수 있는 것이고
(2) 프로그램들을 그룹화(clustering)해서 걔들 간에 데이터를 가변적으로 분산시켜주기 위한 것이다.
저자의 의도대로 이해했는지 모르겠다.


조금 더 자세히
 


그림으로 표현하면 위와 같다. 
(1) 네트워크 상에 물려있는 2개의 프로그램이 있고, 이 프로그램은 hazelcast 기반으로 작성되었다. 
(2) hazelcast상에서 정의된 어떤 자료구조에 파란 옷을 입은 사람이 데이터를 쓰면 
(3) 이를 파란색 옷을 입은 사람도 꺼내갈 수 있고, 녹색옷을 입은 사람도 꺼내갈 수 있다.
즉, 물리적으로 떨어져 있는 두 프로그램이 하나의 자료구조를 공유할 수 있다.

이는 파란옷을 입은 사람이 데이터를 자료구조에 쓰면 hazelcast가 이 자료를 녹색옷 입은 사람에게도 전달하기 때문이고, 데이터 전달에는 multicast, tcp, aws가 사용될수 있다. 뒷단에서 데이터는 왔다 갔다 하겠지만 이 얼마나 아름다운가!! 

라이브러리는 apache license 2.0을 따르고 있으며 elastic memory, security 기능이 빠져있는 community edition은 무료로 다운로드 하여 사용할 수 있고, 이를 포함한 enterprise edition은 돈 주고 사야한다. (commercial license)


샘플 작성하기
hazelcast 기반으로 고리타분한 생산자-소비자를 만들어보자!! 생산자는 hazelcast에서 큐를 가져와 데이터를 생산하고, 소비자는 해당 큐에서 데이터를 꺼내오는 아주 아주 고전적인 실험이다. 프로그램 구조는 다음과 같다.


- conf/hazelcast.xml : hazelcast 환경설정 파일로, 생산자와 소비자가 공유할 자료구조와 통신방법에 대해 정의
- conf/log4j.properties : 로그를 찍기위한 환경설정 파일
- lib/hazelcast_1.9.4.4 : hazelcast 라이브러리 파일
- lib/log4j_1.2.15 : 로그 출력을 위한 라이브러리 파일
- mytest/listener : hazelcast가 생성하는 인스턴스에 대한 리스너로 이 실험에서는 로그를 찍어보기 위한 용도
- mytest/worker/Consumer.java : 생산자
- mytest/worker/Producer.java : 소비자
- mytest/worker/Worker.java : 생산자와 소비자의 슈퍼 클래스
- mytest/Main.java : 프로그램 시작 지점


소스
hazelcast.xml
- group : 이 프로그램이 속하는 그룹(clustering)에 대한 정보

- network : 통신 방법에 대한 정의
- queue : 생산자와 소비자가 사용할 큐에 대한 정보
- map : 큐에 대한 부가 정보


Worker.java (1) Thread를 상속받고 있으며
(2) Hazelcast에서 큐(BlockingQueue)를 가져와서 사용한다.


Producer.java (1) 3초 간격으로 데이터를 생산


Consumer.java (1) 큐에서 데이터를 꺼내서 출력


Main.java

더보기


실험결과
Producer 실행화면 (주요부분 발췌 및 설명추가)

Consumer 실행화면 (주요부분 발췌 및 설명추가) - 스레드로 작성되었기 때문에 프로그램 구동시점에 따라 로그 내용이 달라질 수 있음 


출처 - http://case35.tistory.com/226








'Computer Science > Cache' 카테고리의 다른 글

EHCache  (0) 2013.02.11
Memcached 설치 및 사용 방법  (0) 2012.11.06
Memcached의 확장성 개선  (0) 2012.11.06
memcached를 적용하여 사이트 성능 향상  (0) 2012.11.06
Memcached 구현 소개  (0) 2012.11.06
Posted by linuxism
,