IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  Rational | 자바  >

사용자 정의 Ant 태스크를 사용해야 하는 이유와 사용 방법

Ant 태스크에서 Eclipse API를 호출하여 IBM Rational Application Developer의 기능을 확장하자

developerWorks
문서 옵션

Get Adobe® Reader®

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

토론

샘플 코드

영어원문

영어원문


제안 및 의견
피드백

난이도 : 중급

Robert Weisz, Advisory Software Engineer, IBM Toronto Lab

원문 게재일 : 2009 년 3 월 24 일
번역 게재일 : 2009 년 5 월 12 일

이 기사에서는 Eclipse 플랫폼 기반의 IBM Rational® Application Developer에서 사용자 정의 Ant 태스크를 생성하는 방법에 대해 설명합니다. 또한 이 방법을 사용해야 하는 이유에 대해서도 설명합니다. 이 기사의 예제에서는 IDE(Integrated Development Environment)에서 현재 사용할 수 없는 유용한 기능인 사용자 정의 Ant 태스크를 제공합니다. 이 태스크는 derived로 표시된 모든 생성된 파일을 삭제하는 데 사용할 수 있습니다.

소개

IBM Rational® Application Developer의 기반인 Eclipse 플랫폼에서는 모든 Eclipse API에 액세스하여 해당 확장점을 사용할 수 있는 고유 플러그인(참고자료 참조)을 생성하거나 외부 도구를 호출(예를 들어, Javadoc 또는 Ant 스크립트를 고유 빌더로 호출, 참고자료 참조)하는 기능을 제공하는 등의 여러 가지 방법으로 플랫폼의 기능을 확장할 수 있다.

이 기사의 예제에서는 위 두 가지 방법을 함께 사용한다. 즉, Eclipse API를 사용하는 사용자 정의 Ant 태스크가 포함된 플러그인을 생성한 후 Ant 스크립트에서 이 Ant 태스크를 호출한다. 기사의 후반부에서 설명하듯이 사용자는 GUI에서 스크립트를 수동으로 호출하거나 Rational Application Developer 및 Eclipse 빌드 동안 호출할 빌더 목록에 스크립트를 추가할 수 있다. Ant 태스크는 Rational Application Developer GUI 또는 명령행(헤드리스)에서 실행할 수 있기 때문에 일괄 처리, 자동 또는 야간 빌드에 기능을 추가할 때 매우 유용하게 사용할 수 있다.

첨부된 예제에 대한 배경 설명

Eclipse 규칙에 따라 자동으로 생성된 모든 아티팩트에는 derived 플래그가 표시된다(참고자료 참조). 그림 1과 같이 derived로 표시된 파일의 가장 일반적인 예는 컴파일된 Java™ 클래스 파일(*.class)이다.


그림 1. Derived 플래그가 포함된 파일 특성을 보여 주는 화면 캡처
derived 선택란 매개변수

자동으로 생성된 파일의 또 다른 예로는 주석 또는 WSDL(Web Services Description Language) 파일(예: 웹 서비스 클라이언트의 경우)에서 생성될 수 있는 Java 소스 파일(*.java)이 있다. 또한 자동으로 생성된 아티팩트의 예로는 애플리케이션을 IBM WebSphere® Application Server(또는 다른 서버)에 전개하는 동안 ejbDeploy에 의해 생성되는 EJB(Enterprise JavaBeans™) 스텁이 있다.

이 예제의 핵심은 이러한 생성된 파일의 대부분이 Clean 빌드(Project > Clean 메뉴 사용) 중에 삭제되지 않는다는 것이다. 이는 Clean 명령이 대개 출력 폴더를 삭제하지만 생성된 파일은 출력 폴더에 저장되지 않기 때문이다.

Clean 명령이 생성된 소스 파일을 삭제하지 않을 경우 얻을 수 있는 장점은 대부분의 경우 자동으로 생성된 소스 코드를 다시 생성하지 않아도 되기 때문에 성능 저하를 방지할 수 있다는 것이다.

