'개발'에 해당되는 글 29건

  1. 2009/10/21 메이븐(Maven) 시작하기 (3/3) (4)
  2. 2009/10/09 메이븐(Maven) 시작하기 (2/3) (4)
  3. 2009/10/09 메이븐(Maven) 시작하기 (1/3)
  4. 2009/10/07 기본 윈도우 크롬을 사용하지 않는(chromeless) 에어(AIR) 어플리케이션 만들기
  5. 2009/09/12 FlexUnit - Flex(플렉스) 단위 테스트 프레임워크
  6. 2008/09/30 톰캣(Tomcat) 5.x GET 방식 한글 인코딩에 문제가 있다니..
  7. 2008/06/08 앤트(Ant)에서 톰캣에 웹 애플리케이션을 디플로이하는 방법..
  8. 2008/06/08 앤트(Ant)에서 톰캣을 실행/중지해 보아요. (4)
  9. 2008/06/08 앤트(Ant)의 프로퍼티 파일(.properties)의 제한에 대해서..
  10. 2008/06/04 앤트(Ant)에서 사용자별로 다른 프로퍼티 파일을 읽어들이도록 해보아요.
2009/10/21 23:04

메이븐(Maven) 시작하기 (3/3)

이클립스에서 메이븐 프로젝트를 해보자.

개발을 하는데 이클립스와 같은 IDE를 사용할 수 없다면 생산성이 급격히 낮아질 것이다. 메이븐 프로젝트 역시 마찬가지다. 메이븐이 편리한 도구라서 쓰고 싶은데 IDE를 지원하지 않는다면 무용지물일 것이다. 하지만 메이븐은 좋은 도구답게 이클립스를 비롯한 다양한 IDE를 지원한다. 여기에서도 플러그인이 사용되는데, 조금 재밌는 것은 메이븐에도 이클립스 플러그인이 있고, 이클립스에도 메이븐 플러그인이 있다는 것이다. 두 가지의 차이는 프로젝트를 어디에서 시작을 하는 것이냐는 것이다. 메이븐 이클립스 플러그인은 메이븐에서 먼저 시작하고, 이클립스 메이븐 플러그인은 이클립스에서 먼저 시작한다. 두 가지 모두 사용 가능하지만 결국에는 이클립스의 메이븐 플러그인을 많이 사용하게 될 것이다. 명령어를 치는 것보다 IDE에서 클릭 몇번으로 프로젝트를 생성하고 관리하는 것이 편리하니까..

먼저 메이븐 이클립스 플러그인을 사용하여 보자.

1. 프로젝트를 생성한다.

지금은 이전에 만들어 놓았던 프로젝트를 그냥 쓰기로 하자. ^-^

2. mvn eclipse:eclipse

프로젝트 폴더에서 eclipse 플러그인의 eclipse 골을 실행하는 명령어를 실행한다.

 mvn eclipse:eclipse

'BUILD SUCCESSFUL' 이 보이면서 완료되면 다음과 같은 이클립스 프로젝트 관련 파일들이 생긴다.

  • .project: 프로젝트 설정 파일
  • .classpath: 클래스패스 설정 파일
  • .settings: 기타 설정 파일들을 포함하는 폴더

3. Import Project

이클립스에서 Import Project.. 를 통해 프로젝트를 워크스페이스(Workspace) 내부로 가져온다.

'Existing Projects into Workspace'를 선택하고 메이븐 프로젝트가 있는 경로를 선택해주면 된다.

메이븐으로 이미 만든 프로젝트는 위와 같이 메이븐의 이클립스 플러그인으로 간편하게 이클립스 프로젝트로 만들면 된다.

이클립스에서 전부 다 하자.

이제는 처음부터 이클립스에서 메이븐 프로젝트를 만드는 방법을 알아보자. 그러기 위해서는 이클립스의 메이븐 플러그인을 이클립스에 설치해야 한다. 메이븐 플러그인으로는 M2EclipseQ4E 등이 있다. 둘 중에 아무거나 사용하면 될 것 같다. 나는 이전에 m2eclipse를 설치했는데 요즘엔 q4e가 더 좋다는 것 같기도.. @_@

이클립스의 Software Update에서 다음 사이트(Site)를 추가하고 설치하면 된다.

메이븐 플러그인을 설치한 후에 다음을 진행하도록 하자.

1. 프로젝트를 생성한다.

이클립스에서 다음과 같이 프로젝트를 생성한다. 옵션은 필요에 따라 바꾸면 될 것이다.

다음과 같이 프로젝트가 생성된다.

자동으로 App.java 파일과 AppTest.java 파일이 생성되었고, JUnit 3.8.1과의 의존성에 따라 프로젝트 클래스패스도 만들어졌다.

자동으로 만들어진 App.java, AppTest.java 파일들은 가뿐하게 지워주자.

2. 자바 버전을 5로 올리자.

자바 1.4보다는 자바 5 이상의 버전이 좋다. 메이븐 프로젝트를 처음 생성하면 기본적으로 자바 1.4에 맞춰져 있기 때문에 바꿔주어야 한다.

이전에 했던 대로 POM 파일에서 maven-compiler-plugin 설정을 추가해주면 된다. 직접 파일을 수정할 수도 있겠지만 이클립스의 도움을 받아보자.

이클립스에서 pom.xml 파일을 열면 자동으로 Maven POM editor로 열린다. 에디터 하단에서 plugin 탭을 선택하자. Plugins 부분에서 Add.. 버튼을 클릭하고, Plugin Details 부분에서 다음 그림과 같이 내용을 채워준다.

그리고 Executions 위에 있는 Configuration 링크를 클릭하여 다음 그림과 같이 나머지 설정을 넣어준다.

플러그인을 설정하는 것은 각 플러그인마다 설정하는 항목이 다르므로 결국 수동으로 작성해야 하는 불편함이 있는 것 같다.

이번엔 Dependencies 탭으로 가보자. JUnit 3.8.1이 라이브러리로 등록되어 있는데 자바 5로 올렸으니 거기에 맞게 JUnit도 4.5로 올려주자.

Dependencies 부분에서 junit을 선택하고 Dependency Details 부분에서 버전을 4.5로 바꿔준다.

3. 다른 라이브러리를 더 추가하자.

여기서는 역시 Commons Lang 라이브러리를 사용해보자. POM 에디터의 dependencies 탭에서 직접 추가할 수도 있겠지만.. 조금 더 편하게 라이브러리를 검색해서 추가하는 방법도 있다.

프로젝트에서 마우스 오른쪽 클릭 후 나오는 메뉴에서 Maven > Add Dependency 를 선택한다.

다음처럼 나오는 창에서 라이브러리를 검색하고, 원하는 라이브러리가 보이면 선택한다. 원하는 버전을 골라서 선택할 수 있다.

다음과 같이 commons-lang 라이브러리가 추가된 것을 볼 수 있다.

필요한 라이브러리를 모두 추가했으면 개발을 시작하자.

4. 소스와 테스트 파일을 추가한다.

