maven 정리

Lifecycle

  • default(build) : 일반적인 빌드 프로세스를 위한 모델이다.
  • clean : 빌드 시 생성되었던 파일들을 삭제하는 단계
  • validate : 프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는지 확인하는 단계
  • compile : 프로젝트의 소스코드를 컴파일 하는 단계
  • test : 유닛(단위) 테스트를 수행 하는 단계(테스트 실패시 빌드 실패로 처리, 스킵 가능)
  • pacakge : 실제 컴파일된 소스 코드와 리소스들을 jar, war 등등의 파일 등의 배포를 위한 패키지로 만드는 단계
  • verify : 통합 테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인하는 단계
  • install : 패키지를 로컬 저장소에 설치하는 단계
  • site : 프로젝트 문서와 사이트 작성, 생성하는 단계
  • deploy : 만들어진 package를 원격 저장소에 release 하는 단계

pom.xml

<?xml version="1.0" encoding="UTF-8"?> 
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion> <!--POM model의 버전-->
    <parent> <!--부모 프로젝트정보를 적는다. 부모프로젝트에 dependencyManagement를 통해 버전이 명시되어있다면 자식 프로젝트에는 버전을 명시할 필요가 없다.--> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-parent</artifactId> 
        <version>2.2.4.RELEASE</version> 
        <relativePath/> <!-- lookup parent from repository --> 
    </parent> 
    <groupId>com.thevruk</groupId> <!--프로젝트 groupId, 조직의 Id, 혹은 도메인-->
    <artifactId>sample</artifactId> <!--해당 프로젝트의 이름. groupId 내에서 유일해야 함. 빌드시 [artifactid-version.packaging] 파일명으로 생성됨. 위 예의 경우 빌드할 경우 sample-0.0.1-SNAPSHOT.war 파일이 생성된다.--> 
    <version>0.0.1-SNAPSHOT</version> <!--프로젝트의 현재 버전, 프로젝트 개발 중일 때는 SNAPSHOT을 접미사로 사용--> 
    <packaging>war</packaging> <!--패키징 유형(jar, war, ear 등)--> 
    <name>sample</name> <!--프로젝트, 프로젝트 이름--> 
    <description>Demo project for Spring Boot</description> <!--프로젝트에 대한 간략한 설명-->
    <url>https://kkang32.github.io</url> <!--프로젝트에 대한 참고 Reference 사이트--> 
    <properties> <!-- 해당 pom파일에서 사용될 property를 관리한다. 버전 등에서 사용된다. --> 
        <java.version>1.8</java.version> 
    </properties> 
    <dependencies> <!--프로젝트에서 사용될 의존성을 설정한다.--> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-web</artifactId> 
        </dependency> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-tomcat</artifactId> 
            <scope>provided</scope> 
        </dependency> 
        <dependency> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-starter-test</artifactId> 
            <scope>test</scope> 
            <exclusions> <!-- 설정된 의존성 내에서도 다른 라이브러리 들을 참조한다. 참조중인 라이브러리를 제거하고 직접 설정한 라이브러리를 사용하고 싶을때 제외 설정을 한다. 이후 본인이 사용하고자 하는 라이브러리를 dependency로 설정한다. -->
                <exclusion> 
                    <groupId>org.junit.vintage</groupId> 
                    <artifactId>junit-vintage-engine</artifactId> 
                </exclusion> 
            </exclusions> 
        </dependency> 
    </dependencies> 
    <build> <!--빌드에 사용할 플러그인 목록--> 
        <plugins> 
            <plugin> 
                <groupId>org.springframework.boot</groupId> 
                <artifactId>spring-boot-maven-plugin</artifactId> 
            </plugin> 
        </plugins> 
    </build> 
