슬기로운 개발자 생활

[Maven] Java 응용 프로그램 개발 본문

IT 개발/Maven

[Maven] Java 응용 프로그램 개발

개발자 너부리 2017. 12. 23. 12:42
반응형

Maven에 의한 Java 응용 프로그램 개발의 기본에 대해 기술한다. 실행하는 커멘드, 그리고 pom.xml에 기술에 대해 설명한다.

DarchetypeArtifactId 지정

Maven은 다양한 프로그램을 만들 수 있다. 이것들은 각각에 프로젝트를 작성하는 단계에서 작성 순서가 다르거나, pom.xml에 대한 작성이 다를 것이다. Maven을 이용하여 개발을 하려면, "자신이 만들려는 프로그램을 어떻게 만들어야 할지"를 알아야 한다.

특정 프로젝트 만들기

먼저 기본 중의 기본으로 Java에 의한 어플리케이션(보통 컴퓨터에서 더블 클릭으로 실행할 수 있는 Java 응용 프로그램) 개발부터 생각해 보도록 하자.

Maven으로 프로젝트를 만들 때에 "mvn archetype:generate"라는 커멘드를 실행했었다. 이것은 프로젝트 생성의 가장 기본이 되는 것이다. 하지만 이것을 실행하면, 템플릿 목록이 길게 나열된다. "여기에서 사용하는 템플릿을 선택"하는 것이지만, 이미 1000개 이상의 항목이 있기 때문에 선택하기에 매우 힘들다.

실은 프로젝트를 만들 때, 사용하는 템플릿을 미리 지정해 둘 수 있다. 이것은 - DarchetypeArtifactId라는 옵션을 사용한다.

mvn archetype:generate -DarchetypeArtifactId=아티팩트ID

이렇게 호출한다. 이 -DarchetypeArtifactId라는 것은 사용하는 템플릿 아티펙트 ID를 지정한다. 아무튼, 대부분의 경우에는 아티팩트 ID를 지정하면 그것으로 어떤 템플릿인지 특정할 수 있다.

그러나 경우에 따라서는 특정할 없는 경우도 있다(우연히 같은 아티팩트 ID 템플릿이 여러 개가 있는 것 같은 경우). 이럴 때는 그룹 ID를 지정하는 -DarchetypeGroupId라는 옵션도 준비되어 있다. 이를 사용하여 다음과 같이 실행하면 확실해 진다.

mvn archetype:generate -DarchetypeGroupId=그룹ID -DarchetypeArtifactId=아티팩트ID

기본은 maven-archetype-quickstart

그럼 일반적인 Java 응용 프로그램을 개발할 때는 어떻게 지정하면 되는가. 기본은 아래와 같다.

$ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart

이와 같이 실행하면 다음과 같이 출력이 된다.

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
Define value for property 'groupId': : 
Define value for property 'artifactId': : 
Define value for property 'version':  1.0-SNAPSHOT: : 
Define value for property 'package':  : : 
[WARNING] Archetype is not fully configured
Define value for property 'groupId': : ^Ckimkcui-MacBook-Pro:mvn kimkc$ 
kimkcui-MacBook-Pro:mvn kimkc$ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO] 
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO] 
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Interactive mode
Define value for property 'groupId': : 그룹 ID 입력
Define value for property 'artifactId': : 아티팩트 ID 입력
Define value for property 'version':  1.0-SNAPSHOT: : (default)
Define value for property 'package':  그룹 ID : :  (default)

그룹 ID, 아티팩트 ID, 버전, 패키지 등을 차례로 입력한다. 보면 알 수 있듯이, 이것은 앞전에 프로젝트 생성할 때, 입력한 것과 동일하다. 이러한 입력하면 그대로 Java 애플리케이션 프로젝트가 만들어진다.



플러그인(plugin)

작성한 프로젝트는 Maven 명령으로 빌드 Jar 파일에 통합할 수 있었다. 그러나, 이 Jar 파일, 좀 다루기가 번거롭다. -classpath에서 Jar 파일을 지정하여, 메인 클래스를 실행해 주지 않으면 안된다. "좀 더 실행을 간단히 할 수 없을까"라고 생각한 사람도 많을 것이다. 이는 가능하다. 다만 그러기 위해서는 '플러그인'의 사용법을 알아야 한다.

