maven-jetty-plugin 포트 설정하기

<plugin>
    <groupId>org.mortbay.jetty</groupId>
    <artifactId>maven-jetty-plugin</artifactId>
    <version>6.1.20</version>
    <configuration>
        <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                <port>8081</port>
            </connector>
        </connectors>
    </configuration>           
</plugin>

 

 

참고사이트

http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin

신고
by cranix 2009.09.03 13:19

maven-compiler-plugin encoding 설정하기

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>

 

 

maven-resources-plugin encoding 설정하기

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>

 

 

메이븐에서는 위와같이 버젼이며 인코딩을 명시해 줘야한다. 안그러면 알수없는 오류들을 내뱉는 경우가 종종있다.

신고
by cranix 2009.09.03 12:16

들어가며

기존에 eclipse 에서 tomcat 프로그래밍을 하려면 톰켓을 받아서 설치해야 했었다. maven 에서는 어떻게 하는지 확인해 보도록 하자.

 

프로젝트 만들기

이번 프로젝트는 웹 어플리케이션 이기 때문에 배포형태를 war 로 한다.

 

 

 

디렉토리 구조

웹 어플리케이션 형태는 위와 같이 webapp 디렉토리가 추가된 것이 보일 것이다. 여기에 웹 파일들을 위치시키면 된다.

 

 

TOMCAT 플러그인 설치

이제 웹 어플리 케이션을 테스트 하기 위해서 tomcat 플러그인을 설치해야 한다. tomcat 플러그인은 이름에서도 알 수 있듯이 maven 웹 어플리케이션을 편리하게 tomcat 으로 테스트 해 볼 수 있게 해 주는 플러그인이다. 

 

설치하기 위해서는 아래와 같이 pom.xml 파일을 열어서 plugins 탭에 Add Plugin 아이콘을 클릭한다.

 

아래와 같은 검색화면이 나오는데 tomcat 으로 검색해서 추가하자.

 

 

HELLO 실행하기

일단 아래와 같은 index.jsp 파일을 webapp 디렉토리에 추가하자.

 

- main/webapp/index.jsp

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

 

 

이제 위에서 받은 톰켓 플러그인을 실행해 주면 되는데 그 방법은 [Run As]-[maven build…] 를 클릭 한다음 아래와 같이 Goals 에다가 tomcat:run 이라고 입력하고 Run 을 누르면 된다.

 

그러면 Console 창에 메시지가 뜨면서 실행을 하게 되는데 만약 톰켓이 없다면 자동으로 로컬 레포지토리에 받아지게 된다. 다 받아진 후에 아래 메시지가 뜨면서 실행된다.

[INFO] [tomcat:run {execution: default-cli}]
[INFO] Running war on http://localhost:8080/simplewebapp
[INFO] Creating Tomcat server configuration at D:\cranix\work\workspace-wtp2\simplewebapp\target\tomcat
2009. 8. 17 오후 10:15:47 org.apache.catalina.startup.Embedded start
정보: Starting tomcat server
2009. 8. 17 오후 10:15:48 org.apache.catalina.core.StandardEngine start
정보: Starting Servlet Engine: Apache Tomcat/6.0.16
2009. 8. 17 오후 10:15:48 org.apache.coyote.http11.Http11Protocol init
정보: Initializing Coyote HTTP/1.1 on http-8080
2009. 8. 17 오후 10:15:48 org.apache.coyote.http11.Http11Protocol start
정보: Starting Coyote HTTP/1.1 on http-8080

 

이제 위에서 나온 주소로 접속해 보면 아래와 같이 제대로 뜨는 것을 확인 할 수 있다.

 

 

마치며

maven 은 tomcat 조차도 플러그인 형태로 취급한다. 이렇게 함으로서 작업환경을 특정 플랫폼에 종속시키지 않을 수 있을 것이다.

신고
by cranix 2009.08.17 22:24

들어가며

이 글은 아래 사이트의 내용을 기초로하여 만들어 졌다. 아래 사이트와 다른점은 한글이라는점과 이클립스가 들어갔다는 점이다. 아래에서 만드는 소스내용도 똑같으니 참고하기 바란다.

http://www.sonatype.com/books/maven-book/reference/public-book.html

여기서 만드는 예제는 yahoo 에서 제공하는 xml 을 이용하여 날씨를 얻어오는 예제이다.

