์๋ฐ ๋น๋ ์๋ํ ๋๊ตฌ ์์ ๊ฐ์ด๋: build.xml ํ์คํฌ(javac, jar, war, copy, delete), ํ๊ฒ ์์กด ๊ด๊ณ(depends), ํ๋กํผํฐ ์นํ, Apache Ivy ์์กด์ฑ ๊ด๋ฆฌ ๋ฐ JUnit ํ
์คํธ ์๋ํ
## 1. Apache Ant ์ค์น & ํ๊ฒฝ ๊ตฌ์ฑ ๊ฐ์ด๋ (Installation)
### ๐ป ์์คํ
์ค์น ๋ฐ ์คํ ์๊ตฌ์ฌ์ (System Requirements)
| ํญ๋ชฉ | ์ต์ ์ฌ์ (Minimum) | ๊ถ์ฅ ์ฌ์ (Recommended) | ์ฐธ๊ณ ๋ฐ ๋น๊ณ |
| :--- | :--- | :--- | :--- |
| **์ด์์ฒด์ (OS)** | Windows 10/11, Linux (Ubuntu, RHEL, Alpine), macOS | Ubuntu 22.04 / 24.04 LTS, macOS, Windows 11 | Java(JVM)๊ฐ ๊ตฌ๋๋๋ ๋ชจ๋ ํฌ๋ก์ค ํ๋ซํผ ํ๊ฒฝ |
| **CPU** | 1 ์ฝ์ด ์ด์ (x86_64 / ARM64) | 2 ์ฝ์ด ~ 4 ์ฝ์ด ์ด์ | ์ปดํ์ผ ๋ฐ ํจํค์ง ์ ๋ฉํฐ์ค๋ ๋ ํฌํฌ ์ง์ |
| **๋ฉ๋ชจ๋ฆฌ (RAM)** | 512 MB ์ด์ (JVM ํ 256 MB) | 2 GB ~ 4 GB ์ด์ | ๋๊ท๋ชจ ๋ ๊ฑฐ์ ์ํฐํ๋ผ์ด์ฆ ๋ชจ๋ ์ปดํ์ผ ์ ์ถฉ๋ถํ ํ ํ๋ณด ํ์ (`ANT_OPTS="-Xmx2g"`) |
| **๋์คํฌ (Storage)** | 200 MB ์ด์์ ์ฌ์ ๊ณต๊ฐ | 5 GB ~ 10 GB ์ด์์ SSD | ๋น๋ ์ฐ์ถ๋ฌผ(classes, JAR, WAR) ๋ฐ ์ธ๋ถ ์์กด์ฑ(Ivy ์บ์) |
| **๋คํธ์ํฌ / ๋ฐํ์** | Java SE 8, 11, 17, 21 LTS & Ant 1.10.x | OpenJDK 17 LTS ์ด์ | `JAVA_HOME` ๋ฐ `ANT_HOME` ํ๊ฒฝ ๋ณ์ ์ค์ ํ์ |
---
### ๐ ์ด์์ฒด์ ๋ณ ์ค์น ๋ช
๋ น์ด
```bash
# ๐ง [1] Ubuntu / Debian ์ค์น (Ant ์ฝ์ด ๋ฐ ์ต์
๋ผ์ด๋ธ๋ฌ๋ฆฌ)
sudo apt update
sudo apt install -y ant ant-optional
# ๋ฒ์ ๋ฐ ์ค์น ํ์ธ
ant -version
# ์ถ๋ ฅ: Apache Ant(TM) version 1.10.14 compiled on ...
# ๐ง [2] RHEL / Rocky Linux 9 / AlmaLinux ์ค์น
sudo dnf install -y epel-release
sudo dnf install -y ant ant-lib
# ๐ [3] macOS Homebrew ์ค์น
brew install ant
# ๐ช [4] Windows ์ค์น (winget ๋๋ ์๋ ๋ฐ์ด๋๋ฆฌ ์ค์น)
winget install Apache.Ant
# ํ๊ฒฝ ๋ณ์ ์๋ ์ค์ (Linux/macOS ~/.bashrc ๋๋ ~/.zshrc)
export ANT_HOME=/opt/ant
export PATH=$PATH:$ANT_HOME/bin
export ANT_OPTS="-Xms256m -Xmx1024m -Dfile.encoding=UTF-8"
```
---
## 2. Apache Ant ์ํคํ
์ฒ & ๋ฉํ ๋ชจ๋ธ (Mental Model)
Apache Ant๋ **๋ช
์์ ์ ์ฐจ ์งํฅ(Procedural & Task-driven)** ๋น๋ ๋๊ตฌ์
๋๋ค. ์ ํํ๋ ๋ผ์ดํ์ฌ์ดํด์ ๊ฐ์ ํ๋ Maven๊ณผ ๋ฌ๋ฆฌ, ๊ฐ๋ฐ์๊ฐ XML(`build.xml`) ํ์ผ ์์ ์ปดํ์ผ, ๋ณต์ฌ, ์์ถ ๋ฑ ๊ฐ ๋จ๊ณ(Task)์ ์์
์์(Target depends)๋ฅผ ์์ ์์ฌ๋ก ์ ์ํ ์ ์์ต๋๋ค.
### ๐งญ Ant ๋น๋ ์คํ ํ๋ฆ (Build Execution Model)
```
build.xml
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ <project name="MyApp" default="dist" basedir="."> โ
โ โ
โ [1] Properties & Path ์ ์ธ โ
โ โโ <property name="src.dir" value="src"/> โ
โ โโ <property name="build.dir" value="build"/> โ
โ โโ <path id="project.classpath">...</path> โ
โ โ
โ [2] Target ์์กด์ฑ ๊ทธ๋ํ (Dependency Directed Acyclic Graph)โ
โ โ
โ [clean] โโ> (๋๋ ํ ๋ฆฌ ์ญ์ ) โ
โ โ
โ [init] โโ> (build ๋๋ ํ ๋ฆฌ ์์ฑ) โ
โ โฒ โ
โ โ depends โ
โ [compile] โ> (<javac> ์๋ฐ ์์ค ์ปดํ์ผ) โ
โ โฒ โ
โ โ depends โ
โ [dist] โโโ> (<jar> ์คํ ๊ฐ๋ฅํ JAR ํจํค์ง) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
$ ant dist ์คํ โ
โผ
[init] โโ> [compile] โโ> [dist] (์์๋๋ก ์คํ)
```
### โ๏ธ Ant vs Maven vs Gradle ํต์ฌ ๋น๊ต
| ๋น๊ต ํญ๋ชฉ | Apache Ant | Apache Maven | Gradle |
| :--- | :--- | :--- | :--- |
| **์ค์ ๋ฐฉ์** | ์ ์ฐจ์ XML (`build.xml`) | ์ ์ธ์ XML (`pom.xml`) | ์ฝ๋ํ DSL (`build.gradle` Groovy / Kotlin) |
| **๋ผ์ดํ์ฌ์ดํด** | ๊ฐ๋ฐ์๊ฐ ์ง์ ์ ์ (์์ ๋ ์ต์) | ์๊ฒฉํ ํ์ค ๋ผ์ดํ์ฌ์ดํด (validate -> compile -> test -> package) | ์ ์ฐํ ํ์คํฌ DAG (Directed Acyclic Graph) |
| **์์กด์ฑ ๊ด๋ฆฌ** | ๊ธฐ๋ณธ ๋ด์ฅ ์์ (์๋ lib ํด๋ ๋๋ **Apache Ivy** ์ฐ๋) | Maven Central ์ ์ฅ์ ๊ธฐ๋ณธ ๋ด์ฅ | Maven / Ivy ์ ์ฅ์ ์๋ฒฝ ํธํ |
| **์ ํฉํ ํ๊ฒฝ** | ๋ ๊ฑฐ์ ์ํฐํ๋ผ์ด์ฆ ์์คํ
, ๊ณ ์ ํ ๋น๋ ์ ์ฐจ๊ฐ ๋ณต์กํ ์ปค์คํ
ํ๊ฒฝ | ํ์ค์ ์ธ ์๋ฐ/์คํ๋ง ํ๋ก์ ํธ, ๊ด๋ก ๊ธฐ๋ฐ ๊ฐ๋ฐ | ๋๊ท๋ชจ ๋ฉํฐ ๋ชจ๋, ์๋๋ก์ด๋, ์ด๊ณ ์ ์ฆ๋ถ ๋น๋ |
---
## 3. [์ด๋ณด์ 1๋จ๊ณ] 3๋ถ ํฌ๋ก์๋: ๋จ๋
์๋ฐ ํ๋ก์ ํธ ๋น๋
ํ์ค์ ์ธ ์๋ฐ ์์ค ์ฝ๋๋ฅผ ์ปดํ์ผํ๊ณ ์คํ ๊ฐ๋ฅํ JAR ํ์ผ๋ก ํจํค์งํ๋ ์ต์ `build.xml` ์์ ์
๋๋ค.
### ๐ ํ๋ก์ ํธ ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ
```text
my-ant-project/
โโโ build.xml
โโโ src/
โโโ com/
โโโ lucky/
โโโ App.java
```
### โ ์๋ฐ ์์ค ์ฝ๋ (`src/com/lucky/App.java`)
```java
package com.lucky;
public class App {
public static void main(String[] args) {
System.out.println("๐ Hello from Apache Ant Build System!");
}
}
```
### ๐ ์ต์ ๋์ ๋น๋ ํ์ผ (`build.xml`)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="LuckyAntApp" default="run" basedir=".">
<description>Apache Ant ํฌ๋ก์๋ ๋น๋ ์คํฌ๋ฆฝํธ</description>
<!-- 1. ๊ฒฝ๋ก ๋ฐ ํ๋กํผํฐ ์ ์ -->
<property name="src.dir" location="src"/>
<property name="build.dir" location="build"/>
<property name="classes.dir" location="${build.dir}/classes"/>
<property name="dist.dir" location="${build.dir}/dist"/>
<property name="main.class" value="com.lucky.App"/>
<!-- 2. ์ด๊ธฐํ ํ์คํฌ: ๋น๋ ๊ฒฐ๊ณผ ๋๋ ํฐ๋ฆฌ ์์ฑ -->
<target name="init" description="๋น๋ ๋๋ ํฐ๋ฆฌ ์ด๊ธฐํ">
<mkdir dir="${classes.dir}"/>
<mkdir dir="${dist.dir}"/>
</target>
<!-- 3. ์ปดํ์ผ ํ์คํฌ: javac ์คํ -->
<target name="compile" depends="init" description="์๋ฐ ์์ค ์ฝ๋ ์ปดํ์ผ">
<javac srcdir="${src.dir}"
destdir="${classes.dir}"
includeantruntime="false"
source="17"
target="17"
encoding="UTF-8"/>
</target>
<!-- 4. ํจํค์ง ํ์คํฌ: ์คํ ๊ฐ๋ฅํ JAR ์์ฑ -->
<target name="jar" depends="compile" description="์คํ ๊ฐ๋ฅํ JAR ํ์ผ ์์ฑ">
<jar destfile="${dist.dir}/lucky-app.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="Built-By" value="LuckyTechWorld"/>
</manifest>
</jar>
</target>
<!-- 5. ์คํ ํ์คํฌ: ์๋ฐ ๋ฉ์ธ ํด๋์ค ์คํ -->
<target name="run" depends="jar" description="๋น๋๋ ์ ํ๋ฆฌ์ผ์ด์
์คํ">
<java jar="${dist.dir}/lucky-app.jar" fork="true"/>
</target>
<!-- 6. ํด๋ฆฐ ํ์คํฌ: ๋น๋ ๋๋ ํฐ๋ฆฌ ์ญ์ -->
<target name="clean" description="๋น๋ ์ฐ์ถ๋ฌผ ์ ์ฒด ์ญ์ ">
<delete dir="${build.dir}"/>
</target>
</project>
```
### ๐งช ๋น๋ ๋ฐ ์คํ ๋ช
๋ น์ด
```bash
# ๊ธฐ๋ณธ ํ๊ฒ(run) ์คํ (init -> compile -> jar -> run ์์ฐจ ์คํ)
ant
# ํน์ ํ๊ฒ๋ง ๋จ๋
์คํ
ant compile
ant jar
ant clean
```
#### ๐ฅ๏ธ ์ฝ์ ์ถ๋ ฅ ๊ฒฐ๊ณผ (Console Output)
```text
Buildfile: /workspace/my-ant-project/build.xml
init:
[mkdir] Created dir: /workspace/my-ant-project/build/classes
[mkdir] Created dir: /workspace/my-ant-project/build/dist
compile:
[javac] Compiling 1 source file to /workspace/my-ant-project/build/classes
jar:
[jar] Building jar: /workspace/my-ant-project/build/dist/lucky-app.jar
run:
[java] ๐ Hello from Apache Ant Build System!
BUILD SUCCESSFUL
Total time: 1 second
```
---
## 4. [2๋จ๊ณ] ํต์ฌ ๊ธฐ๋ฅ: ํ๋กํผํฐ, ํด๋์คํจ์ค & ๋ด์ฅ ํ์คํฌ
### โ๏ธ 1. ํ๋กํผํฐ(Properties)์ ์ธ๋ถ ์ค์ ํ์ผ ์ฐ๋
ํ๋กํผํฐ๋ ํ ๋ฒ ๊ฐ์ด ์ค์ ๋๋ฉด **๋ถ๋ณ(Immutable)**์ ํน์ฑ์ ๊ฐ์ง๋๋ค.
```xml
<!-- 1) ์ง์ ๊ฐ ์ง์ -->
<property name="app.version" value="1.0.0"/>
<!-- 2) ์ธ๋ถ ํ๋กํผํฐ ํ์ผ ๋ก๋ (build.properties) -->
<property file="build.properties"/>
<!-- 3) ์์คํ
ํ๊ฒฝ ๋ณ์ ์ ๊ทผ (์ ๋์ฌ env ์ค์ ) -->
<property environment="env"/>
<echo message="ํ์ฌ JAVA_HOME ๊ฒฝ๋ก: ${env.JAVA_HOME}"/>
<echo message="ํ์ฌ ์ฌ์ฉ์ ๊ณ์ : ${user.name}"/>
<!-- 4) ํ์์คํฌํ ์๋ ์์ฑ -->
<tstamp>
<format property="build.time" pattern="yyyy-MM-dd HH:mm:ss" locale="ko,KR"/>
</tstamp>
<echo message="๋น๋ ์์ฑ ์ผ์: ${build.time}"/>
```
---
### ๐ฆ 2. ํด๋์คํจ์ค(Classpath) ๋ฐ ๋ฆฌ์์ค ํ์ผ์
(FileSet)
์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(`lib/*.jar`)๋ฅผ ์ฐธ์กฐํ์ฌ ์ปดํ์ผํ๊ฑฐ๋ ์คํํ ๋ ๊ฒฝ๋ก ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ํฉ๋๋ค.
```xml
<!-- ํด๋์คํจ์ค ID ์ ์ธ -->
<path id="project.classpath">
<!-- lib ํด๋ ์์ ๋ชจ๋ JAR ํ์ผ ํฌํจ -->
<fileset dir="lib">
<include name="**/*.jar"/>
<exclude name="**/*-sources.jar"/>
</fileset>
<!-- ์ปดํ์ผ๋ classes ๋๋ ํฐ๋ฆฌ ์ถ๊ฐ -->
<pathelement location="${classes.dir}"/>
</path>
<!-- ์ปดํ์ผ ์ ํด๋์คํจ์ค ์ฐธ์กฐ -->
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false">
<classpath refid="project.classpath"/>
</javac>
</target>
```
---
### ๐ ๏ธ 3. ํ์ ๊ธฐ๋ณธ ๋ด์ฅ ํ์คํฌ (Core Tasks)
```xml
<!-- 1) ํ์ผ ๋ฐ ๋๋ ํฐ๋ฆฌ ๋ณต์ฌ -->
<copy todir="${classes.dir}">
<!-- src ํด๋์ XML ๋ฐ ํ๋กํผํฐ ์ค์ ํ์ผ๋ง ๋ณต์ฌ -->
<fileset dir="${src.dir}">
<include name="**/*.xml"/>
<include name="**/*.properties"/>
</fileset>
</copy>
<!-- 2) ๋๋ ํฐ๋ฆฌ ์ญ์ -->
<delete dir="${build.dir}" quiet="true"/>
<delete file="${dist.dir}/old-backup.jar"/>
<!-- 3) ์ธ๋ถ ์
ธ ๋ช
๋ น์ด ์คํ (exec) -->
<exec executable="git" outputproperty="git.revision">
<arg value="rev-parse"/>
<arg value="--short"/>
<arg value="HEAD"/>
</exec>
<echo message="ํ์ฌ Git ์ปค๋ฐ ํด์: ${git.revision}"/>
<!-- 4) ZIP / TAR.GZ ์์ถ ๋ฐฐํฌํ ํจํค์ง -->
<zip destfile="${dist.dir}/release-bundle.zip">
<fileset dir="${dist.dir}" includes="*.jar"/>
<fileset dir="docs" prefix="manual"/>
<fileset dir="conf" prefix="config"/>
</zip>
```
---
### ๐ 4. Apache Ivy ์ฐ๋ (ํ๋์ ์ธ ์์กด์ฑ ์๋ ๊ด๋ฆฌ)
Ant๋ Maven Central ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ง์ ๋ค์ด๋ก๋ํ์ง ๋ชปํ์ง๋ง, **Apache Ivy** ํ๋ฌ๊ทธ์ธ์ ๊ฒฐํฉํ๋ฉด Maven/Gradle์ฒ๋ผ ์๊ฒฉ ์์กด์ฑ์ ์๋์ผ๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
#### `ivy.xml` (์์กด์ฑ ์ ์ธ ํ์ผ)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
<info organisation="com.lucky" module="lucky-ant-ivy"/>
<dependencies>
<!-- JSON ๋ผ์ด๋ธ๋ฌ๋ฆฌ (Jackson) ๋ค์ด๋ก๋ ์ ์ธ -->
<dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.17.2"/>
<!-- ๋ก๊น
๋ผ์ด๋ธ๋ฌ๋ฆฌ (SLF4J) -->
<dependency org="org.slf4j" name="slf4j-api" rev="2.0.13"/>
</dependencies>
</ivy-module>
```
#### `build.xml` ๋ด Ivy ํตํฉ
```xml
<project name="IvyExample" default="resolve" xmlns:ivy="antlib:org.apache.ivy.ant">
<!-- Ivy ์ ์ฅ์์์ ์์กด์ฑ ๋ค์ด๋ก๋ ํ lib ๋๋ ํฐ๋ฆฌ์ ๋ณต์ฌ -->
<target name="resolve" description="์ธ๋ถ ์์กด์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๋ ํด๊ฒฐ">
<ivy:retrieve pattern="lib/[artifact]-[revision].[ext]"/>
</target>
</project>
```
---
## 5. [3๋จ๊ณ] ์ค๋ฌด ์์ฉ: WAR ํจํค์ง, JUnit ํ
์คํธ & ๋ฉํฐ ๋ชจ๋
### ๐ 1. ์ํฐํ๋ผ์ด์ฆ ์น ์ ํ๋ฆฌ์ผ์ด์
WAR ํจํค์ง
์คํ๋ง/์๋ธ๋ฆฟ ๋ ๊ฑฐ์ ํ๋ก์ ํธ๋ฅผ ํฐ์บฃ(Tomcat) ๋ฐฐํฌ์ฉ WAR ํ์ผ๋ก ๋ฌถ๋ ์ค๋ฌด ์ค์ ์
๋๋ค.
```xml
<target name="war" depends="compile" description="์น ๋ฐฐํฌ์ฉ WAR ํจํค์ง">
<war destfile="${dist.dir}/ROOT.war" webxml="WebContent/WEB-INF/web.xml">
<!-- 1) ์ ์ ์น ๋ฆฌ์์ค(HTML, CSS, JS, JSP, ์ด๋ฏธ์ง) ํฌํจ -->
<fileset dir="WebContent">
<exclude name="WEB-INF/web.xml"/>
</fileset>
<!-- 2) WEB-INF/classes ์ปดํ์ผ ํด๋์ค ๋ณต์ฌ -->
<classes dir="${classes.dir}"/>
<!-- 3) WEB-INF/lib ์์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ณต์ฌ -->
<lib dir="WebContent/WEB-INF/lib">
<include name="*.jar"/>
</lib>
</war>
</target>
```
---
### ๐งช 2. JUnit ์๋ ๋จ์ ํ
์คํธ & HTML ๊ฒฐ๊ณผ ๋ณด๊ณ ์
```xml
<property name="test.src.dir" location="test"/>
<property name="test.classes.dir" location="${build.dir}/test-classes"/>
<property name="test.reports.dir" location="${build.dir}/reports"/>
<target name="test" depends="compile" description="JUnit ํ
์คํธ ์คํ ๋ฐ ๋ณด๊ณ ์ ์์ฑ">
<mkdir dir="${test.classes.dir}"/>
<mkdir dir="${test.reports.dir}"/>
<!-- ํ
์คํธ ์์ค ์ปดํ์ผ -->
<javac srcdir="${test.src.dir}" destdir="${test.classes.dir}" includeantruntime="false">
<classpath>
<path refid="project.classpath"/>
<pathelement location="${classes.dir}"/>
</classpath>
</javac>
<!-- JUnit ํ
์คํธ ์คํ -->
<junit printsummary="yes" fork="true" haltonfailure="false">
<classpath>
<path refid="project.classpath"/>
<pathelement location="${classes.dir}"/>
<pathelement location="${test.classes.dir}"/>
</classpath>
<formatter type="xml"/>
<batchtest todir="${test.reports.dir}">
<fileset dir="${test.src.dir}">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
</junit>
<!-- XML ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ธฐ ์ข์ HTML ๋ณด๊ณ ์๋ก ๋ณํ -->
<junitreport todir="${test.reports.dir}">
<fileset dir="${test.reports.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${test.reports.dir}/html"/>
</junitreport>
</target>
```
---
### ๐ 3. ์กฐ๊ฑด๋ถ ์คํ๊ณผ ํ๊ฒ ํธ์ถ (`if`, `unless`, `antcall`)
```xml
<!-- ํน์ ํ๋กํผํฐ๊ฐ ์ ์๋์ด ์์ ๋๋ง ์คํ -->
<target name="check-env">
<available file="config/production.properties" property="is.prod"/>
</target>
<target name="deploy-prod" depends="check-env" if="is.prod">
<echo message="๐ ์ด์(Production) ํ๊ฒฝ ๋ฐฐํฌ ์์
์ ์งํํฉ๋๋ค."/>
</target>
<!-- ๋์ผ ํ์ผ ๋ด ๋ค๋ฅธ ํ๊ฒ์ ๋งค๊ฐ๋ณ์์ ํจ๊ป ํธ์ถ (antcall) -->
<target name="build-all">
<antcall target="create-bundle">
<param name="bundle.name" value="client-edition"/>
</antcall>
<antcall target="create-bundle">
<param name="bundle.name" value="server-edition"/>
</antcall>
</target>
<target name="create-bundle">
<echo message="ํจํค์ง ์งํ ์ค: ${bundle.name}"/>
</target>
```
---
### ๐ 4. ๋ ๊ฑฐ์ Ant์์ Gradle๋ก์ ๋ง์ด๊ทธ๋ ์ด์
์ ๋ต
Gradle์ Ant์ `build.xml`์ ์ฝ๋ ์์ ์์ด ๊ทธ๋๋ก ๊ฐ์ ธ์ ์คํํ ์ ์๋ `ant.importBuild` ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
```groovy
// build.gradle (Gradle์์ ๊ธฐ์กด Ant ์คํฌ๋ฆฝํธ ๊ทธ๋๋ก ํธ์ถ)
plugins {
id 'java'
}
// Ant ๋น๋ ํ์ผ ๊ฐ์ ธ์ค๊ธฐ
ant.importBuild('build.xml')
// ๊ธฐ์กด Ant์ 'compile' ํ๊ฒ์ Gradle ํ์คํฌ์ฒ๋ผ ์์กด์ฑ ์ฐ๊ฒฐ
tasks.named('build') {
dependsOn 'compile'
}
```
---
## 6. ํ๋ก๋์
์ด์ CLI ๋ช
๋ น์ด & ํธ๋ฌ๋ธ์ํ
(Operations)
### ๐ ์ฃผ์ Ant CLI ํ๋๊ทธ ์์ฝ
| ๋ช
๋ น์ด | ๊ธฐ๋ฅ ๋ฐ ์ฌ์ฉ ๋ชฉ์ |
| :--- | :--- |
| `ant -p` (๋๋ `-projecthelp`) | `build.xml`์ ๊ธฐ์ ๋ ๋ชจ๋ ๊ณต๊ฐ ํ๊ฒ๊ณผ ์ค๋ช
(`description`) ๋ชฉ๋ก ํ์ธ |
| `ant -diagnostics` | Ant ์ค์น ํ๊ฒฝ, JVM ์ค์ , ํ์ฑํ๋ ์ต์
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ XML ํ์ ์ง๋จ |
| `ant -D<name>=<value>` | ์ปค๋งจ๋๋ผ์ธ์์ ํ๋กํผํฐ ๊ฐ์ ๋์ ์ผ๋ก ์ค๋ฒ๋ผ์ด๋ ์ ๋ฌ (์: `ant -Denv=prod`) |
| `ant -f <file.xml>` | ๊ธฐ๋ณธ `build.xml` ๋์ ์ง์ ๋ ๋ค๋ฅธ XML ์คํฌ๋ฆฝํธ ํ์ผ ์คํ |
| `ant -v` (๋๋ `-verbose`) | ์์ธ ์คํ ๋ก๊ทธ ์ถ๋ ฅ (ํ์คํฌ๋ณ ์คํ ์กฐ๊ฑด, ๋งค์นญ๋ ํ์ผ ๋ชฉ๋ก ์ถ์ ) |
| `ant -d` (๋๋ `-debug`) | ๊ฐ๋ฐ์์ฉ ์ ์ฒด ๋๋ฒ๊ทธ ํธ๋ ์ด์ค ์ถ๋ ฅ (ํ์คํฌ ๋ด๋ถ ์์ธ ๋ถ์) |
| `ant -keep-going` (`-k`) | ํ ํ๊ฒ์์ ์๋ฌ๊ฐ ๋ฐ์ํด๋ ์ค๋จํ์ง ์๊ณ ๊ฐ๋ฅํ ๋ชจ๋ ํ๊ฒ ๋๊น์ง ์คํ |
---
### ๐ ์์ฃผ ๋ฐ์ํ๋ ์ค๋ฅ & ํธ๋ฌ๋ธ์ํ
#### 1. `includeantruntime was not set, defaulting to build.sysclasspath=fqcn` ๊ฒฝ๊ณ
- **์์ธ**: Ant 1.8 ์ดํ ๋ฒ์ ์์ ์์คํ
ํด๋์คํจ์ค ์๋ ํฌํจ ์ฌ๋ถ๋ฅผ ๋ช
์ํ์ง ์์ ๋ฐ์ํฉ๋๋ค.
- **ํด๊ฒฐ์ฑ
**: `<javac>` ํ์คํฌ์ `includeantruntime="false"` ์์ฑ์ ๋ช
์์ ์ผ๋ก ์ถ๊ฐํฉ๋๋ค.
#### 2. ํ๊ธ ์ฃผ์ ๋๋ ๋ฌธ์์ด ์ปดํ์ผ ์๋ฌ (`unmappable character for encoding`)
- **์์ธ**: OS ๊ธฐ๋ณธ ์ธ์ฝ๋ฉ(Windows MS949 ๋ฑ)๊ณผ ์๋ฐ ์์ค ํ์ผ ์ธ์ฝ๋ฉ(UTF-8)์ด ์ผ์นํ์ง ์์ ๋ ๋ฐ์ํฉ๋๋ค.
- **ํด๊ฒฐ์ฑ
**:
```xml
<javac srcdir="${src.dir}" destdir="${classes.dir}" encoding="UTF-8"/>
```
#### 3. ๋๊ท๋ชจ ๋น๋ ์ค `java.lang.OutOfMemoryError: Java heap space`
- **์์ธ**: Ant๊ฐ ์คํ๋๋ JVM ๊ธฐ๋ณธ ํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์์ค ์ฝ๋ ์ปดํ์ผ ๋ฐ JAR ์์ถ ์๊ตฌ๋์ ์ด๊ณผํจ.
- **ํด๊ฒฐ์ฑ
**:
```bash
export ANT_OPTS="-Xms512m -Xmx2048m -XX:+UseG1GC"
```
๋๋ `<javac>`์ `<java>` ํ์คํฌ์ `fork="true"` ๋ฐ `memoryMaximumSize="1024m"`์ ์ค์ ํฉ๋๋ค.
์๊ฒฌ ๋ฐ ์ง๋ฌธ
0์์ง ๋ฑ๋ก๋ ์๊ฒฌ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋๊ธ์ ๋จ๊ฒจ๋ณด์ธ์!
๋๊ธ ์์
๋๊ธ ์ญ์