주요글: 도커 시작하기
반응형
필자가 Maven에서 가장 좋아하는 기능 중의 하나를 꼽으라면? Maven과 Jetty를 연동하여 웹 어플리케이션을 테스트할 수 있다는 것이다. 이클립스에서 톰캣이나 다른 WAS를 연동해서 테스트 해 본 개발자라면 프로젝트 별로 톰캣 연동 설정을 하는 게 얼마나 귀찮은 일인지 알 것이다. 동일한 프로젝트가 여러 브랜치에서 개발되고 있고, 각 브랜치를 하나의 이클립스에서 동시에 테스트 해야 할 경우 이클립스에서 WAS를 연동해서 테스트 하는 건 더욱 더 성가신 작업이 될 수 있다.

Maven은 웹 어플리케이션을 위한 프로젝트 타입을 제공하고 있을 뿐만 아니라 maven-jetty-plugin을 이용해서 프로젝트 별로 간단한 설정만으로 Jetty를 이용해서 웹 어플리케이션 테스트를 진행할 수 있다. 본 글에서는 Maven을 이용해서 웹 프로젝트를 생성하는 방법과 Jetty를 연동해서 웹 어플리케이션을 실행하고 테스트하는 방법을 살펴보도록 하겠다.

웹 어플리케이션 프로젝트 생성하기

웹 어플리케이션을 생성할 때에는 'archetype:generate' 플러그인 골을 실행한 뒤, Archetype으로 'maven-archetype-webapp'을 선택하면 된다. (archetype:generate 플러그인 골을 실행하는 방법은 필자가 쓴 'Maven 기초 사용법'을 참고하기 바란다.)

maven-archetype-webapp Arcetype을 이용해서 Maven 프로젝트를 생성하면 다음과 같이 디렉터리 구조가 생성된다.

simple-web
└─src
    └─main
        ├─resources
        └─webapp
            └─WEB-INF (web.xml 파일 포함)

src/main/webapp 디렉터리는 웹 어플리케이션에서 필요로 하는 HTML, 이미지, JSP 등의 파일이 위치한다. 웹 어플리케이션에서 필요로 하는 클래스를 추가해야 할 경우 src/main/java 디렉터리를 생성한 뒤 이 디렉터리에 자바 소스 코드를 위치시키면 된다.

maven-archetype-webapp을 통해서 생성된 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.daum.cafe</groupId>
    <artifactId>simple-web</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>simple-web Maven Webapp</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>
    <build>
        <finalName>simple-web</finalName>
    </build>
</project>

위 코드를 보면 <packaging>의 값이 war인 것을 알 수 있는데, 이는 mvn package 명령어를 실행할 때 생성되는 결과물이 war 파일이라는 것을 의미하며, 이때 생성되는 war 파일의 이름은 <build>/<finalName>의 값을 사용한다. 위 예의 경우에는 simple-web.war 파일이 생성된다. mvn package 명령어로 생성되는 war 파일의 이름을 변경하고 싶다면 <finalName>에 원하는 값을 입력해 주면 된다.

웹 어플리케이션 개발시 주로 사용되는 의존 프로젝트 목록

웹 기반의 엔터프라이즈 어플리케이션을 개발할 때에는 서블릿 API, JSP API, JTA API 등 Sun에서 정의한 API가 필요하다. 문제는 라이센스 때문에 Sun이 제공하는 API를 Maven 중앙 리포지토리에서 다운로드 받을 수 없다는 점이다. 중앙 리포지토리에 없는 라이브러리는 직접 다운로드 받아 로컬 리포지토리에 등록해주어야 하는데, 다행히 Geronimo 프로젝트에서 Sun의 주요 API를 만들어 Maven 리포지토리에 등록하고 있다. 따라서, 서블릿 API나 JSP API 가 필요한 경우 Geronimo에서 제공하는 프로젝트를 pom.xml 파일의 <dependency>에 추가해주면 된다.

아래 표는 Geronimo가 제공하는 Sun의 주요 표준 API 목록을 정리한 것이다. 참고로 아래 표에 정리된 Artifact 들의 groupId는 org.apache.geronimo.specs 이다.

표준 표준 버전 Artifact ID  Artifact 최신 버전
Activation 1.0.2  geronimo-activation_1.0.2_spec 1.2 
Activation 1.1 geronimo-activation_1.1_spec 1.0.2
EJB 2.1 geronimo-ejb_2.1_spec 1.1 
EJB 3.0 geronimo-ejb_3.0_spec 1.0 .1
J2EE Connector 1.5 geronimo-j2ee-connector_1.5_spec  2.0.0
J2EE JACC 1.0  geronimo-j2ee-jacc_1.0_spec  1.1.1 
JACC 1.1  geronimo-jacc_1.1_spec  1.0.1
JavaMail  1.3.1  geronimo-javamail_1.3.1_spec  1.3 
JavaMail 1.4  geronimo-javamail_1.4_spec 1.5
JMS 1.1 geronimo-jms_1.1_spec  1.1.1
JPA 3.0  geronimo-jpa_3.0_spec  1.1.1
JSP 2.0  geronimo-jsp_2.0_spec 1.1
JSP 2.1  geronimo-jsp_2.1_spec 1.0.1
JTA 1.0.1B geronimo-jta_1.0.1B_spec  1.1.1 
JTA 1.1  geronimo-jta_1.1_spec 1.1.1
Servlet 2.4  geronimo-servlet_2.4_spec 1.1.1 
Servlet 2.5  geronimo-servlet_2.5_spec 1.2