물론 프로젝트 내용은 중요한것이 아니고 maven의 기능을 살펴보는데 초점을 맞추게 될것이다.

 

 

프로젝트 만들기

maven 프로젝트를 생성해서 아래와같이 입력하고 Next 버튼을 누른다.

 

기본적으로 test 를 위해 junit 은 필요할테니까 Add 를 클릭해서 junit 을 검색해서 추가한다.

단 scope 는 test 로 해야 한다는 것을 잊지 말자.

 

 

Dependency 추가

pom.xml 파일을 열면 아래와같은 화면이 나오는데 여기서  Dependencies 탭으로 가서 아래처럼 찾기 아이콘을 클릭한다.

 

이제 찾기 화면에서 아래 라이브러를 검색해서 추가한다.  (단 여기서 log4j 는 이보다 최신버젼이 있지만 그 버젼을 선택할경우 오류가 나는 현상이 있어서 이전 버젼을 선택했다.) 추가한 다음에는 꼭 저장버튼을 클릭해서 적용을 하자.

log4j (1.2.14 )

dom4j

jaxen

velocity

 

 

프로그램 작성

프로그램 작성에 들어가기 전에 이클립스 셋팅을 해야한다. maven 프로젝트를 생성하면 기본적으로 자바 1.4 가 선택이 된다. 프로젝트의 Properties 로 들어가서 Java Compiler 메뉴로 가서 컴파일러 버젼을 최신으로 바꾼다음에 진행하도록 하자.

 

프로그램의 소스파일은 아래와 같다. 여기서 중요한 것은 소스의 내용이 아니기 때문에 소스설명은 생략하도록 하겠다.

net/cranix/Weather.java

net/cranix/Main.java

net/cranix/YahooRetriver.java

net/cranix/YahooParser.java

net/cranix/WeatherFormatter.java

 

<net/cranix/Weather.java>

package net.cranix;

public class Weather {
    private String city;
    private String region;
    private String country;
    private String condition;
    private String temp;
    private String chill;
    private String humidity;