</project>

  • scope

    • compile :
      • 기본 scope. 미입력시에도 기본 적용
      • 모든 상황에서 포함됨
    • provided :
      • compile과 유사하게 모든 상황에서 수행된다
      • 하지만, 다른 외부 컨테이너에서 기본 제공되는 API인경우 provided로 지정 시 마지막 패키징할 때 포함되지 않음
      • 예를 들면 tomcat에서 기본적으로 servlet api를 제공하기 때문에 servlet api를 provided로 지정하면 패키징시 제외된다.
    • runtime :
      • 컴파일 시에는 불필요 실행시에 필요한 경우.
      • 런타임 및 테스트 시 classpath에 추가 되지만, 컴파일시에는 추가 되지 않음
    • test : 테스트시에만 사용
    • system :
      • provided와 유사
      • system의 특정 path를 참조하도록 지정
      • Maven의 central repository를 사용하지 않음
    • import :
      • scope는 dependencyManagement 섹션에서 pom의 의존관계에 대해 사용
  • dependencyManagement

    • 자신을 parent로 지정한 pom파일에서 dependency정보를 매니징 하기위해 설정한다.

      부모 pom.xml
      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>org.springframework.data</groupId>
                  <artifactId>spring-data-jpa</artifactId>
                  <version>${spring.data.version}</version>
              </dependency>
          </dependencies>
      </dependencyManagement>
      ..
          
      자식 pom.xml
      <dependency>
          <groupId>org.springframework.data</groupId>
          <artifactId>spring-data-jpa</artifactId>
      </dependency>
      
    • 또한 복잡한 라이브러리들의 경우(spring같은) bom(bill of materials) 프로젝트를 제공하여 같은 groupid로 묶이는 dependency들의 버전을 명시 하지 않아도 되도록 한다

      <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-data-bom</artifactId>
                  <version>${spring.version}</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
  • module

    • 여러기능으로 분리된 프로젝트를 모듈로 만들경우 사용한다.

    • 동일한 dependency정책을 사용하기위해 dependencyManagement태그도 함께 사용한다.

    • main 프로젝트

      <groupId>com.thevruk</groupId>
      <artifactId>parent</artifactId>
      <packaging>pom</packaging>
      <version>1.0-SNAPSHOT</version>
          
      <modules>
          <module>admin</module>
          <module>core</module>
          <module>front</module>
      </modules>
      
    • 동일 폴더에 하위 프로젝트들을 추가하고 해당 프로젝트에는 main프로젝트를 parent로 설정한다.

      <parent>
          <groupId>com.thevruk</groupId>
          <artifactId>parent</artifactId>    
          <version>1.0-SNAPSHOT</version>
      </parent>
      <modelVersion>4.0.0</modelVersion>
      <artifactId>admin</artifactId>
      
  • javadoc

    • 자동으로 javadoc문서를 생성해 준다.
    • 아래 pom.xml파일에 플러그인 설정을 해준다.
    • 빌드시 mvn javadoc:javadoc 으로 문서를 생성하며 target/site내에 문서들이 생성된다.
    <build>
            <resources>
                ...
            </resources>
      
            <plugins>
                ...
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <configuration>
                        <locale>ko_kr</locale>
                        <encoding>utf-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    • 문서 생성은 소스에 작성된 주석 기준으로 작성되기 때문에 아래 주석 규칙으로 작성한다.

    • 클래스

      /**
       * 설명
       *
       * @author [작성자명]
       */
      public class Something {
          
          
          
      }
      
    • 필드(필드는 javadoc대상이 아니다. 그치만 주석 남기는 김에 남겨준다..)

          
      public class Something {
             
          //데이터를 저장하는 변수
      	private String str;
          
          
      }
      
      • lombok을 사용하므로 해당 변수의 getter와 setter에 상세한 내용을 남기고 싶을 경우 아래와 같이 필드에 @param@return을 작성해 준다.

              public class DemoBoard {
                  /**
                   * 문서 번호 
                   *
                   * @param docId 문서번호
                   * @return 문서 번호
                   */
                  private int docId;
        
    • 메서드

      • IDE에서 자동으로 생성해주는 기능을 활용
        • 아래의 주석을 추가해야 하는 항목이 있을 경우에만 작성. 여러줄로 작성 가능
        • 메서드 설명은 필수.
        • @param : 매개 변수에 대한 설명
        • @return : 반환값에 대한 설명
        • @throws : throw되는 exception 들에 대한 설명(여러개 작성 가능)
          
      public class Something {
          /**
           * 메서드 설명
           * 
           * @param data 공통모듈이 확인할 데이터
           * @return 공통값 반환
           * @throws NullPointerException 데이터가 없을때 발생한다.
           */
          public Common getBean(String data) throws NullPointerException {
             ....
              return applicationContext.getBean(Common.class);
          }
      }
      
  • profile

    • 소스 구동환경별로 리소스 파일을 분리 시킬 경우 사용한다.

    • 가령 application.properties 파일내 DB접속 문자열이 로컬/개발/운영 환경이 서로 다르다면 각 파일을 아래와 같이 다른 디렉토리에 넣어 놓고 빌드시 옵션으로 다르게 빌드 되도록 한다.

      • 개발PC : src\main\resources 참조
      • 개발서버 : src\main\resources-dev 참조
      • 운영서버 : src\main\resources-prod 참조
      
      ...
      <profiles>
          <profile>
              <id>dev</id>
              <properties>
                  <environment>dev</environment>
              </properties>
          </profile>
        
          <profile>
              <id>prod</id>
              <properties>
                  <environment>prod</environment>
              </properties>
          </profile>
      </profiles>
      ...
      <build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <excludes>
                        <exclude>**/*.java</exclude>
                    </excludes>
                </resource>
      
                <resource><!-- 리소스 적용 우선순위를 잘 판단해서 설정한다. -->
                    <directory>src/main/resources-${environment}</directory>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                </resource>
            </resources>
      </build>
    
          
          [로컬]
          mvn clean package
            
          [개발서버]
          mvn clean package -P dev
            
          [운영서버]
          mvn clean package -P prod
           
    
  • build

    • finalName : 빌드 결과물 이름 설정

    • resources : 리소스 위치 지정

      • resource : 없다면 기본 src/main/resources

        <build>
        	<resources>
            	<resource>
                	<directory>src/main/resources</directory>
                </resource>
            </resources>
        </build>
        
    • sourceDirectory : 컴파일 대상 소스 위치 지정

    • outputDirectory : 컴파일한 결과물 위치지정(target/classes)

    • testResources : 테스트 리소스 지정

      • testResource : 없다면 src/test/resources

        <build>
        	<testResources>
            	<testResource>
                	<directory>src/test/resources</directory>
                </testResource>
            </testResources>
        </build>
        
    • testSourceDirectory : 테스트 소스 파일 위치

    • testOutputDirectory : 테스트 소스를 컴파일한 결과물 위치값 지정(target/test-classes)

    • plugins

      • plugin : 어떠한 액션 하나를 담당하는 것으로 가장 중요하지만 들어가는 옵션은 제 각각이다. 다행인 것은 플러그인 형식에 대한 것은 안내가 나와있으니 그것을 참고해서 작성하면 된다.
      • https://wikidocs.net/18346

실행가능한 jar만들기

  • 별도의 jar파일로 동작시키기 위해 실행가능한 jar파일을 생성한다.
  • 이 경우 maven 의존성설정된 라이브러리 파일들이 모두 함께 jar파일에 포함이 되므로 용량이 클 수 있다.
  • 만약 해당 jar가 다른 프로그램에 의해 동작된다면(jmeter backendlistener같은..) 해당 프로그램에서 로드되는 라이브러리를 이용할 수 있으므로 어떤 라이브러리들이 사용가능한지 살펴 보고 dependency scope를 provided로 설정 해 준다.

  • pom.xml

    <build>
    		<finalName>${project.artifactId}</finalName>
      
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-assembly-plugin</artifactId>
    				<executions>
    					<execution>
    						<phase>package</phase>
    						<goals>
    							<goal>single</goal>
    						</goals>
    					</execution>
    				</executions>				
      
    			</plugin>
      
    		</plugins>
      
      
    	</build>
    
  • assembly-descriptor-bin.xml

  • 위치는 src아래에 올 수 있도록 한다.
  <assembly
  	xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/3.0.0"
  	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  	xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/3.0.0 http://maven.apache.org/xsd/assembly-3.0.0.xsd">
  
  	<id>jar-with-dependencies</id>
  	<formats>
  		<format>jar</format>
  	</formats>
  	<includeBaseDirectory>false</includeBaseDirectory>
  	<dependencySets>
  		<dependencySet>
  			<outputDirectory>/</outputDirectory>
  			<useProjectArtifact>true</useProjectArtifact>
  			<unpack>true</unpack>
  			<scope>runtime</scope>
  			<excludes>
  			</excludes>
  		</dependencySet>
  	</dependencySets>
  
  </assembly>

archetype

  • http://maven.apache.org/guides/mini/guide-creating-archetypes.html

기본 제공 properties

  • target 폴더
    • ${project.build.directory} = ${pom.build.directory}
  • target/classes 폴더
    • ${project.build.outputDirectory}
  • 프로젝트 이름
    • ${project.name} = ${pom.name}
  • 프로젝트 버전
    • ${project.version} = ${pom.version} = ${version}
  • 최종파일이름
    • ${project.build.finalName}
  • 환경변수 - 시스템Path
    • ${env.PATH}
  • 환경변수 = JAVA_HOME
    • ${env.JAVA_HOME}
  • pom.xml이 위치하는 폴더
    • ${basedir}