전체(예: 야간) 빌드를 수행할 경우 얻을 수 있는 장점도 있다. 원래 소스 파일(예: WSDL 파일) 또는 주석이 있는 파일(자동 생성의 기반이 되는 파일) 중 일부가 수정된 경우 전체 빌드를 수행할 수 있다. 이러한 경우에는 이전에 생성된 파일을 남겨 두지 않기 위해 생성된 파일도 함께 삭제하는 것이 좋다. 이렇게 하는 이유는 남아 있는 파일로 인해 컴파일 오류와 런타임 오류를 비롯하여 모든 종류의 찾기 어려운 문제가 발생할 수 있기 때문이다.

현실적으로 생각해 보면 야간 빌드의 경우 각 빌드가 새 작업 공간에서 발생하면 전체 빌드를 쉽게 수행할 수 있다. 즉, 기존 작업 공간을 먼저 삭제한 후 새 작업 공간을 시작하고 소스 제어 시스템 등에서 다양한 프로젝트를 체크아웃하여 새 작업 공간을 채운다. 이 방법은 자동으로 생성된 파일이 소스 제어 시스템에 우선적으로 체크인되지 않는다고 가정한다. 실제로 derived로 표시된 파일은 소스 제어 시스템에 체크인되지 않는다(파생된 리소스 참조).

이에 반해 개별 개발자의 경우에는 새 작업 공간에서 시작하는 이 방법을 사용할 수 있기는 하지만 시간이 많이 걸리기 때문에 큰 효과를 얻을 수 없다. 이 예제는 사용자 정의 Ant 태스크를 사용하여 derived로 표시된 파일을 모두 삭제하는 기능을 수행한다. 이 태스크는 GUI 또는 명령행에서 Ant 빌드 중에 호출할 수 있다. 이 새로운 Ant 태스크는 Clean 명령을 통해 삭제된 파일 외에 파생된 모든 파일을 삭제하여 현재의 Clean 명령을 보완한다.

이 구현을 살펴보기 전에 한 가지 주의할 사항이 있다. derived 플래그의 사용법이 Eclipse에 명확하게 정의되어 있기는 하지만 Eclipse 기반의 제품을 만든 모든 다양한 제품 그룹에서 이 플래그의 사용법을 실제로 어떻게 구현 또는 해석했는지는 아무도 알 수 없다. 다시 말해서, derived로 표시되지 않아야 하는 파일이 derived로 표시되어 이 Ant 태스크에 의해 삭제되는 경우가 발생할 수 있다. 또한 derived로 표시되어야 하는 파일이 derived로 표시되지 않아서 삭제되지 않는 경우도 발생할 수 있다. 참고자료 섹션에 소개된 Eclipse bugzilla 126354 기사에서 Clean이 파생된 리소스도 삭제해야 하는지 여부에 대한 주제를 다룬 기존 논의를 참조할 수 있다.





위로


파생된 리소스 삭제: 코드

다음 코드는 JAR(Java archive) 통합 단계를 거쳐서 Ant 태스크 플러그인으로 패키징되기 전에 Eclipse Java 프로젝트로 개발되었다. Listing 1에서는 Eclipse API를 사용하여 작업 공간에서 derived로 표시된 리소스를 재귀적으로 검색한 후 삭제하는 관련 코드 부분을 보여 준다. 검색 및 삭제 작업은 이 Ant 태스크의 가장 중요한 작업이다.

참고:
샘플 코드는 Rational Application Developer V7(Eclipse V3.2 기반)에서 테스트되었다.