    public Weather() {
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCondition() {
        return condition;
    }

    public void setCondition(String condition) {
        this.condition = condition;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    public String getChill() {
        return chill;
    }

    public void setChill(String chill) {
        this.chill = chill;
    }

    public String getHumidity() {
        return humidity;
    }

    public void setHumidity(String humidity) {
        this.humidity = humidity;
    }
}

 

<net/cranix/Main.java>

package net.cranix;

import java.io.InputStream;

import org.apache.log4j.PropertyConfigurator;

public class Main {

    public static void main(String[] args) throws Exception {
        // Configure Log4J
        PropertyConfigurator.configure(Main.class.getClassLoader().getResource("log4j.properties"));

        // Read the Zip Code from the Command-line (if none supplied, use 60202)
        String zipcode = "60202";
        try {
          zipcode = args[0];
        } catch( Exception e ) {}

        // Start the program
        new Main(zipcode).start();
      }

    private String zip;

    public Main(String zip) {
        this.zip = zip;
    }

    public void start() throws Exception {
        // Retrieve Data
        InputStream dataIn = new YahooRetriever().retrieve(Integer.valueOf(zip));

        // Parse Data
        Weather weather = new YahooParser().parse(dataIn);

        // Format (Print) Data
        System.out.print(new WeatherFormatter().format(weather));
    }
}

<net/cranix/YahooRetriver.java>

package net.cranix;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.log4j.Logger;

public class YahooRetriever {

    private static Logger log = Logger.getLogger(YahooRetriever.class);

    public InputStream retrieve(int zipcode) throws Exception {
        log.info("Retrieving Weather Data");
        String url = "http://weather.yahooapis.com/forecastrss?p=" + zipcode;
        URLConnection conn = new URL(url).openConnection();
        return conn.getInputStream();
    }
}

<net/cranix/YahooParser.java>

package net.cranix;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.io.SAXReader;

public class YahooParser {

    private static Logger log = Logger.getLogger(YahooParser.class);

    public Weather parse(InputStream inputStream) throws Exception {
        Weather weather = new Weather();

        log.info("Creating XML Reader");
        SAXReader xmlReader = createXmlReader();
        Document doc = xmlReader.read(inputStream);

        log.info("Parsing XML Response");
        weather.setCity(doc.valueOf("/rss/channel/y:location/@city"));
        weather.setRegion(doc.valueOf("/rss/channel/y:location/@region"));
        weather.setCountry(doc.valueOf("/rss/channel/y:location/@country"));
        weather.setCondition(doc.valueOf("/rss/channel/item/y:condition/@text"));
        weather.setTemp(doc.valueOf("/rss/channel/item/y:condition/@temp"));
        weather.setChill(doc.valueOf("/rss/channel/y:wind/@chill"));
        weather.setHumidity(doc.valueOf("/rss/channel/y:atmosphere/@humidity"));

        return weather;
    }

    private SAXReader createXmlReader() {
        Map<String, String> uris = new HashMap<String, String>();
        uris.put("y", "http://xml.weather.yahoo.com/ns/rss/1.0");

        DocumentFactory factory = new DocumentFactory();
        factory.setXPathNamespaceURIs(uris);

        SAXReader xmlReader = new SAXReader();
        xmlReader.setDocumentFactory(factory);
        return xmlReader;
    }
}

<net/cranix/WeatherFormatter.java>

package net.cranix;

import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;

import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

public class WeatherFormatter {
    private static Logger log = Logger.getLogger(WeatherFormatter.class);
    public String format(Weather weather) throws Exception {
        log.info("Formatting Weather Data");
        Reader reader = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("output.vm"));
        VelocityContext context = new VelocityContext();
        context.put("weather", weather);
        StringWriter writer = new StringWriter();
        Velocity.evaluate(context, writer, "", reader);
        return writer.toString();
    }
}

 

소스를 조금 설명하자면 dom4j 라이브러리로 yahoo 에서 제공하는 xml 파일을 읽어서 파싱한 다음 velocity 라이브러리로 출력을 하게 되는 것이다. 여기서 콘솔출력은 log4j 에 의해 이루어진다.

 

 

RESOURCE 추가

그러나 이렇게 소스만 만들어놨다고 제대로된 결과를 기대하기는 어렵다. 왜냐하면 log4j 같은 경우는 설정 파일이 필요하고 velocity 는 템플릿 파일이 필요하다 이런 resource 를 추가하는 방법을 알아보도록 하겠다.

 

모든 리소스들은 resource 디렉토리에 위치시키면 된다. 이 프로그램에서 필요한 리소스는 아래와 같다.

log4j.properties

output.vm

 

<log4j.properties>

# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=INFO, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%-4r %-5p %c{1} %x - %m%n

<output.vm>

*********************************
Current Weather Conditions for:
${weather.city}, ${weather.region}, ${weather.country}

Temperature: ${weather.temp}
Condition: ${weather.condition}
Humidity: ${weather.humidity}
Wind Chill: ${weather.chill}
*********************************

디렉토리의 형태는 아래와 같다.

 

 

실행하기

실행하기 위해서는 Run As-maven build 를 클릭한다음 아래와같이 셋팅하고 Run 을 클릭하자.

 

아래와 같은 결과가 나오면서 우리가 만든 프로그램이 제대로 실행되고 있는 것을 알 수 있다.

[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] Attempting to resolve a version for plugin: org.codehaus.mojo:exec-maven-plugin using meta-version: LATEST
[INFO] Using version: 1.1.1 of plugin: org.codehaus.mojo:exec-maven-plugin
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - net.cranix:weather:jar:0.0.1-SNAPSHOT
[INFO]
[INFO] Id: net.cranix:weather:jar:0.0.1-SNAPSHOT
[INFO] task-segment: [exec:java]
[INFO] ------------------------------------------------------------------------
[INFO] [exec:java]
0    INFO  YahooRetriever  - Retrieving Weather Data
359  INFO  YahooParser  - Creating XML Reader
561  INFO  YahooParser  - Parsing XML Response
639  INFO  WeatherFormatter  - Formatting Weather Data
*********************************
Current Weather Conditions for:
  Evanston, IL, US
Temperature: 70
   Condition: Fair
    Humidity: 73
  Wind Chill: 70
*********************************
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Sun Aug 16 15:44:18 KST 2009
[INFO] Final Memory: 4M/12M
[INFO] ------------------------------------------------------------------------

 

 

Dependency 정보 확인하기

이렇게 maven 으로 프로젝트를 만들었다면 Dependency 정보를 쉽게 확인할 수 있다.

pom.xml 파일을 열어서 Dependency Graph 탭을 클릭하고 새로고침 버튼을 클릭하면 아래와 같이 그래프 형태로 표시되는 것을 볼 수 있다.

 

아래와 같이 Dependency Hierarchy 를 클릭해서 트리 형태로 볼 수도 있다.

 

 

 

테스트 소스 추가하기

여기서는 유닛 테스트를 위해 commons-io 라이브러리를 사용한다. pom.xml 파일을 열어서 dependency 탭으로 가서 commons-io 라이브러리를 검색해서 추가하자. 단 테스트를 위한 것이기 때문에 scope 를 test 로 설정하자.

 

테스트를 하기 위해서는 test 디렉토리에 테스트 파일이 위치해야 하며 여기서 사용할 테스트파일은 아래와 같다.

test/net/cranix/YahooParserTest.java

test/net/cranix/WeatherFormatterTest.java

 

<test/net/cranix/YahooParserTest.java>

package net.cranix;

import java.io.InputStream;

import junit.framework.TestCase;

public class YahooParserTest extends TestCase {