Maven은 다양한 기능이 "플러그인"으로 추가되어 있다. 프로그램의 실행은 "exec-maven-plugin"이라는 플러그인으로 구현되어 있다. 이 플러그인에 대한 설정 정보를 pom.xml에 추가하여 프로그램을 실행 할 수 있다.

플러그인이라는 것은 pom.xml의 <project> 태그 안에 다음과 같은 형태로 포함된다. (※빌드에 대한 플러그인의 경우)

<build>
    <plugins>
        <plugin> ... 생략 ... </plugin>
    </ plugins>
</ build>

<build>는 빌드에 관한 설정을 기술하기 위한 것으로, <plugins>는 플러그인 설정 정보를 정리하기위한 것이다. 이 안에 <plugin>라는 태그를 사용하여, 특정 플러그인에 대한 설정을 정리하고 있다.

플러그인은 이뿐만 아니라 많이 준비되어 있다. 사실은 이미 설명한 것 중에도 플러그인을 사용한 기능은 있다. 예를 들어, "mvn compile"라는 명령은 maven-conpiler-plugin이라는 플러그인으로 구현되는 것이다. 또한 "mvn package"는 maven-jar-plugin이라는 플러그인으로 구현되어 있다.

결국은 Maven에서 사용하는 골(compile이나 package 같은 것)라는 것은 모든 플러그인으로 내장되어있는 것이다. 이것들은 <dependency> 태그 등으로 라이브러리를 다운로드할 필요는 없다. 표준으로 제대로 사용할 수 있게 되어있는 것도 있고, 없다면 필요에 따라 다운로드된다. 따로 <dependency> 태그을 준비할 필요는 없다.

<plugin> 태그

이 플러그인의 설정 정보를 기술하는 <plugin> 태그는 그 플러그인에 대한 필요한 정보를 태그에 준비해야 한다.

최소한 준비해야 하는 태그으로는 대체로 다음과 같다

<plugin>
    <groupId>그룹 ID</groupId>
    <artifactId>아티팩트 ID</artifactId>
    <version>버전</version>
    <configuration>
        ...... 설정 정보 ......
    </configuration>
</plugin>

그룹 ID, 아티팩트 ID 및 버전 같은 것은 이제 익숙할 것이다. 이것들을 사용하여 사용하는 플러그인 프로그램을 지정한다. 이 후에 <configuration> 태그는 이 플러그인을 사용하는데 필요한 정보 등을 준비하기 위한 것이다. 이것은 플러그인에 의해 기술하는 내용은 다르다(필요없는 경우도 있다).



exec-maven-plugin Java 실행

작성한 Java 응용 프로그램을 간단히 실행할 수 있도록 하는 플러그인 설정에 대해 설명한다.

프로그램의 실행은 exec-maven-plugin이라는 플러그인을 이용한다. 이 플러그인에 실행하는 응용 프로그램 클래스의 정보를 추가 기입해 두는 것으로, 프로그램을 간단히 수행 할 수 있다.

이 플러그인의 설정 정보는 다음과 같이 작성한다. (버전은 2017 년 12 월 현재 최신 버전이다)

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <configuration>
        <mainClass>실행 클래스 지정</mainClass>
    </configuration>
</plugin>

설정으로 <configuration> 태그 안에 작성해야 하는 것은 <mainClass>라는 태그이다. 이것이 실행되는 응용 프로그램의 클래스를 설정한다.

앞전에 작성한 SampleMavenApp 프로젝트에서는 com.devkuma.App라는 클래스가 메인 클래스로 되어 있었는데, 이것을 <mainClass>에 지정하면 된다.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <configuration>
        <mainClass>com.devkuma.App</mainClass>
    </configuration>
</plugin>

프로그램 실행

이제 프로그램을 실행해 보자. 이는 매우 간단한다. 프로젝트 폴더에 현재 디렉토리를 이동해서 다음과 같이 실행하면 된다.

$ mvn exec:java

그러면 <mainClass>에 지정된 클래스를 실행한다. 예제인 SampleMavenApp 프로젝트 실행을 하면 다음과 같이 출력될 것이다.

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building SampleMavenApp 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ SampleMavenApp ---
Hello World!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.703 s
[INFO] Finished at: 2017-12-13T20:59:26+09:00
[INFO] Final Memory: 7M/155M
[INFO] ------------------------------------------------------------------------