소스 코드를 포함한 전체 코드는 하나의 .zip 파일로 패키징되어 있으며(다운로드 영역의 DeleteDerivedAttachments.zip 참조) 기존 Rational Application Developer 및 Eclipse 설치에 Eclipse 플러그인으로 전개할 수 있다. 그렇게 하려면 DeleteDerivedAntTaskPlugin_1.0.0.jar을 Rational Application Developer 설치 디렉토리 /SDP70/plugins 폴더에 끌어 놓으면 된다. 이 .zip 파일에는 나중에 설명할 build.xml 파일도 있다.

Listing 1의 코드에서는 다음 두 가지 가능성을 고려한다.

  • 현재 프로젝트(Ant 스크립트 build.xml 파일이 있는 프로젝트)의 파생된 리소스만 삭제
  • 전체 작업 공간의 파생된 리소스 삭제

build.xml 파일 내에서 선택할 수 있으며 기본값은 현재 프로젝트 범위이다. 이에 대해서는 나중에 설명한다.


Listing 1. 파생된 리소스 검색 및 삭제하기
/**
 * Performs the "derived resources" deletion.
 *
 * @exception BuildException thrown if a problem occurs during execution.
 */
public void execute() throws BuildException
{
  log = ResourcesPlugin.getPlugin().getLog();
  IProject[] project = null;
  IProject currentProject = null;

  IWorkspace workspace = ResourcesPlugin.getWorkspace();
  IWorkspaceRoot  root = workspace.getRoot();
	
  if (cleanWorkspace)  // delete derived resources in the whole workspace
  {
    System.out.println("DeleteDerivedResourcesAntTask.execute()-
                                                clean all the workspace");
    project = root.getProjects();
    int length = project.length;
    for (int i = 0; i < length; i++)
    {
      if (project[i].isOpen())
      {
        System.out.println("delete all derived resources in project: " +
                                                          project[i].getName());
        try
        {
          IResource[] resourcesInProject = project[i].members();
          int projectMembers = resourcesInProject.length;
          for (int j = 0; j < projectMembers; j++)
          {
            try
            {							
              if (resourcesInProject[j].exists())
              {
                deleteAllDerivedResources(resourcesInProject[j]);
              }
            }
            catch (CoreException e)
            {
              e.printStackTrace(System.out);
            }						
          }					
        }
        catch (CoreException e)
        {
          e.printStackTrace(System.out);
          System.out.println("CoreException reading project members");
        }						
      }				
    }
  }
  else // delete derived resources only in the current project
  {
    antProject = getProject();
    baseDir = antProject.getBaseDir().getName();
    currentProject = root.getProject(baseDir);
    if (currentProject.isOpen())
    {
      try
      {
        IResource[] resourcesInCurrentProject = currentProject.members();
        int currentProjectMembers = resourcesInCurrentProject.length;
        for (int j = 0; j < currentProjectMembers; j++)
        {
          try
          {							
            if (resourcesInCurrentProject[j].exists())
            {
              deleteAllDerivedResources(resourcesInCurrentProject[j]);
            }
          }
          catch (CoreException e)
          {
            e.printStackTrace(System.out);
          }						
        }					
      }
      catch (CoreException e)
      {
        e.printStackTrace(System.out);
      }
    }
  }
}

/**
 * Delete a resource (file or folder) if it is derived.
 * (By definition, anything inside a derived folder is derived too.)
 *  If it is a non-derived folder, keep on recursing down the tree looking
 *  for derived resources.
 */	
public static void deleteAllDerivedResources(final IResource resource)
throws CoreException
{
  if (resource.isDerived())  // only Files and Folders can be derived.
  {                          //  Projects cannot be marked derived.
    deleteResource(resource);
  }
  else
  {
    if( resource.getType() == IResource.FOLDER )
    {
      IResource[] members = ((IFolder)resource).members();
      for( int i=0, length=members.length; i<length; i++ )
      {
        deleteAllDerivedResources(members[i]);
      }
    }		
  }
}
                    




위로


Ant 태스크가 포함된 플러그인 생성하기

먼저 JAR 파일로 패키징되어 있는 Ant 태스크 구현을 포함할 매우 간단한 플러그인을 생성해야 한다. 각 플러그인에는 Eclipse 프레임워크에 대해 플러그인을 정의하고 JAR 라이브러리 파일을 가리키는 plugin.xml이 있어야 한다. 이 경우 Listing 2에서 보여 주는 plugin.xml 파일은 Ant 태스크를 선언하는 데도 사용할 수 있다.

Eclipse Ant 태스크 스펙(참고자료 참조)에 따라 새로운 사용자 정의 Ant 태스크를 선언해야 한다.

The plugin.xml 파일


Listing 2. plugin.xml 파일의 컨텐츠
 
<?xml version="1.0" encoding="UTF-8"?>
        <?eclipse version="3.2"?> 
        <plugin> 
            <extension id="deleteDerived" name="deleteDerivedResources"
                point="org.eclipse.ant.core.antTasks"> 
            <antTask name="deleteDerived"
                class="com.rw.sample.DeleteDerivedResourcesAntTask" 
                library="antLib/AntLib.jar" headless="true" eclipseRuntime="true"/> 
            </extension>
        </plugin> 

예기치 않은 문제가 발생하지 않은 경우에는 새 Ant 태스크가 Eclipse에 인식되어야 한다. 이 태스크는 그림 2와 같이 Window > Preferences > Ant > Runtime > Tasks 메뉴에도 표시되어야 한다.

참고: Ant 태스크 라이브러리와 플러그인의 JAR 파일이 서로 다른 위치에 있어야 한다는 점에 주의해야 한다. AntLib.jar 파일은 클래스 로드 문제를 방지하기 위해 플러그인의 서브폴더에 있다. 참고자료 섹션의 Eclipse bugzilla 34466에 따라 플러그인의 classloader 대신 Ant classloader를 사용하여 Ant 태스크를 로드할 수 있다.


그림 2. 새로 생성된 deleteDerived Ant 태스크를 보여 주는 Eclipse
새로 생성된 deleteDerived 항목을 보여 주는 목록

build.xml 파일

Ant 빌드를 실행하려면 Ant 런타임을 실행하는 데 사용할 Ant 스크립트가 있어야 한다. 이 파일의 이름은 일반적으로 build.xml이다. Ant 스크립트는 .xml 파일이다. 예를 들어, Listing 3에서는 새로 생성된 사용자 정의 Ant 태스크를 호출하는 데 사용할 build.xml을 보여 준다. 이 build.xml 파일은 삭제할 파생된 리소스가 있는 프로젝트의 루트(.project 파일이 있는 프로젝트 폴더)에 배치해야 한다.

예제 Ant 태스크의 유연성을 높이기 위해 cleanCurrentProjectOnly 옵션을 추가한다. 이 옵션이 true일 경우에는 build.xml 스크립트 파일이 배치된 프로젝트에 있는 파생된 리소스만 삭제된다. 그렇지 않고 false일 경우에는 전체 작업 공간에 있는 파생된 리소스가 삭제된다.


Listing 3. build.xml 파일의 컨텐츠
 
<?xml version="1.0" encoding="UTF-8" ?>
    <project name="customAntTaskBuild" default="deleteDerivedTarget" basedir=".">
        <taskdef name="deleteDerived"
        classname="com.rw.sample.DeleteDerivedResourcesAntTask"> 
        </taskdef>
        <target name="deleteDerivedTarget" cleanCurrentProjectOnly="true" />
        </target> 
        </project> 

수동으로 Ant 빌드 실행하기

이제 build.xml 파일이 생성되었으므로 이 파일을 실행하여 작동하는 방법을 확인할 수 있다. 수동으로 실행하려면 그림 3과 같이 build.xml 파일을 마우스 오른쪽 단추로 클릭한 다음 Run As > Ant Build를 선택한다.


그림 3. 수동으로 Ant 빌드 호출하기
옵션 메뉴를 사용하여 ant 빌드 실행하기

대부분의 경우에는 Launch Configuration 마법사의 모든 기본값을 그대로 적용한 채로 빌드 파일을 실행할 수 있다. 그러나 JRE 탭은 예외이다. 사용자 정의 Ant 태스크에서 Eclipse API에 액세스해야 하는 경우에는 Rational Application Developer 및 Eclipse와 동일한 JRE에서 태스크를 실행해야 한다. 그림 8에서는 이를 수행하는 데 필요한 설정을 보여 준다.





위로


Ant 빌드를 Eclipse 빌더로서 자동으로 실행하기

수동으로 Ant 빌드를 실행할 경우에는 파생된 리소스를 삭제할 때 사용자가 모든 기능을 제어할 수 있다.

이에 반해 효율적으로 작업을 수행하기 위해 이 태스크를 자동으로 수행하는 경우도 있다. 예를 들어, Clean을 호출할 때 파생된 리소스도 삭제되도록 하기 위해 이 태스크를 Clean 작업에 연결할 수 있다. 그림 4와 같이 Eclipse의 빌더 목록에 build.xml을 추가하여 이 작업을 수행할 수 있다.

  1. build.xml 파일을 저장해 놓은 프로젝트를 선택한다.
  2. Properties > Builders를 선택한다.
  3. New 단추를 클릭한다.

그림 4. New Builder 마법사 호출하기
build 마법사 대화 상자에서 새 프로젝트 선택하기


  1. Figure 5와 같이 Ant Build 구성 유형을 선택한다.

그림 5. Ant Build 구성 선택하기
Choose configuration type 대화 상자에서 Ant Build 선택하기

이후 단계에서는 Ant Build 구성의 다양한 특성을 설정한다.

  1. 그림 6과 같이 Main 탭에서 빌더의 이름을 설정한 후 생성된 build.xml 파일의 경로를 지정한다.

그림 6. Main Ant Build 구성 설정하기
Properties 대화 상자 스크린샷

  1. Main 탭에서 필요한 설정을 완료한 후 그림 7과 같이 Targets 탭의 설정을 채운다.

Eclipse 플랫폼에는 이 빌더를 호출해야 하는 시간과 관련된 다음과 같은 여러 가지 옵션이 있다.

  • Clean 후
  • 모든 수동 빌드 시
  • 모든 자동 빌드 시
  • Clean 중

그림 7과 같이 이 예제에서는 Clean 중에만 파생된 리소스를 삭제하는 옵션을 사용한다. (build.xml의 기본 대상은 deleteDerived Ant 태스크이다.) 이 옵션을 사용하는 이유는 Clean 중에만 파생된 리소스를 삭제하면 성능 저하를 방지할 수 있기 때문이다.

  1. 이를 수행하기 위해 Set Targets 단추를 클릭하고 적합한 항목을 선택한다.

이 기능은 Clean 명령의 일반적인 작업을 수행하는 동시에 생성된 코드가 모두 삭제되었는지도 확인한다.


그림 7. 빌더 대상
Clean 프로세스의 기본 대상을 보여 주는 Properties 대화 상자

Targets 탭에서 설정을 완료한 후에는 JRE 탭으로 이동한다.

  1. 그림 8과 같이 Run in the same JRE as the workspace 옵션이 선택되어 있는지 확인한다. (Ant 태스크 코드에서 Eclipse API에 액세스하려면 이 옵션을 선택해야 한다.)

그림 8. Ant 빌더의 JRE 구성
JRE 런타임 옵션을 보여 주는 Properties 대화 상자

  1. 이제 빌더의 구성을 완료했으므로 Save를 클릭한다. 그림 9와 같이 새로 정의한 빌더가 목록에 표시되어야 한다.

그림 9. 업데이트된 빌더 목록
빌더 목록을 보여 주는 Properties 대화 상자

고려할 사항이 한 가지 더 있다. 이 경우에는 다른 빌더, 컴파일러 등을 실행하기 전에 생성된(파생된) 리소스를 삭제해야 한다.

  1. 빌더의 호출 순서를 변경하려면 빌더(Delete Derived resources Ant Builder)를 선택한 후 빌더가 맨 위로 올 때까지 Up 단추를 클릭한다(그림 10 참조). Eclipse는 맨 위부터 차례대로 빌더를 호출한다.

그림 10. 수정된 프로젝트 빌더 호출 순서
리소스 삭제 빌더를 보여 주는 Properties 대화 상자

동일한 맥락에서 파생된 리소스를 삭제할 범위가 전체 작업 공간일 경우에는 build.xml 파일이 포함된 프로젝트를 다른 모든 프로젝트보다 먼저 빌드해야 한다. 따라서 다른 프로젝트를 빌드하기 전에 작업 공간의 파생된 리소스가 모두 삭제된다.

  1. 사용자의 프로젝트를 먼저 빌드하기 위해 그림 11과 같이 Window > Preferences > Workspace > Build Order를 선택하여 프로젝트에 적합한 순서를 할당한다.

그림 11. 작업 공간에서 프로젝트의 빌드 순서 설정
작업 공간 빌드 순서를 보여 주는 Preferences 대화 상자




위로


살펴본 내용

이 기사에서는 제품의 기능을 확장할 수 있는 강력하고 유연한 기법을 살펴보았다. 이 기법을 활용하면 팀의 요구 사항에 부합하는 새 목표를 효과적으로 달성할 수 있다.

이 점을 강조하기 위해 이 기사의 참고자료 섹션에서는 이 사용자 정의 Ant 태스크 기술을 사용하여 특정 니즈를 해결하는 다른 애플리케이션에 대한 참조(예: Ant Tasks to import and export files 및 Automating Modeling Compare Merge)를 제공한다.




위로


감사의 인사

이 기사를 검토해 준 IBM Toronto Lab의 Bob Dytyniak에게 감사의 뜻을 전한다.





위로


다운로드 하십시오

설명이름크기다운로드 방식
Sample Ant task for this articleDeleteDerivedAttachments.zip6KBHTTP
다운로드 방식에 대한 정보


참고자료

교육

제품 및 기술 얻기
  • IBM Rational 시험판 소프트웨어를 다운로드하자.

  • IBM 시험판 제품을 다운로드하여 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및 미들웨어 제품을 사용하자.

  • IBM 시험판 제품을 다운로드하여 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및 미들웨어 제품을 사용하자.

토론


필자소개

Photo of Robert Weisz

Robert Weisz는 IBM Toronto Lab의 Rational Premium Support 팀 소속으로 Eclipse 및 Rational 애플리케이션 개발자를 지원하고 있다.




기사에 대한 평가


보다 나은 서비스를 제공하기 위함이오니 잠시 짬을 내어 이 양식을 제출하여 주십시오.



 


 


 


이 문서 북마킹 하기

mar.gar.in mar.gar.in naver naver eolin eolin del.icio.us del.icio.us





위로


IBM, Rational 및 IBM 로고는 미국 또는 기타 국가에서 사용되는 International Business Machines Corporation의 상표이다. Java 및 모든 Java 기반 상표와 로고는 미국 또는 기타 국가에서 사용되는 Sun Microsystems, Inc.의 상표이다. 기타 회사, 제품, 및 서비스명은 다른 상표나 서비스 마크일 수 있습니다.

developerWorks 콘텐트를 다른 사이트에 전재하기:
developerWorks 콘텐트에 대한 저작권은 IBM에 있습니다. IBM의 서면 허가나 원본 저자의 허락이 없이는 전재를 금합니다. 저희 콘텐트를 전재하시려면 IBM developerWorks 담당자 에게 문의하십시오.
    IBM 소개 개인정보 보호정책 문의