    public YahooParserTest(String name) {
        super(name);
    }

    public void testParser() throws Exception {
        InputStream nyData = getClass().getClassLoader().getResourceAsStream(
                "ny-weather.xml");
        Weather weather = new YahooParser().parse(nyData);
        assertEquals("New York", weather.getCity());
        assertEquals("NY", weather.getRegion());
        assertEquals("US", weather.getCountry());
        assertEquals("39", weather.getTemp());
        assertEquals("Fair", weather.getCondition());
        assertEquals("39", weather.getChill());
        assertEquals("67", weather.getHumidity());
    }
}

 

<test/net/cranix/WeatherFormatterTest.java>

package net.cranix;

import java.io.InputStream;

import org.apache.commons.io.IOUtil;

import junit.framework.TestCase;

public class WeatherFormatterTest extends TestCase {

    public WeatherFormatterTest(String name) {
        super(name);
    }

    public void testFormat() throws Exception {
        InputStream nyData = getClass().getClassLoader().getResourceAsStream("ny-weather.xml");
        Weather weather = new YahooParser().parse(nyData);
        String formattedResult = new WeatherFormatter().format(weather);
        InputStream expected = getClass().getClassLoader().getResourceAsStream("format-expected.dat");
        assertEquals(IOUtil.toString(expected).trim(), formattedResult.trim());
    }
}

 

 

테스트 RESOURCE 추가하기

테스트를 위한 이 프로그램 역시 그냥은 실행되지 않는다. 리소스 파일을 추가해 줘야 하는데 테스트 리소스 파일은 test/resources 디렉토리에 위치해야 한다.

test/resources/format-expected.dat

test/resources/ny-weather.xml

<test/resources/format-expected.dat>

*********************************
Current Weather Conditions for:
New York, NY, US

Temperature: 39
Condition: Fair
Humidity: 67
Wind Chill: 39
*********************************
<test/resources/ny-weather.xml>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<title>Yahoo! Weather - New York, NY</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/New_York__NY/</link>
<description>Yahoo! Weather for New York, NY</description>
<language>en-us</language>
<lastBuildDate>Sat, 10 Nov 2007 8:51 pm EDT</lastBuildDate>

<ttl>60</ttl>
<yweather:location city="New York" region="NY" country="US" />
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph" />
<yweather:wind chill="39" direction="0" speed="0" />
<yweather:atmosphere humidity="67" visibility="1609" pressure="30.18"
rising="1" />
<yweather:astronomy sunrise="6:36 am" sunset="4:43 pm" />
<image>
<title>Yahoo! Weather</title>

<width>142</width>
<height>18</height>
<link>http://weather.yahoo.com/</link>
<url>http://l.yimg.com/us.yimg.com/i/us/nws/th/main_142b.gif</url>
</image>
<item>
<title>Conditions for New York, NY at 8:51 pm EDT</title>

<geo:lat>40.67</geo:lat>
<geo:long>-73.94</geo:long>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/New_York__NY/\</link>
<pubDate>Sat, 10 Nov 2007 8:51 pm EDT</pubDate>
<yweather:condition text="Fair" code="33" temp="39"
date="Sat, 10 Nov 2007 8:51 pm EDT" />
<description><![CDATA[
<img src="http://l.yimg.com/us.yimg.com/i/us/we/52/33.gif" /><br />
<b>Current Conditions:</b><br />
Fair, 39 F<BR /><BR />
<b>Forecast:</b><BR />
Sat - Partly Cloudy. High: 45 Low: 32<br />
Sun - Sunny. High: 50 Low: 38<br />
<br />
]]></description>
<yweather:forecast day="Sat" date="10 Nov 2007" low="32" high="45"
text="Partly Cloudy" code="29" />

<yweather:forecast day="Sun" date="11 Nov 2007" low="38" high="50"
text="Sunny" code="32" />
<guid isPermaLink="false">10002_2007_11_10_20_51_EDT</guid>
</item>
</channel>
</rss>

 

최종 디렉토리는 아래와 같다.

 

 

 

테스트 실행

이제 테스트 환경이 갖추어졌다.

Run As-maven test 를 실행하자. 아래와 같이 테스트가 되는 것을 볼 수 있다.

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - net.cranix:weather:jar:0.0.1-SNAPSHOT
[INFO]
[INFO] Id: net.cranix:weather:jar:0.0.1-SNAPSHOT
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test]
[INFO] Surefire report directory: D:\cranix\work\workspace-wtp2\weather\target\surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running net.cranix.YahooParserTest
0    INFO  YahooParser  - Creating XML Reader
171  INFO  YahooParser  - Parsing XML Response
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.407 sec
Running net.cranix.WeatherFormatterTest
266  INFO  YahooParser  - Creating XML Reader
282  INFO  YahooParser  - Parsing XML Response
282  INFO  WeatherFormatter  - Formatting Weather Data
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.172 sec