Sample.java

package net.kjunine.maven.eclipse;

import org.apache.commons.lang.StringUtils;

public class Sample {

	public static String reverse(String s) {
		return StringUtils.reverse(s);
	}

	public static void main(String[] args) {
		for (int i = 0; i < args.length; i++) {
			System.out.println(reverse(args[i]));
		}
	}

}

SampleTest.java

package net.kjunine.maven.eclipse;

import static org.junit.Assert.*;

import org.junit.Test;

public class SampleTest {

	@Test
	public void testReverse() {
		String actual = Sample.reverse("hello");
		String expected = "olleh";
		assertEquals(expected, actual);
	}

}

이전 예제에서 사용한 예제 그대로이다. 다른 예제를 만들기가 귀차나서.. ㅠ_ㅠ

에러가 생기면 POM 에디터에서 수정한 사항이 프로젝트에 반영이 제대로 안 된 것이니 프로젝트에서 마우스 오른쪽 클릭 후  나오는 메뉴에서 Maven > Update DependenciesUpdate Project Configuration 을 실행하여 반영시키자.

5. 프로젝트를 테스트하고 빌드한다.

프로젝트에서 마우스 오른쪽 클릭 후 나오는 메뉴에서 Run As > Maven 으로 시작하는 많은 메뉴 아이템들을 볼 수 있다. 콘솔에서 직접 입력해서 실행하던 메이븐 명령어를 방금 언급한 메뉴를 선택하는 것으로 쉽게 실행할 수 있다.

빌드, 테스트 후 그리고 로컬 리포지토리에 설치하려면 아래 메뉴들 중에서 'Maven install' 메뉴를 선택한다.

콘솔 창에 'BUILD SUCCESSFUL' 이라고 메시지가 뜨면 성공한 것이다.

'Maven build...' 메뉴를 선택하면 다음과 같은 팝업창이 떠서 다른 플러그인의 골을 실행할 수 있다. 다음과 같이 exec:java 골을 실행하여 위에서 만든 프로그램을 실행하여 보자.

콘솔 창에 'BUILD SUCCESSFUL' 이라는 메시지와 함께 결과가 제대로 나오는 것을 볼 수 있을 것이다.

자바 프로젝트는 항상 메이븐과 함께 하자.

이제 메이븐의 기초를 배웠으니 자바 프로젝트를 만들 때는 항상 메이븐으로 시작하자. 이클립스 플러그인의 도움을 받으면 몇번의 클릭으로 거의 모든 것을 할 수 있으니 어려워하지 않아도 될 것 같다.

이것으로 첫 시리즈인 메이븐 시작하기 시리즈를 마친다. 자세하게 쓸려고 노력했지만 의미가 충분히 전달되지 않은 것도 많은 것 같다. 잘 이해가 안 가거나 잘 못된 부분은 댓글로 남겨주길 바라고, 더 자세히 알고싶으면 메이븐 홈페이지메이븐 책을 참고하길 바란다.

앞으로는 더 높은 수준의 포스트를 기대하며..

저작자 표시
Trackback 0 Comment 4
2009/10/09 22:34

메이븐(Maven) 시작하기 (2/3)

지난 번 포스트에서 메이븐으로 자바 프로젝트의 라이브러리를 관리하는 법을 살펴보았다. 이번 포스트에서 살짝 더 나아가서 메이븐의 꽃이라고 할 수 있는 플러그인에 대해서 알아보자.

메이븐 플러그인은 메이븐의 핵심이다.

일단 개념부터 짚고 넘어가자. 알아야하는 개념은 플러그인(Plugin)과 골(Goal)이다.

플러그인은 메이븐의 핵심 구성 요소이다. 다시 말하면 메이븐은 플러그인들의 집합이라고 할 수 있다. 참고로 메이븐 홈페이지의 플러그인 페이지에서 사용 가능한 플러그인들의 목록을 볼 수 있다. 그리고 플러그인은 관련있는 골들의 집합이다. 골은 메이븐에서 작업의 단위이라고 할 수 있다. 앤트(Ant)를 안다면 앤트의 태스크(task)와 유사한 것으로 생각해도 될 것이다. 메이븐 생명주기의 관점에서 보면 빌드 단계(Build Phase)에는 그 단계가 실행하는 골이 정해져있다. 예를 들면, compile 빌드 단계는 compiler 플러그인의 compile 골을 실행하고, package 빌드 단계는 jar 플러그인의 jar 골을 실행한다.

정리하면 메이븐에는 무수한 플러그인들이 있고, 각 플러그인들은 관련된 골들을 묶어 놓은 것이다. 그리고 각 골들은 메이븐 빌드 단계에서 수행되는 하나의 작업인 것이다. 더 자세한 설명은 역시 메이븐 홈페이지메이븐 책(Maven: The Definitive Guide)를 참고하자.

메이븐 플러그인을 사용해 보자.

사실 지난 번 포스트에서 이미 메이븐 플러그인을 사용해 보았다.

mvn archetype:generate -DgroupId=net.kjunine -DartifactId=sample -Dpackage=net.kjunine.sample -Dversion=1.0-SNAPSHOP

위 명령어를 기억하는가? 위 명령어에서 'archetype:generate'는 archetype 플러그인의 generate 골을 실행하라는 메이븐 명령어이다. 참고로 archetype 플러그인은 자바 프로젝트를 생성하는 것과 관련있는 골들의 모음이다. 이 플러그인에 대해 자세한 설명은 여기를 참고하자. 여기서 보여주고 싶은 것은 플러그인의 골을 실행하는 방법이다. mvn 명령어에 플러그인:골 형식의 옵션과 -D를 붙인 key=value 형식의 파라메터들을 덧붙여서 실행하면 된다.

그리고 지난 번 포스트에서 완성된 프로젝트를 실행하는 방법이 좀 까다로웠던 것을 기억하는가?

java -cp target/sample-1.0-SNAPSHOT.jar;"%HOME%/.m2/repository/commons-lang/commons-lang/2.4/commons-lang-2.4.jar" net.kjunine.sample.Sample hello kjunine

위와 같이 클래스패스를 복잡하게 설정하면서 실행했었는데 이것을 exec 플러그인을 사용하면 간단하게 실행시킬 수 있다. exec 플러그인의 상세한 설명은 여기를 참조하자.

mvn exec:java -Dexec.mainClass=net.kjunine.sample.Sample -Dexec.args="hello kjunine"

exec 플러그인이 POM 파일을 참조해 라이브러리와 프로젝트의 의존 관계를 파악해서 알아서 클래스패스를 설정해주므로 명령어가 매우 간단해졌다. 결과는 다음과 같이 나온다.

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] ------------------------------------------------------------------------
[INFO] Building sample
[INFO]    task-segment: [exec:java]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing exec:java
[INFO] No goals needed for project - skipping
[INFO] [exec:java]
olleh
eninujk
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: < 1 second
[INFO] Finished at: Fri Oct 09 21:51:55 KST 2009
[INFO] Final Memory: 5M/9M
[INFO] ------------------------------------------------------------------------

