 |
|
난이도 : 중급 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 플래그가 포함된 파일 특성을 보여 주는 화면 캡처
자동으로 생성된 파일의 또 다른 예로는 주석 또는 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
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 빌드 호출하기
대부분의 경우에는 Launch Configuration 마법사의 모든 기본값을 그대로 적용한
채로 빌드 파일을 실행할 수 있다. 그러나 JRE 탭은 예외이다. 사용자 정의 Ant 태스크에서
Eclipse API에 액세스해야 하는 경우에는 Rational Application Developer 및 Eclipse와 동일한 JRE에서
태스크를 실행해야 한다. 그림 8에서는 이를 수행하는 데 필요한 설정을 보여 준다.
Ant 빌드를 Eclipse 빌더로서 자동으로 실행하기 수동으로
Ant 빌드를 실행할 경우에는 파생된 리소스를 삭제할 때 사용자가 모든 기능을 제어할 수 있다.
이에 반해 효율적으로 작업을 수행하기 위해 이 태스크를 자동으로
수행하는 경우도 있다. 예를 들어, Clean을 호출할 때 파생된 리소스도 삭제되도록 하기 위해
이 태스크를 Clean 작업에 연결할 수 있다. 그림 4와 같이 Eclipse의 빌더 목록에
build.xml을 추가하여 이 작업을 수행할 수 있다.
build.xml 파일을 저장해 놓은 프로젝트를 선택한다.
- Properties > Builders를 선택한다.
- New 단추를 클릭한다.
그림 4. New Builder 마법사 호출하기
- Figure 5와 같이 Ant Build 구성 유형을 선택한다.
그림 5. Ant Build 구성 선택하기
이후 단계에서는 Ant Build 구성의 다양한 특성을 설정한다.
- 그림 6과 같이 Main 탭에서 빌더의 이름을 설정한 후
생성된
build.xml 파일의 경로를 지정한다.
그림 6. Main Ant Build 구성 설정하기
- Main 탭에서 필요한 설정을 완료한 후 그림 7과 같이 Targets 탭의 설정을 채운다.
Eclipse 플랫폼에는 이 빌더를 호출해야 하는 시간과 관련된 다음과 같은 여러 가지 옵션이 있다.
- Clean 후
- 모든 수동 빌드 시
- 모든 자동 빌드 시
- Clean 중
그림 7과 같이 이 예제에서는 Clean 중에만 파생된 리소스를
삭제하는 옵션을 사용한다. (build.xml의 기본 대상은 deleteDerived
Ant 태스크이다.) 이 옵션을 사용하는 이유는 Clean 중에만 파생된 리소스를 삭제하면 성능
저하를 방지할 수 있기 때문이다.
- 이를 수행하기 위해 Set Targets 단추를 클릭하고 적합한 항목을 선택한다.
이 기능은 Clean 명령의 일반적인 작업을 수행하는 동시에 생성된
코드가 모두 삭제되었는지도 확인한다.
그림 7. 빌더 대상
Targets 탭에서 설정을 완료한 후에는 JRE 탭으로 이동한다.
- 그림 8과 같이 Run in the same JRE as the workspace 옵션이 선택되어
있는지 확인한다. (Ant 태스크 코드에서 Eclipse API에 액세스하려면 이 옵션을 선택해야 한다.)
그림 8. Ant 빌더의 JRE 구성
- 이제 빌더의 구성을 완료했으므로 Save를 클릭한다. 그림 9와 같이
새로 정의한 빌더가 목록에 표시되어야 한다.
그림 9. 업데이트된 빌더 목록
고려할 사항이 한 가지 더 있다. 이 경우에는 다른 빌더, 컴파일러 등을
실행하기 전에 생성된(파생된) 리소스를 삭제해야 한다.
- 빌더의 호출 순서를 변경하려면 빌더(Delete Derived resources Ant
Builder)를 선택한 후 빌더가 맨 위로 올 때까지 Up 단추를 클릭한다(그림 10 참조). Eclipse는
맨 위부터 차례대로 빌더를 호출한다.
그림 10. 수정된 프로젝트 빌더 호출 순서
동일한 맥락에서 파생된 리소스를 삭제할 범위가 전체 작업 공간일 경우에는
build.xml 파일이 포함된 프로젝트를 다른 모든 프로젝트보다 먼저
빌드해야 한다. 따라서 다른 프로젝트를 빌드하기 전에 작업 공간의 파생된 리소스가 모두 삭제된다.
- 사용자의 프로젝트를 먼저 빌드하기 위해 그림 11과 같이 Window > Preferences >
Workspace > Build Order를 선택하여 프로젝트에 적합한 순서를 할당한다.
그림 11. 작업 공간에서 프로젝트의 빌드 순서 설정
살펴본 내용 이
기사에서는 제품의 기능을 확장할 수 있는 강력하고 유연한 기법을 살펴보았다. 이 기법을 활용하면
팀의 요구 사항에 부합하는 새 목표를 효과적으로 달성할 수 있다.
이 점을 강조하기 위해 이 기사의 참고자료 섹션에서는
이 사용자 정의 Ant 태스크 기술을 사용하여 특정 니즈를 해결하는 다른 애플리케이션에 대한 참조(예: Ant
Tasks to import and export files 및 Automating Modeling Compare Merge)를 제공한다.
감사의 인사 이
기사를 검토해 준 IBM Toronto Lab의 Bob Dytyniak에게 감사의 뜻을 전한다.
다운로드 하십시오 | 설명 | 이름 | 크기 | 다운로드 방식 |
|---|
| Sample Ant task for this article | DeleteDerivedAttachments.zip | 6KB | HTTP |
|---|
참고자료 교육
제품 및 기술 얻기
-
IBM Rational 시험판 소프트웨어를 다운로드하자.
-
IBM
시험판 제품을 다운로드하여 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및
미들웨어 제품을 사용하자.
- IBM 시험판 제품을
다운로드하여 DB2®, Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및
미들웨어 제품을 사용하자.
토론
필자소개  | 
|  | Robert Weisz는 IBM Toronto Lab의 Rational Premium Support 팀 소속으로 Eclipse 및 Rational 애플리케이션 개발자를 지원하고 있다. |
기사에 대한 평가
 |
| 이 문서 북마킹 하기
|
|