Results :

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

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Sun Aug 16 16:55:20 KST 2009
[INFO] Final Memory: 2M/6M
[INFO] ------------------------------------------------------------------------

 

 

 

Dependencies 까지 포함시켜서 패키징하기

이 과정을 assembly 과정 이라고 하는데 제대로 실행되도록 하려면 셋팅을 해야한다. pom.xml 파일을 열어서 아래 부분을 추가한다.

<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>

 

그 다음 Run As-maven assembly:assembly 를 실행한다. 아래와같은 화면이 나오면서 패키징을 하게된다.

[INFO] [jar:jar]
[INFO] Building jar: D:\cranix\work\workspace-wtp2\weather\target\weather-0.0.1-SNAPSHOT.jar
[INFO] [statemgmt:end-fork]
[INFO] Ending forked execution [fork id: 574707759]
[INFO] [assembly:assembly]
[INFO] Processing DependencySet (output=)
[INFO] Expanding: D:\cranix\work\maven\repository\log4j\log4j\1.2.14\log4j-1.2.14.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.1429370463.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\maven\dom4j\1.7-20060614\dom4j-1.7-20060614.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.1955766376.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\jaxme\jaxme-api\0.3\jaxme-api-0.3.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.165260721.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\jaxen\jaxen\1.1.1\jaxen-1.1.1.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.1217840646.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.3570191.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\jdom\jdom\1.0\jdom-1.0.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.1685521809.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\xerces\xmlParserAPIs\2.6.2\xmlParserAPIs-2.6.2.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.305584397.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\xerces\xercesImpl\2.6.2\xercesImpl-2.6.2.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.1558042758.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\xom\xom\1.0\xom-1.0.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.2049563553.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\com\ibm\icu\icu4j\2.6.1\icu4j-2.6.1.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.796405737.tmp
[INFO] Expanding: D:\cranix\work\maven\repository\xalan\xalan\2.6.0\xalan-2.6.0.jar into C:\Users\cranix\AppData\Local\Temp\archived-file-set.1324133154.tmp

이 작업은 현재 종속된 모든 라이브러리를 하나의 jar 파일로 묶는 작업으로 시간이 조금 걸린다. 완료가 되면 target 디렉토리에 모든 종속된 라이브러리의 클래스가 포함된 weather-0.0.1-SNAPSHOT-jar-with-dependencies.jar 파일이 생성된 것을 볼 수있다.

 

마치며

왠만해서 pom.xml 파일을 직접 에디트 하지 않았으면 했지만 아직 m2eclipse 플러그인 에서는 비쥬얼하게 위와같이 assembly 설정을 할수있는 방법이 없는거 같다. 하여튼 마지막 assembly 과정은 maven 의 백미 라고 볼 수 있겠다.

신고
by cranix 2009.08.16 17:17

들어가며