플러그인을 실행하는 방법을 알아봤으니 이번에는 POM 파일에서 플러그인의 설정을 하는 방법을 알아보자.

메이븐으로 자바 프로젝트를 빌드할 때 compiler 플러그인의 설정을 바꿔주지 않으면 기본적으로 JDK 1.4 버전을 기준으로 컴파일한다. 그래서 지난 번 포스트에서는 JUnit 라이브러리의 버전이 3.8.2였던 것이다. 이번 기회에 JDK 버전과 JUnit 버전을 각각 1.5와 4.5로 올리고, @Test 어노테이션(Annotation)을 사용해 보자.

1. POM 파일(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>net.kjunine</groupId>
  <artifactId>sample</artifactId>
  <packaging>jar</packaging>
  <version>2.0-SNAPSHOT</version>
  <name>sample</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.5</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

주목할 부분은 세 부분이다. 첫째, 프로젝트의 version 을 '2.0-SNAPSHOT'으로 올렸다. 둘째, junit 라이브러리의 버전을 4.5로 올렸다. 셋째, <build /> 부분에 그 안에 compiler 플러그인의 설정을 추가하였다. 여기서 플러그인을 설정하는 방법을 잘 봐두자. 다른 플러그인도 마찬가지 방법으로 설정할 수 있다. compiler 플러그인에 대한 상세한 설명은 여기를 참조하자.

2. SampleTest 클래스를 수정하자.

package net.kjunine.sample;

import static org.junit.Assert.*;

import org.junit.Test;

public class SampleTest {

	@Test
	public void testReverse() {
		String actual = Sample.reverse("hello");
		String expected = "olleh";
		assertEquals(expected, actual);
	}

}

JUnit 4.5의 @Test 어노테이션을 사용하도록 수정하였다.

mvn test 명령어를 실행하면 빌드와 테스트가 성공하는 것을 볼 수 있다. 그리고 mvn install 명령어를 실행하면 설치가 성공하는 것을 볼 수 있고, 로컬 리포지토리에 이전 버전인 1.0-SNAPSHOT 버전과 최신 버전인 2.0-SNAPSHOT 버전이 모두 설치되어 있는 것을 볼 수 있다.

메이븐 플러그인을 맛보다..

이 포스트에서 메이븐 플러그인을 살펴보았다. 그러나 여기서 살펴본 것은 거의 맛만 본 수준이다. 메이븐에는 무수한 플러그인이 있고, 또 직접 플러그인을 만들 수도 있다. 메이븐을 제대로 알려면 최대한 많은 프러그인들을 사용해보고 또, 직접 플러그인을 만들어 보는 것이 좋을 것이다.

포스트를 쓰다보니 길어져서 또 나누게 되었다. 다음 포스트에서는 메이븐과 이클립스의 연동을 주제로 '메이븐 시작하기' 시리즈를 마무리하고자 한다. 그럼 다음 포스트에서..

저작자 표시
Trackback 0 Comment 4
2009/10/09 22:28

메이븐(Maven) 시작하기 (1/3)

메이븐으로 자바 프로젝트를 관리해 보자.

이전부터 자바 프로젝트를 시작할 때 제일 먼저하는 것은 이클립스를 띄우고, 자바 프로젝트를 만들고 라이브러리들을 lib 폴더에 추가하는 것이었다. 그런데 비슷비슷한 라이브러리들을 똑같이 사용하는 자바 프로젝트를 여러 개 만들다보면 비슷한 노가다를 계속해야 했다. 그러다가 조금 더 발전한 것이 여러 프로젝트에서 공통으로 사용하는 라이브러리 프로젝트를 만들어서 참조하게 한 것이다. 조금 편해졌지만 그래도 각 프로젝트마다 클래스패스를 잡아주는 것은 고역이었다.

그러다 메이븐이라는 것을 알게 되었다. 메이븐에서 라이브러리 혹은 프로젝트 의존 관계(Dependency)를 설정하는 것은 매우 간단하다. 설정 파일에 그 의존 관계를 선언하기만 하면 된다. 이클립스와의 연동도 가능하다. 메이븐에서 이클립스 프로젝트를 만들 수도 있고, 이클립스에서 메이븐 플러그인을 설치하여 메이븐 프로젝트를 만들 수도 있다.

메이븐은 사실 의존 관계 관리 도구라기보다는 프로젝트 관리 도구이다. 메이븐은 빌드 생명주기(Build Lifecycle)에 따라 프로젝트 표준을 제공하고 의존 관계를 관리하고 플러그인이 제공하는 부가 기능을 사용할 수 있게 하는 도구이다. 더 자세한 것은 메이븐 홈페이지나 Sonatype에서 공개한 메이븐 책(Maven: The Definitive Guide)를 참조하길 바란다. 메이븐 책은 무료로 다운로드 받을 수 있고, 영어임에도 불구하고 매우 쉽게 쓰여져 읽는 데 큰 어려움은 없다. Thanks, Sonatype. 메이븐 책을 3장까지만 읽어보면 감을 잡을 것이다. 사실 메이븐 책 3장까지 봤으면 이 포스트는 볼 필요도 없다. ㅎ_ㅎ (그래도 이건 한글이다. +_+)

일단 따라해보자.

애초에 라이브러리 관리를 더 편하게 하기 위해 메이븐을 사용하려고 했던 것이니 다른 라이브러리를 사용하는 프로젝트를 만들어 보자. 단위 테스트를 위한 JUnit 라이브러리와 자바 API를 보완하는 여러 기능들을 제공하는 Commons Lang 라이브러리 정도만 사용해 보자.

1. 메이븐을 설치한다.

메이븐 홈페이지에서 메이븐을 다운로드하고 적당한 폴더에 압축을 푼 뒤, 메이븐 폴더 내 bin 폴더를 PATH에 추가해준다. mvn --help 명령어를 쳤을 때 사용법이 제대로 나온다면 다음을 진행할 수 있다. mvn은 메이븐을 실행하는 명령어이다.

2. 메이븐 프로젝트를 만든다.

작업할 폴더에서 다음 명령어를 실행한다. 도중에 옵션을 물어보기도 하는데 그냥 엔터를 쳐서 기본값으로 넘어갈 수 있다.

mvn archetype:generate -DgroupId=net.kjunine -DartifactId=sample -Dpackage=net.kjunine.sample -Dversion=1.0-SNAPSHOT

위 명령어에서 archetype:generate는 archetype 플러그인의 generate 골(Goal)이라는 것인데, 플러그인과 골은 지금은 몰라도 좋다. 그냥 프로젝트를 생성하는 옵션이라고 생각하면 된다. -D로 시작하는 것들은 생성할 프로젝트에 대한 정보를 나타내는 파라메터들이다. 각 파라메터는 다음을 의미한다.

  • groupId
    • 프로젝트를 만드는 그룹, 조직, 회사 등을 나타내는 유일한 이름, 보통 자바 패키지처럼 URI를 거꾸로 써서 나타낸다.
  • artifactId
    • 아티팩트(artifact) 즉, 프로젝트를 나타내는 유일한 이름, 그룹 내 다른 아티팩트와 이름이 같아서는 안된다.
  • package
    • 프로젝트의 최상위 패키지
  • version
    • 프로젝트의 현재 버전

프로젝트 생성이 성공하면, 명령어를 수행한 폴더 내에 artifactId 이름과 동일한 폴더가 생긴다. 그 폴더로 들어가면 다음과 같이 src 폴더와 pom.xml 파일을 볼 수 있다.

pom.xml 파일은 바로 Project Object Model(POM)이라는 것으로 메이븐 프로젝트에 대한 모든 설정을 저장하는 파일이다. 메이븐 프로젝트의 모든 것이다. 그 파일을 열어보면 다음과 같을 것이다. 앞서 프로젝트 생성 시 설정한 프로젝트 옵션 값들이 저장되어 있는 것을 볼 수 있다.

<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>net.kjunine</groupId>
  <artifactId>sample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>sample</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>

3. 라이브러리 의존 관계를 설정한다.

POM에서 지금 관심을 가져야 할 부분은 바로 <dependencies /> 부분이다. 여기에서 프로젝트의 의존 관계를 설정할 수 있다. 현재 JUnit 라이브러리는 자동으로 추가되어 있는 것을 볼 수 있다. 여기에 Commons Lang 라이브러리도 추가하자. <dependencies /> 부분을 다음과 같이 바꾸면 된다. <dependency /> 항목을 하나 추가하는 것으로 라이브러리를 추가할 수 있다. 정말 편하지 않은가?! +_+

  <dependencies>
    <dependency>
      <groupId>commons-lang</groupId>
      <artifactId>commons-lang</artifactId>
      <version>2.4</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

해당 라이브러리의 groupId와 artifactId는 어떻게 알 수 있는지 궁금할 것이다. 의외로 간단하다. Maven Repository 홈페이지에서 검색하면 된다. 다만 가끔 비슷한 게 많이 나와서 어떤 걸 써야할지 모를 때도 있다. (예를 들면, springframework) 그럴 때는 해당 라이브러리 홈페이지에서 정확한 메이븐 groupId와 artifactId를 찾아보던가 구글링할 수 밖에 없는 것 같다. 아직 내공이 부족하다. ㅠ_ㅠ

4. 자바 소스와 테스트를 작성한다.

프로젝트 폴더 내 src 폴더에 보면 main 폴더와 test 폴더가 있는데 각각 자바 소스 파일과 테스트 파일들이 존재하는 곳이다. 메이븐은 이렇게 정해진 폴더 구조와 이름을 강제로 사용하게 해서 프로그래머의 고민을 덜어준다. 하지만 바꿀 수도 있는 것 같다.

각 소스 폴더와 테스트 폴더에는 프로젝트 생성 시에 설정한 패키지 이름대로 폴더 구조가 만들어져 있고, 각각 App.java 파일과 AppTest.java 파일이 존재한다. 두 파일을 사용할 것은 아니니 삭제하자.

그리고 소스 폴더의 해당 패키지에 다음 클래스 파일를 작성하자.

Sample.java

package net.kjunine.sample;

import org.apache.commons.lang.StringUtils;

public class Sample {

	public static String reverse(String s) {
		return StringUtils.reverse(s);
	}

	public static void main(String[] args) {
		for (int i = 0; i < args.length; i++) {
			System.out.println(reverse(args[i]));
		}
	}

}

Commons Lang 라이브러리의 StringUtils 유틸 클래스가 제공하는 reverse 메소드를 사용하여 입력받은 문자열들을 거꾸로 출력하는 프로그램을 만들었다.

테스트 폴더의 해당 패키지에 위 클래스에 대한 테스트 클래스 파일도 작성하자.

SampleTest.java

package net.kjunine.sample;

import junit.framework.TestCase;

public class SampleTest extends TestCase {

	public void testReverse() {
		String actual = Sample.reverse("hello");
		String expected = "olleh";
		assertEquals(expected, actual);
	}

}

JUnit 라이브러리를 사용한 간단한 테스트 클래스이다.

5. 프로젝트를 빌드한다.

프로젝트를 빌드하는 것은 간단하다. 프로젝트 폴더에서 다음 명령어를 실행하면 된다.

 mvn install

이 명령어를 이해하려면 메이븐에서 말하는 빌드 생명주기(Build Lifecycle)라는 개념을 알아야 한다. 빌드 생명주기는 일련의 프로젝트 빌드 단계(Build Phase)들의 (순서있는) 집합이다. 빌드 단계는 compile, test, package, deploy 등과 같은 프로젝트를 빌드하는데 거치는 단계들을 의미한다. 그리고 각 빌드 단계마다 무슨 일을 해야하는지가 정해져 있다. 허접한 설명이라 더 자세한 내용은 여기를 참조하자. (메이븐 책을 봐도 좋다.)

위 명령어는 생명주기에서 install 단계까지의 전 단계를 실행하라는 것으로 compile, test, package, install 등의 단계들을 포함한다.

그래서 위 명령어를 실행하면 중간에 다음과 같이 테스트 결과가 나온다. 그리고 빌드가 성공하면 "BUILD SUCCESSFUL"이 보일 것이다.

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running net.kjunine.sample.SampleTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.031 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar: D:\dev\workspaces\maven\sample\target\sample-1.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing D:\dev\workspaces\maven\sample\target\sample-1.0-SNAPSHOT.jar to ...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

또, 프로젝트 폴더 내 target 폴더에 생성된 클래스 파일들과 테스트 파일들 등이 들어있는 폴더들과 함께 jar 형태로 묶인 프로젝트 패키지 파일이 보인다.

6. 프로그램을 실행한다.

테스트도 성공하고 패키지 파일도 생성했으니 이제 실행만 하면 된다. 다음 명령어를 실행하라.

java -cp target/sample-1.0-SNAPSHOT.jar;"%HOME%/.m2/repository/commons-lang/commons-lang/2.4/commons-lang-2.4.jar" net.kjunine.sample.Sample hello kjunine

생각보다 실행 방법이 까다로운데 이것은 아직 플러그인을 배우지 않았기 때문이니 지금은 그냥 참고 넘어가자. %HOME%/.m2/repository 폴더는 메이븐이 라이브러리와 플러그인을 다운로드해서 저장하는 로컬 저장 폴더이다. 그리고 Commons Lang 라이브러리는 위와 같은 경로에 존재한다. 실행 시에 Commons Lang 라이브러리를 사용하기 때문에 클래스패스에 추가한 것이다.

실행 결과는 다음과 같다.

olleh
eninujk

굳~

이제 겨우 걸음마를 시작했을 뿐..

아직 메이븐에 대해 공부할 것은 많이 남아 있다. 플러그인과 골의 개념을 이해하고 POM에 설정할 수 있어야 한다. 그리고 이클립스에서 개발하기 위해 메이븐 이클립스 플러그인(maven-eclipse-plugin)을 사용하거나, 아니면 m2eclipse, Q4E와 같은 이클립스 플러그인을 사용할 수 있어야 한다. 실제 프로젝트를 진행할 때는 지금처럼 명령어에서 실행하기보다는 이클립스 플러그인을 사용하는 것이 훨씬 쉽고 간편할 것이다.

방금 말한 내용들은 다음 포스트들에서 다룰 것이다. 이미 제목은 써놓았다. 다만 언제 완성될지는.. ^^;


저작자 표시
Trackback 0 Comment 0
2009/10/07 00:59

기본 윈도우 크롬을 사용하지 않는(chromeless) 에어(AIR) 어플리케이션 만들기

나만의 멋진 윈도우 모양을 가지는 AIR 어플리케이션을 만들어 보자.


트위터 클라이언트인 DestroyTwitter처럼 AIR로 만들어진 데스크탑 애플리케이션들을 보면 대부분이 운영체제에서 사용하는 기본 윈도우 크롬(타이틀과 테두리 영역)을 사용하지 않고, 대신 자신만의 보기 좋은 윈도우 모양을 사용하고 있다. 이 포스트에서는 어떻게 하면 기본 윈도우 크롬을 사용하지 않을 수 있는지 보여주겠다. 어려워 보이지만 사실 매우 간단하다. 딱 두가지만 하면 된다.

1. 애플리케이션 디스크립터(Application Descriptor) 파일을 수정한다.

플렉스 빌더로 만든 프로젝트에서는 메인 MXML 파일 이름에 '-app' 가 더 붙은 XML 파일이 애플리케이션 디스크립터 파일이다. FlashDevelop에서는 application.xml 파일이다.

애플리케이션 디스크립터 파일에서 <initialWindow /> 부분 중 <systemChrome /> 태그의 값은 'none'으로 설정하고, <transparent /> 태그의 값은 'true'로 설정한다.

	<initialWindow>
		...
		<systemChrome>none</systemChrome>
		<transparent>true</transparent>
		...
	</initialWindow>

2. 메인 MXML 파일을 수정한다.

메인 MXML 파일에서 WindowedApplication 컴포넌트의 'showFlexChrome' 속성을 'false' 로 설정하면 된다.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" showFlexChrome="false">
	...
</mx:WindowedApplication>

이게 끝이다. 다음은 위 방법대로 만들어 본 예제이다.

WindowedApplication 컴포넌트 안에 Canvas와 Button만 넣었다. 소스는 다음과 같다.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" showFlexChrome="false">
	<mx:Canvas width="100" height="100" backgroundColor="0xEEEEEE" backgroundAlpha="0.5">
		<mx:Button label="hello" x="10" y="10" width="80" height="80" />
	</mx:Canvas>
</mx:WindowedApplication>

이제 남은 것은..

이제 기본 윈도우 크롬을 제거하는 방법은 알았다. 실제 애플리케이션처럼 제대로 만들려면 자체 윈도우 모양을 만들고 그 윈도우가 실제 윈도우처럼 동작하게 만들어야 할 것이다. 상단 타이틀을 클릭 & 드래그해서 이동하거나 최대/최소화하는 등의 기능을 구현해야 할 것이다. 이러한 기능들도 쉽게 만들 수 있도록 AIR에서 API로 제공하고 있으니 AIR 문서를 참조하면 어렵지 않게 만들 수 있을 것이다.

다음에 기회가 되면 멋진 자체 윈도우를 만드는 것도 포스팅할 생각은 있다.. 생각만 있다.

저작자 표시
Trackback 0 Comment 0
2009/09/12 20:42

FlexUnit - Flex(플렉스) 단위 테스트 프레임워크

Flex에서 단위 테스트를 하자!

나는 모르고 있었다. Flex에도 단위 테스트를 위한 프레임워크가 있다는 것을.. 바로 FlexUnit으로 플렉스에서 단위 테스트를 할 수가 있다. 비슷한 프레임워크로 AsUnit이란 게 있는데, 아주 살짝 살펴보니 다음과 같은 차이가 있는 것 같다.

  • AsUnit
    • Flex SDK가 없어도 사용할 수 있다.
  • FlexUnit
    • 테스트 결과를 쌔끈한 UI로 보여준다.

FlashDevelop에서 FlexUnit을 사용해 예제를 하나 만들어 보았다. 참고로 FlashDevelop은 유료 소프트웨어인 Flash Builder (구 Flex Builder)를 대체할 수 있는 오픈소스 소프트웨어이다. (여기에서 최신버전을 다운로드 받을 수 있다.)

그럼 예제를 따라해보자. 잠깐! 그 전에 여기에서 FlexUnit 라이브러리를 다운로드하고 시작하자. 다운로드한 압축파일 속 bin 폴더의 'FlexUnit.swc' 파일을 사용하게 될 것이다.

 1. FlashDevelop에서 Flex 3 프로젝트를 생성한다.

메뉴에서 Project > New Project를 선택한다. 템플릿에서 Flex 3 Project를 선택하고, 프로젝트 이름, 저장 위치, 기본 패키지 이름을 채우고 프로젝트를 생성한다.

프로젝트가 생성되면 우측 프로젝트 뷰에서 src 폴더 속 방금 지정한 패키지에 'Main.mxml' 파일이 생긴 것을 볼 수 있다.

2. 해당 프로젝트에 FlexUnit 라이브러리를 추가한다.

lib 폴더에 앞에서 말했던 FlexUnit.swc 파일을 복사한다. 그리고 FlexUnit.swc 파일에서 마우스 오른쪽 클릭한 후, Add To Library를 선택하면 된다. 참 쉽죠~잉?

3. 테스트하고자 하는 ActionScript 클래스를 만든다.

net.kjunine.test.sample.Sample.as

package net.kjunine.test.sample 
{
	
	public class Sample 
	{
		
		public static function sum(values:Array):Number
		{
			var sum:Number = 0;
			
			for (var i:int = 0; i < values.length; i++) 
			{
				sum += parseInt(values[i]);
			}
			
			return sum;
		}
		
	}
	
}

Sample 클래스에 배열을 파라메터로 받아들여서 그 배열의 모든 엘리먼트들의 합을 구해서 반환하는 sum이라는 메소드를 만들어 보았다.

4. 방금 만든 ActionScript 클래스를 테스트할 TestCase 클래스를 만든다.

먼저 테스트 소스가 들어갈 test 폴더를 만들고 그 안에 폴더를 추가해 src와 같은 패키지 구조로 만들어 준다. 그리고 메뉴에서 Project > Properties를 선택해서 classpath 탭을 선택하고 방금 만든 test 폴더를 클래스패스에 추가한다. (지금처럼 소스와 테스트를 폴더로 분리하는 것이 바람직한 방법이다.)

net.kjunine.test.sample.SampleTest.as

package net.kjunine.test.sample 
{
	import flexunit.framework.TestCase;
	
	public class SampleTest extends TestCase
	{
		
		public function testSum():void
		{
			var values:Array = new Array('8', '20', '10', '7', '15');
			
			var actual:Number = Sample.sum(values);
			var expected:Number = 60;
			
			assertEquals(expected, actual);
		}
		
	}
	
}

TestCase를 상속받은 SampleTest 클래스를 만들어서 Sample.sum() 메소드를 테스트한다. TestCase 클래스는 JUnit처럼 다양한 assert 메소드들을 제공한다.

5. 테스트용 Main.mxml을 만든다.

net.kjunine.test.Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:flexui="flexunit.flexui.*" creationComplete="this.init();">
	<mx:Script>
		<![CDATA[
		import flexunit.framework.TestSuite;
		import net.kjunine.test.sample.SampleTest;
		
		private function init():void {
			var test:TestSuite = new TestSuite();
			test.addTestSuite(SampleTest);
			testRunner.test = test;
			testRunner.startTest();
		}
		]]>
	</mx:Script>
	<flexui:TestRunnerBase id="testRunner" />
</mx:Application>

TestRunnerBase와 TestSuite가 사용된다. 테스트를 더 추가하고 싶으면 다른 테스트 클래스를 TestSuite.addTestSuite() 메소드로 추가해주기만 하면 된다.

예제의 모든 내용을 만들었다. 그러면 프로젝트 구조는 위와 같을 것이다.

6. 테스트를 실행한다.

FlashDevelop에서 프로젝트를 실행하는 것은 메뉴에서 Project > Test Movie를 선택하거나 단축키 F5를 누르면 된다. 그러나 실행하기 전에 test 폴더의 Main.mxml 파일이 실행되도록 하자.

위 그림과 같이 test 폴더의 Main.mxml 파일에서 마우스 오른쪽 클릭한 후 Always Compile을 선택한다. 이렇게 하면 Test Movie를 실행했을 때 test 폴더의 Main.mxml 파일이 실행될 것이다. (만약 다시 src 폴더의 Main.mxml 파일이 실행되게 하려면 src 폴더의 Main.mxml 파일에서 같은 방법대로 하면 된다.)

이제 실행해보자. 위 그림과 같이 테스트가 성공하였는가? 그리고 UI가 정말 이쁘지 않은가? ^-^ 화면 중간에 보이는 드롭다운 박스의 옵션을 선택해서 리스트에 보일 테스트 결과를 변경할 수 있다.

방금 만든 프로젝트 파일들을 압축해서 올렸다. 참고하시라.

이제 FlexUnit로 Flex에서 단위 테스트를 할 수 있게 되었다. 그 동안 ActionScript 클래스를 테스트 해보기 위해서 trace()를 남발했었는데 이제부터는 테스트를 작성해서 테스트하면 안심할 수 있을 것이다.


저작자 표시
Trackback 0 Comment 0
2008/09/30 21:00

톰캣(Tomcat) 5.x GET 방식 한글 인코딩에 문제가 있다니..

여태껏 잘 되는 줄 알았던 한글 처리가 POST 방식일 때만 잘 되었던 거였어요..
우연히 오늘 GET 방식으로 보내다가 한글이 깨지는 현상을 발견하고 이유를 찾다가 알게 되었네요..

다른 블로그에 관련 내용이 많이 있어서 링크만 걸어둡니다.
다행히 해결책도 함께 다루고 있네요

아무튼 쇼크~! 충격입니다. @_@


Trackback 0 Comment 0
2008/06/08 02:25

앤트(Ant)에서 톰캣에 웹 애플리케이션을 디플로이하는 방법..

톰캣에 웹 애플리케이션을 디플로이하는 방법에는 두 가지가 있어요.
  • ${톰캣_설치_경로}[각주:1]/webapps 디렉토리에 war 파일을 추가한다.
  • ${톰캣_설치_경로}/conf/Catalina/localhost 디렉토리에 context 파일을 추가한다.
war 파일은 일반적인 웹 애플리케이션 파일이구요.
context 파일 내용은 대략 다음과 같아요.

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/${웹애플리케이션_이름}" docBase="${웹애플리케이션_디렉토리}" reloadable="true">
</Context>

첫번째 방법이 보통 많이 쓰이는 방법이죠. 저는 두번째 방법을 더 선호합니다만..



그런데 사실 한 가지 방법이 더 있습니다.

톰캣의 manager 어플리케이션을 이용하는 것입니다. ^-^/

톰캣의 manager 어플리케이션을 사용하려면 다음을 확인합니다.

1.톰캣에 manager 어플리케이션이 설치되어 있는지 확인한다.
   (5.0, 5.5, 6.0 버전 모두 기본적으로 설치되어 있네요..)

2. manager 권한이 있는 사용자를 등록한다.
    ${톰캣_설치_경로}\conf\tomcat-users.xml 파일에 다음 내용을 추가합니다.

<role rolename="manager"/>
<user username="${사용자_아이디}" password="${사용자_암호}" roles="manager"/>

3. 서버를 띄우고 http://localhost:8080/manager/html 로 접속합니다.
    (등록한 사용자의 아이디/암호를 입력합니다.)

다음과 같은 화면에서 Deploy를 실행하면 됩니다.
Context 파일 내용을 설정하거나 war 파일을 업로드해서 디플로이할 수 있습니다.


그리고 매니저에서는 다른 웹 애플리케이션을 실행/중지/리로드/언디플로이할 수 있어요~



이제부터 본론으로 들어갑니다.

제가 말씀드릴 앤트로 톰캣에 웹 애플리케이션을 디플로이하는 방법은 내부적으로 톰캣의 manager 애플리케이션을 이용합니다. 그러므로 먼저 톰캣의 manager 애플리케이션이 설정이 되어있어야 해요~!

빌드 파일에서 사용할 프로퍼티 파일은 다음과 같습니다. (sample 어플리케이션을 배포한다고 가정합니다.)

# catalina home directory
catalina.home=C:\Tomcat[각주:2]
catalina.ant.jar=${catalina.home}/server/lib/catalina-ant.jar
catalina.tasks.file=catalina.tasks[각주:3]

# catalina manager configurations
catalina.manager.url=http://localhost:8080/manager
catalina.manager.user.name=test[각주:4]
catalina.manager.user.password=test

# application configurations
application.path=/sample[각주:5]
application.context=sample.xml[각주:6]

그리고 태스크 정의 파일이 필요합니다. 다음과 같은 내용으로 catalina.tasks 라는 파일을 만듭니다.

# catalina tasks properties
deploy=org.apache.catalina.ant.DeployTask
undeploy=org.apache.catalina.ant.UndeployTask
start=org.apache.catalina.ant.StartTask
reload=org.apache.catalina.ant.ReloadTask
stop=org.apache.catalina.ant.StopTask
sessions=org.apache.catalina.ant.SessionsTask
list=org.apache.catalina.ant.ListTask
serverinfo=org.apache.catalina.ant.ServerinfoTask
roles=org.apache.catalina.ant.RolesTask
resources=org.apache.catalina.ant.ResourcesTask

어플리케이션 컨텍스트 설정 파일이 필요합니다. 다음과 같은 내용으로 sample.xml 이라는 파일을 만듭니다.

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/sample" docBase="C:\Sample[각주:7]" debug="0" privileged="true" reloadable="true">
    <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost.sample." suffix=".txt" timestamp="true" />
</Context>

마지막으로 빌드 파일 내용은 다음과 같습니다.

먼저 태스크 정의 파일을 설정해야 합니다.

<taskdef file="catalina.tasks" classpath="${catalina.ant.jar}" />

그러면 다음과 같은 태스크들을 사용할 수 있어요.

<target name="catalina.deploy" description="Deploy web application">
    <deploy url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" config="${application.context}" update="true" />
</target>

<target name="catalina.undeploy" description="Undeploy web application">
    <undeploy url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" />
</target>

<target name="catalina.start" description="Start web application">
    <start url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" />
</target>

<target name="catalina.reload" description="Reload web application">
    <reload url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" />
</target>

<target name="catalina.stop" description="Stop web application">
    <stop url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" />
</target>

<target name="catalina.sessions" description="View server information">
    <sessions url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" />
</target>

<target name="catalina.list" description="List web applications">
    <list url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" />
</target>

<target name="catalina.serverinfo" description="View server information">
    <serverinfo url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" />
</target>

<target name="catalina.roles" description="View server information">
    <roles url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" />
</target>

<target name="catalina.resources" description="View server information">
    <resources url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" />
</target>

디플로이 태스크를 자세히 살펴보죠.

<deploy url="${catalina.manager.url}" username="${catalina.manager.user.name}" password="${catalina.manager.user.password}" path="${application.path}" config="${application.context}" update="true" />

config 속성에 애플리케이션의 컨텍스트 설정 파일의 위치를 입력하는데요..
config 속성 대신에 war 속성을 써서 애플리케이션 war 파일의 위치를 입력할 수도 있어요.
두 속성은 반드시 어느 하나만 써야해요. 안 그러면 에러날 걸~?

톰캣의 앤트태스크를 이용하면 애플리케이션을 디플로이하는 것 뿐만 아니라 웹 어플리케이션의 목록을 보는 것, 애플리케이션을 실행하거나 중지하는 것 등등의 작업을 앤트로 할 수가 있어요. 이게 다 톰캣 개발자들이 앤트 태스크를 쓰기 좋게 만들어둔 덕분이죠. 감사감사 ^^*

보면 볼수록 앤트는 멋진 것 같아요.

환경:
Tomcat 5.0 or 5.5
Ant 1.7.0

  1. ${무언가} 는 변수를 뜻해요! [본문으로]
  2. 톰캣의 설치 경로에요. [본문으로]
  3. 태스크 정의 파일 이름 [본문으로]
  4. manager 권한이 있는 사용자 이름과 암호 [본문으로]
  5. 샘플 어플리케이션 경로 [본문으로]
  6. sample 어플리케이션 컨텍스트 파일 이름 [본문으로]
  7. 샘플 어플리케이션 디플로이 경로 [본문으로]
Trackback 0 Comment 0
2008/06/08 01:28

앤트(Ant)에서 톰캣을 실행/중지해 보아요.

앤트에서 톰캣을 실행하거나 중지해 보아요.

방법은 간단해요. <java /> 태스크로 org.apache.catalina.startup.Bootstrap 클래스를 실행하면 돼요.
다만 프로퍼티 옵션이나 환경 변수 등의 실행 옵션을 잘 주어야 해요.

다음과 같이 해 보아요.

build.properties
java_home=C:/Program Files/Java/jdk1.5.0_14
catalina.home=C:/Programz/Tomcat/5.5
catalina.base=C:/Project/Tomcat/Configuration


java.home 이라는 프로퍼티가 이미 존재(자동으로 생성)하기 때문에, java_home 이라는 이름으로 만들었어요.

build.xml
<project name="history" default="default" basedir=".">

	<property file="build.properties" />

	<target name="default">
		<echo message="이것은 'Ant Tomcat Container'의 빌드 파일이에요." />
		<echo message="앤트(ant) 1.7.0 버전에 최적화되어 있어요." />
		<echo message="사용법:" />
		<echo message="ant tomcat.start" />
		<echo message="ant tomcat.stop" />
		<echo message="참고:" />
		<echo message="java.home = ${java.home}" />
		<echo message="java_home = ${java_home}" />
		<echo message="catalina.home = ${catalina.home}" />
		<echo message="catalina.base = ${catalina.base}" />
	</target>

	<target name="tomcat.start">
		<java classname="org.apache.catalina.startup.Bootstrap" jvm="${java_home}/bin/java" fork="true" spawn="true">
			<classpath>
				<fileset dir="${catalina.home}/bin">
					<include name="bootstrap.jar" />
				</fileset>
			</classpath>
			<arg value="start" />
			<sysproperty key="catalina.home" value="${catalina.home}" />
			<sysproperty key="java.endorsed.dirs" value="${catalina.home}/common/endorsed" />
			<sysproperty key="java.util.logging.manager" value="org.apache.juli.ClassLoaderLogManager" />
			<sysproperty key="java.util.logging.config.file" value="${catalina.home}/conf/logging.properties" />
			<sysproperty key="catalina.base" value="${catalina.base}" />
			<sysproperty key="java.io.tmpdir" value="${catalina.base}/temp" />
		</java>
	</target>

	<target name="tomcat.stop">
		<java classname="org.apache.catalina.startup.Bootstrap" jvm="${java_home}/bin/java" fork="true" spawn="true">
			<classpath>
				<fileset dir="${catalina.home}/bin">
					<include name="bootstrap.jar" />
				</fileset>
			</classpath>
			<arg value="stop" />
			<sysproperty key="catalina.base" value="${catalina.home}" />
			<sysproperty key="catalina.home" value="${catalina.home}" />
			<sysproperty key="java.endorsed.dirs" value="${catalina.home}/common/endorsed" />
			<sysproperty key="java.util.logging.manager" value="org.apache.juli.ClassLoaderLogManager" />
			<sysproperty key="java.util.logging.config.file" value="${catalina.home}/conf/logging.properties" />
			<sysproperty key="java.io.tmpdir" value="${catalina.home}/temp" />
		</java>
	</target>

</project>


톰캣은 JRE가 아니라 JDK로 실행시켜야 하기 때문에 <java /> 태스크의 jvm 속성으로 JDK의 java를 지정했어요.
그리고 새로운 JVM에서 실행이 되도록 fork 속성을, 앤트의 JVM이 종료되더라도 톰캣의 JVM이 계속 남아 있게 하기 위해서 spawn 속성을 true로 지정했어요.

환경:
    Ant 1.7.0
    Tomcat 5.0 or 5.5

Trackback 1 Comment 4
2008/06/08 00:13

앤트(Ant)의 프로퍼티 파일(.properties)의 제한에 대해서..

디렉토리 구분자의 제한

Ant에서는 경로를 나타낼 때, 디렉토리 구분자로 '/'와 '\'를 모두 사용할 수 있어요.
Ant는 두 가지 슬래시 모두를 사용한다고 해서 부끄러워하지 않으며, 오히려 그것을 자랑스럽게 생각한다.
- 자바의 또 다른 멋진 도구 Ant

그러나 프로퍼티 파일에서 경로를 지정할 때 '\'를 사용하고 싶으면, '\\'로 써야해요.
왜냐하면 자바에서는 '\' 문자를 이스케이프 문자로 취급하기 때문이지요. 

프로퍼티 파일 간 참조의 제한

Ant의 프로퍼티는 전방참조(forward-reference)와 후방참조(backward-reference)가 모두 가능하죠.

<property file="first.properties" />
<property file="second.properties" />

그러나 위와 같이 프로퍼티 파일을 2개 사용할 때, 첫번째 프로퍼티 파일에서 두번째 프로퍼티 파일에 존재하는 프로퍼티는 접근할 수 없어요(전방참조 불가).

그러므로 단일 파일에서만 전방 참조가 가능한 것이죠.

build.properties
# common build properties

net=./net
net.kjunine=${net}/kjunine

net.other=.\\net
net.kjunine.other=${net.other}\\kjunine


first.properties
# first properties file

first=first
first.second=${first}.${second}


second.properties
# second properties file

second=second
second.first=${second}.${first}


build.xml
<project name="Ant Project" default="default" basedir=".">

	<!-- START: PROPERTY -->
	<property file="build.properties" />
	<property file="first.properties" />
	<property file="second.properties" />
	<!-- END: PROPERTY -->

	<!-- START: DEFAULT -->
	<target name="default">
		<echo message="이것은 'Ant Property PropertiesFile'의 빌드 파일이에요." />
		<echo message="앤트(ant) 1.7.0 버전에 최적화되어 있어요." />
		<echo message="사용법:" />
		<echo message="	ant directorydelimiter" />
		<echo message="	ant betweenproperties" />
	</target>
	<!-- END: DEFAULT -->

	<!-- START: DIRECTORY DELIMITER-->
	<target name="directorydelimiter">
		<echo message="net.kjunine = ${net.kjunine}" />
		<echo message="net.kjunine.other = ${net.kjunine.other}" />
		<mkdir dir="${net.kjunine}" />
		<delete dir="${net}" />
		<touch file="${net.kjunine.other}" mkdirs="true" />
		<delete dir="${net}" />
	</target>
	<!-- END: DIRECTORY DELIMITER -->

	<!-- START: BETWEEN PROPERTIES-->
	<target name="betweenproperties">
		<echo message="first = ${first}" />
		<echo message="second = ${second}" />
		<echo message="first.second = ${first.second}" />
		<echo message="second.first = ${second.first}" />
	</target>
	<!-- END: BETWEEN PROPERTIES -->

</project>


사용법:

ant

default:
     [echo] 이것은 'Ant Property PropertiesFile'의 빌드 파일이에요.
     [echo] 앤트(ant) 1.7.0 버전에 최적화되어 있어요.
     [echo] 사용법:
     [echo]  ant directorydelimiter
     [echo]  ant betweenproperties

디렉토리 구분자 예제:

ant directorydelimiter

directorydelimiter:
     [echo] net.kjunine = ./net/kjunine
     [echo] net.kjunine.other = .\net\kjunine
    [mkdir] Created dir: C:\Workspace\Project\Workspace\AntExample\Property\PropertiesFile\net\kjunine
   [delete] Deleting directory C:\Workspace\Project\Workspace\AntExample\Property\PropertiesFile\net
    [touch] Creating C:\Workspace\Project\Workspace\AntExample\Property\PropertiesFile\net\kjunine
   [delete] Deleting directory C:\Workspace\Project\Workspace\AntExample\Property\PropertiesFile\net

프로퍼티 파일 간 참조 예제:

ant betweenproperties

betweenproperties:
     [echo] first = first
     [echo] second = second
     [echo] first.second = first.${second}
     [echo] second.first = second.first

환경:
    Ant 1.7.0

Trackback 0 Comment 0
2008/06/04 02:05

앤트(Ant)에서 사용자별로 다른 프로퍼티 파일을 읽어들이도록 해보아요.

앤트에서 사용자별로 다른 프로퍼티 파일을 읽어들이도록 해 보아요.

쉽게 생각하면 -propertyfile 옵션을 이용하면 될 것 같지요.
하지만 -propertyfile 옵션을 이용해 .properties 파일을 읽어들이면 심각한 문제가 있어요.

그래서 다음과 같이 하면 돼요.

default.user.properties
# default user properties
user.properties=default.user.properties


user1.properties
# user1 properties
user.properties=user1.properties


user2.properties
# user2 properties
user.properties=user2.properties


build.xml
<project name="Ant Project" default="default" basedir=".">

	<!-- START: PROPERTY -->
	<property file="${user.id}.properties" />
	<property file="default.user.properties" />
	<!-- END: PROPERTY -->

	<!-- START: DEFAULT -->
	<target name="default">
		<echo message="이것은 'Ant Project'의 빌드 파일이에요." />
		<echo message="앤트(ant) 1.7.0 버전에 최적화되어 있어요." />
		<echo message="사용법:" />
		<echo message="	ant userdependant" />
		<echo message="	ant -Duser.id=user1 userdependant" />
		<echo message="	ant -Duser.id=user2 userdependant" />
	</target>
	<!-- END: DEFAULT -->

	<!-- START: USER DEPENDANT-->
	<target name="userdependant">
		<echo message="user.id = ${user.id}" />
		<echo message="user.properties = ${user.properties}" />
	</target>
	<!-- END: USER DEPENDANT -->

</project>


사용법을 볼까요?

ant

default:
     [echo] 사용법:
     [echo]  ant userdependant
     [echo]  ant -Duser.id=user1 userdependant
     [echo]  ant -Duser.id=user2 userdependant

디폴트 사용자일 때..

ant userdependant

userdependant:
     [echo] user.id = ${user.id}
     [echo] user.properties = default.user.properties

user.id 프로퍼티가 없으면 build.xml에서 ${user.id}.properties 파일을 읽는 property 태스크는 무시되어요.

사용자 1일 때..

ant -Duser.id=user1 userdependant

userdependant:
     [echo] user.id = user1
     [echo] user.properties = user1.properties

사용자 2일 때..

ant -Duser.id=user2 userdependant

userdependant:
     [echo] user.id = user2
     [echo] user.properties = user2.properties

위와 같이 하면 사용자마다 다른 프로퍼티 파일을 읽을 수 있겠네요.
사용자마다 작업 디렉토리나 서버 설치 디렉토리가 다른 경우 등등에 적용할 수 있을 것 같아요.

환경:
    Ant 1.7.0

Trackback 0 Comment 0