출력의 중간 쯤에 "Hello World!"라는 텍스트가 보일 것이다. 이것이 App 클래스를 실행하여 출력된 결과이다. 마지막으로 "BUILD SUCCESS"이라고 빌드 결과가 출력되고, 제대로 프로그램이 실행되는 것을 확인할 수 있다.



maven-jar-plugin 실행 가능한 Jar 생성

앞장에서 프로그램의 실행은 간단히 했지만 아직 완전하지 않다.

target 폴더에 패키지된 Jar 파일이 생성되었지만, 이를 그대로 실행하려고 하면 동작하지 않는다. 예를 들어, 아래와 같이 명령을 실행해 보자.

java -jar target/SampleMavenApp-1.0-SNAPSHOT.jar

그러면 다음과 같은 에러 메시지가 출력된다.

target/SampleMavenApp-1.0-SNAPSHOT.jar에 기본 Manifest 속성이 없습니다.

mvn package으로 생성된 Jar 파일은 실행 가능한 Jar가 아니다. 매니페스트 파일이 제대로 생성되지 않기 때문에 그대로는 사용할 수 없다.

maven-jar-plugin 설정에 대해

Jar 파일의 생성은 maven-jar-plugin이라는 플러그인에 의해 이루어 진다. 이 플러그인에 매니페스트 파일 작성을 위한 설정 정보를 추가하면 다음과 같은 형태가 된다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>메인 클래스 지정</mainClass>
                <addClasspath>true</addClasspath>
                <addExtensions>true</addExtensions>
                <packageName>패키지</packageName>
            </manifest>
        </archive>
    </configuration>
</plugin>

설정 정보를 작성하는 <configuration>안에, 아카이브에 관한 설정인 <archive> 태그가 있다. 그 안에 매니페스트 파일에 대한 <manifest> 태그가 있고, 여기에 매니페스트에 대한 정보를 작성한다. 작성하는 내용은 다음과 같다.

태그설명
<mainClass>메인 클래스를 지정한다.
<addClasspath>클래스 패스(Class-Path 값)을 추가할지 여부를 지정한다. 이것은 true로 하면 된다.
<addExtensions>확장 정보가 포함된다. 이것은 <dependencies>에 작성된 라이브러리 정보 를 내보내는 위한 것이다. 이것도 true 하면 된다.
<packageName>Jar 패키지(Package)을 출력한다.

특히 라이브러리도 사용하지 않고, SampleMavenApp와 같은 간단한 프로그램이라면 <mainClass> 만 지정하면 된다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>com.devkuma.App</mainClass>
                <addClasspath>true</addClasspath>
                <addExtensions>true</addExtensions>
                <packageName>com.devkuma</packageName>
            </manifest>
        </archive>
    </configuration>
</plugin>

이렇게 pom.xml에 작성하고, mvn package으로 Jar 파일을 생성하여 java -jar으로 SampleMavenApp-1.0-SNAPSHOT.jar을 실행해 본다. 이번에는 문제없이 실행할 수 있을 것이다.

$ java -jar target/SampleMavenApp-1.0-SNAPSHOT.jar 
Hello World!

pom.xml의 완성판

지금까지 설명했던 플러그인 정보를 추가한 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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.devkuma</groupId>
  <artifactId>SampleMavenApp</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SampleMavenApp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.6.0</version>
        <configuration>
          <mainClass>com.devkuma.App</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.0.2</version>
        <configuration>
          <archive>
            <manifest>
                <mainClass>com.devkuma.App</mainClass>
                <addClasspath>true</addClasspath>
                <addExtensions>true</addExtensions>
                <packageName>com.devkuma</packageName>
            </manifest>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

이는 Java 응용 프로그램을 작성하여 바로 실행해 보거나, 실행 가능한 Jar 파일을 만드는 경우에 기본적인 코드이다.

플러그인이 불필요하게 되면 삭제해도 상관 없다. 예를 들어, 실행 가능한 Jar를 만들 경우, exec:java으로 실행을 못해도 상관 없다면, exec-maven-plugin의 <plugin> 부분은 삭제해도 된다. 필요에 따라 수정하면서 이용하면 된다.



반응형
Tag
0 Comments
댓글쓰기 폼