maven 에 관한 문서를 찾아보다가 아래 사이트에서 상당히 괜찮은 문서를 찾았다. 아래 사이트를 따라하면서 maven 을 이해해보도록 하겠다.

http://www.sonatype.com/books/maven-book/reference/public-book.html

 

설치하기

eclipse 에서 maven 을 지원하는 플러그인이 나와있다 업데이트 주소는 아래와 같다

http://m2eclipse.sonatype.org/update/

이클립스 메뉴의 Help-Install New Software 에 들어가서 위의 URL 을 입력하고 설치하기 바란다.

 

 

프로젝트 만들기

m2eclipse 를 설치하면 위와같이 3가지 형태의 maven 프로젝트를 만들수 있는데 Maven Project 를 만들어 선택하고 Next 를 누르자.

 

maven 은 다양한 archetype을 지원하는데 여기서 archetype 란 기본적인 프로젝트 셋팅 이라고 보면된다. 우리는 셋팅이 하나도 되어있지 않은 프로젝트를 생성할것이기 때문에 archetype 를 선택하지 말고 skip 하도록 Create a simple project 를 체크하고 Next 를 누른다.

 

Group Id 는 java 의 package 와 같은 개념으로 보면 된다.

Artifact Id 는 메이븐 프로젝트의 이름으로 이 값이 만들어졌을때 이클립스 프로젝트 명이 된다.

Name 과 Description 은 해당 프로젝트의 설명 이다.

일단 위와같이 입력하고 Next 를 누른다.

 

dependencies 설정하는 부분이 나오는데 현재는 없음으로 그냥 Finish를 누른다.

 

위와같은 형태의 프로젝트가 생성된것을 확인할수 있을것이다.

 

 

MAVEN 프로젝트 구조

프로젝트 디렉토리를 확인해보면 아래와 같다.

simple/

   pom.xml

   src/

      main/

         java/

         resources/

      test/

         java/

         resources/

   target/

      classes/

      test-classes/

이 디렉토리 구조는 maven 표준 디렉토리 구조이다. 이제 의미를 알아보도록 하겠다.

simple/ - 디렉토리명은 artifact id 의 값과 일치한다.

pom.xml - 모든 maven 프로젝트는 Project Object Model (POM) 이라는 이름의 셋팅파일을 같는다.

main/ – 이 디렉토리는 프로그램의 모든 소스파일과 리소스 파일이 들어가는 디렉토리 이다. 예를들어 properties 파일같은경우 resources 디렉토리에 집어넣으면 된다.

test/ – 이 디렉토리는 junit 테스트 프로그램이 위치하게 된다.

 

HELLO 프로그램하기

우리의 maven 프로젝트에 아래 프로그램을 집어넣는다. package 가 아까 설정했던 group id 와 같은것을 유념해서 디렉토리를 만든후에 작성하도록 한다.

package net.cranix;

public class Hello {
    public static void main(String args[]) {
        System.out.println("Hello Maven World!");
    }
}

다 작성했다면 프로젝트에 마우스오른쪽 버튼 눌러서 Run As-maven package 를 차례로 클릭한다.

 

콘솔창에 무언가 뜨고 조금 지나면 BUILD SUCCESSFUL 이라는 결과가 출력된다.

과연 무엇이 바뀐것일까. 프로젝트 네비게이터에서 F5 키를 눌러서 리플래쉬 시켜보면 새로생긴 파일과 디렉토리가 보인다.

확인해보면 아래와 같다.

target/

   classes/

      net/

         cranix/

            Hello.class

   maven-archiver/

      pom.properties

   test-classes/

   simple-0.0.1-SNAPSHOT.jar

위와 같이 .jar 파일이 생성된 것을 알 수 있다.

 

 

테스트 하기

테스트를 하기 위해서는 junit 라이브러리가 필요하다. maven 에서는 이런 의존관계 설정이 쉽게 되는데 pom.xml 파일을 열어서 Dependencies 탭에 가서 추가만 해주면 된다.

 

위 버튼을 눌러서 아래와같이 검색하자. 알아서 리모트에있는 라이브러리를 검색해서 리스팅 해준다. 원하는 junit 를 선택하고 scope 를 test 로 셋팅한다음 OK 버튼을 누른다.

 

그럼 아래와 같이 추가된 것을 확인할 수 있으며 저장을 눌러서 적용하자.

 