예를 들어, 개발 과정에서 서블릿 2.5 API가 필요할 경우 pom.xml에 다음과 같이 <dependency>를 추가해주면 된다.

<dependency>
    <groupId>org.apache.geronimo.specs</groupId>
    <artifactId>geronimo-servlet_2.5_spec</artifactId>
    <version>1.2</version>
    <scope>provided</scope>
</dependency>

위 코드에서 scope가 provided인 이유는 서블릿이나 JSP API의 경우 컨테이너에 제공하기 때문이다.

Maven과 Jetty 연동을 통한 웹 테스트

Maven을 이용해서 웹 어플리케이션을 개발할 때 필자 개인적으로 가장 매력적인 점은 pom.xml 파일에 maven-jetty-plugin 설정만 추가해주면 Jetty를 이용해 웹 어플리케이션을 테스트 할 수 있다는 점이다. 즉, 톰캣과 같은 WAS를 설치하거나 추가적으로 설정할 필요 없이 웹 어플리케이션에 대한 기능 테스트가 가능하다는 점이다.

maven-jetty-plugin의 설정 방법은 매우 간단한데, 아래와 같이 pom.xml 파일에 설정해주면 된다.

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
    <build>
        <finalName>main</finalName>
        <plugins>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.11</version>
                <configuration>
                    <contextPath>/main</contextPath>
                    <scanIntervalSeconds>3</scanIntervalSeconds>
                    <!-- 포트를 변경하고 싶은 경우 connectors 설정 이용 -->
                    <connectors>
                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                            <port>80</port>
                            <maxIdleTime>60000</maxIdleTime>
                        </connector>
                    </connectors>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

<configuration>에서 주요 설정 값은 다음과 같다.
  • <contextPath> - 웹 어플리케이션 컨텍스트 경로. 예를 들어, 위 설정의 경우 http://localhost:8080/main 이 웹 어플리케이션의 접근 URL이 된다.
  • <scanIntervalSeconds> - 웹 어플리케이션 컨텍스트의 클래스가 변경되는 지의 여부를 검사하는 시간 간격을 초 단위로 입력한다. 이 값을 0보다 크게 주면, 클래스가 변경될 때 마다 리로드 된다.
<scanTargets>나 <scanTargetPatterns>를 설정하면 클래스 뿐만 아니라 특정 디렉터리나 파일이 변경되는 지의 여부를 검사하도록 설정할 수 있다. 스캔 설정을 비롯한 maven-jetty-plugin의 다양한 설정 옵션을 확인하고 싶다면 'Maven Jetty Plugin Configuration Guide' 문서를 참고하기 바란다.

포트 번호를 지정하지 않을 경우 기본 값은 8080 이다. 따라서 8080 이 아닌 다른 포트를 사용하고 싶다면 위 설정에서 처럼 <connector>를 알맞게 설정해 주어야 한다.

jetty:run을 이용한 실행

maven-jetty-plugin이 제공하는 골에는 run, run-exploaded, run-war, start, stop 등 몇 가지가 존재하는데, 가장 많이 사용되는 건 run 골이다. run 골을 실행하는 방법은 다음과 같다.

$ mvn jetty:run
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'jetty'.
[INFO] ------------------------------------------------------------------------
[INFO] Building javacan3
[INFO]    task-segment: [jetty:run]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing jetty:run
[INFO] [resources:resources]
...
[INFO] [jetty:run]
[INFO] Configuring Jetty for project: javacan3
[INFO] Webapp source directory = C:\work\JavaCan3_maven\src\main\webapp
[INFO] web.xml file = C:\work\JavaCan3_maven\src\main\webapp\WEB-INF\web.xml
[INFO] Classes = C:\work\JavaCan3_maven\target\classes
2008-12-19 15:49:19.210::INFO:  Logging to STDERR via org.mortbay.log.StdErrLog
[INFO] Context path = /main
[INFO] Tmp directory =  determined at runtime
[INFO] Web defaults = C:\work\JavaCan3_maven\src\jetty\webdefault.xml
[INFO] Web overrides =  none
[INFO] Webapp directory = C:\work\\JavaCan3_maven\src\main\webapp
[INFO] Starting jetty 6.1.11 ...
...
2008-12-19 15:48:38.584::INFO:  Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server

jetty:run을 실행하면 잠시 뒤에 Jetty가 실행되고 이 후로 웹 브라우저를 이용해서 기능 테스트를 진행할 수 있게 된다.


관련 링크:
  • Archetype 플러그인 사용법: http://maven.apache.org/plugins/maven-archetype-plugin/usage.html
  • Maven Jetty Plugin Configuration Guide: http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin
  • Jetty 서블릿/JSP 컨테이너 기초 사용: http://javacan.tistory.com/entry/136

+ Recent posts