이제 라이브러리도 받았으니 테스트 소스만 만들면 된다. 테스트를 위해서는 테스트를 원하는 클래스의 위치를 test 폴더에다가 만들고 *Test 형태로 클래스를 만들어 주면 된다. 예를 들어 Hello 클래스면 HelloTest 라는 클래스를 만들어 주면 된다.

위와 같이 HelloTest.java 파일을 위치시켰다.

HelloTest 파일의 내용은 아래와 같다.

package net.cranix;

import junit.framework.TestCase;

public class HelloTest extends TestCase{
    public HelloTest(String app) {
        super(app);
    }
    public void testHello() {
        assertTrue(true);
    }
}

 

이제 테스트를 수행하려면 패키지이름에 마우스오른쪽버튼 누르고 Run As-maven test 를 클릭하면 된다. Console 창에 테스트가 수행되는 화면을 확인할 수 있을 것이다.

 

프로그램 실행하기

Run As – Maven build 를 차례로 클릭해서 아래와 같이 설정한다. 파라메터에 mainClass 지정해 주는 것도 잊지 말자.

 

Run 을 누르게 되면 Console 화면에 실행되는 결과를 볼 수 있다.

[INFO] Searching repository for plugin with prefix: 'exec'.
[INFO] Attempting to resolve a version for plugin: org.codehaus.mojo:exec-maven-plugin using meta-version: LATEST
[INFO] Using version: 1.1.1 of plugin: org.codehaus.mojo:exec-maven-plugin
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building simplename
[INFO]
[INFO] Id: net.cranix:simple:jar:0.0.1-SNAPSHOT
[INFO] task-segment: [exec:java]
[INFO] ------------------------------------------------------------------------
[INFO] [exec:java]
Hello Maven World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Sun Aug 16 00:48:28 KST 2009
[INFO] Final Memory: 1M/8M
[INFO] ------------------------------------------------------------------------

 

 

마치며

요즈음에는 자바기반 프로젝트를 하게 되면 거의 필수적으로 아파치 같은 공개 라이브러리를 쓰게 된다. 그러나 이런 라이브러리 역시 다른 라이브러리를 사용하는 것이 대부분이다. 이러다 보니 몇 개의 라이브러리만 가져다 써도 나중에 배포할 때는 의존관계를 따져가며 상당히 귀찮은 작업을 해야 한다. maven 은 이런 귀찮은 작업을 상당히 줄여줄 것으로 기대된다.

신고
by cranix 2009.08.16 01:06

서론

얼마전 java 프로젝트를 하나 했었는데 거기서 maven 이라는 도구를 처음 봤다. 처음 느낀점은 상당히 복잡하다는 것이다. “이걸 구지 써야하나?” 라는 생각이 들정도 였다. 그러나 프로젝트를 진행하면서 이 도구는 잘만쓰면 상당히 유용할 것이라는 생각이 들었다. 그래서 이참에 메이븐이 무엇이고 그 사용법에대해 알아보려고 한다.

 

본론

maven 의 사전적 의미는 이디시어로 “지식의 축적” 을 의미한다고 한다. 이 프로젝트는 Jakarta Turbine 프로젝트에서 빌드과정을 간략히 하려는데서 출발했다. 우리는 프로젝트를 빌드하는데 표준화된 방법, 프로젝트의 확실한 정의, 프로젝트의 정보를 공개하는 쉬운 방법 그리고 프로젝트들간의 JAR 파일의 공유를 원했다. 그래서 maven 이 나왔고 현재는 모든 java 기반 프로젝트에 적용가능하다.

 

maven 의 첫번째 목표는 개발자가 개발산출물을 최단시간내에 이해할수 있도록 하는것이다.

목표를 이루기위해 다루는 영역은 다음과 같다

- 쉬운 빌드 과정
- 동일한 빌드 시스템 제공
- 양질의 프로젝트 정보 제공
- 모범사례에 대한 지침 제공
- 새로운 기능에 투명성 있는 마이그레이션 제공

 

결론

오늘은 메이븐 홈페이지에서 메이븐 소개를 그냥 해석해 봤다. 역시 소개부분이라 상당히 추상적이지만 maven 이 무엇을위해 만들어졌는지는 어느정도 감이 잡힌다. 다음번에는 메이븐과 이클립스를 연동하면서 실제로 프로젝트를 생성해보도록 하겠다.

신고
by cranix 2009.08.15 17:47
| 1 |