////
Search
🥑

Maven

더 자세한 내용은 위의 url을 통해서 학습
알면 좋은 것들
더 자세한 maven : https://maven.apache.org/pom.html

기본

기본 라이프 사이클

1.
compile 소스 코드를 컴파일 한다.
2.
test 단위 테스트 실행 (기본설정은 단위 테스트가 실패하면 빌드 실패로 간주함)
3.
package 컴파일된 클래스 파일과 리소스 파일들을 war 혹은 jar와 같은 파일로 패키징
4.
install 패키징한 파일을 로컬 저장소에 배포 (USER_HOME/.m2)
5.
deploy 패키징한 파일을 원격 저장소에 배포 (nexus 혹은 maven central 저장소)

clean 라이프 사이클

1.
clean 메이븐 빌드를 통하여 생성된 모든 파일 삭제

site 라이프 사이클

1.
site 메이븐 설정파일 정보를 활용하여 프로젝트에 대한 문서 사이트를 생성
2.
site-deploy 생성한 문서 사이트를 설정되어 있는 서버에 배포

프로젝트 생성 및 실행

1단계 : 프로젝트 생성

기본적으로 path에 mvn이 설정되어 있어야한다는 가정
$ mvn archetype:generate -DgroupId=com.devkuma.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
Java
복사

2단계 : 확인

// 경로 설정 내 내 경로에 만든지 확인! cmd의 위치 기준 => 이건 다아실꺼니깐 스킵 c:\Users\jinmuk // 확인 목록 my-app/pom.xml my-app/src/main/java/com/devkuma/app/App.java my-app/src/test/java/com/devkuma/app/AppTest.java
Java
복사

3단계 : 응용 프로그램의 jar 작성 및 실행

$ cd myapp $ mvn package $ java -cp target/my-app-1.0-SNAPSHOT.jar com.devkuma.app.App
Plain Text
복사

인코딩 및 컴파일러 설정

이전 packaging 단계에서 경고가 나왔다. 이번에 제거할 수 있다.
//변경 전 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>com.devkuma.app</groupId> <artifactId>my-app</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>my-app</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> </project> ... //변경 후 pom.xml /* 주요 변경점 project.build.sourceEncoding : 소스 속성 파일 등의 인코딩 설정 project.reporting.outputEncoding : 보고서 등의 출력 자원의 인코딩 설정 maven.compiler.source : javac 명령 -source 설정 maven.compiler.target : javac 명령의 -target 설정 */ <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>com.devkuma.app</groupId> <artifactId>my-app</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> </project>
XML
복사

intellij 에서 사용하기

폴더 열기 및 빌드 해주기

의존성 추가

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>com.devkuma.app</groupId> <artifactId>my-app</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <!-- 추가 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <!-- 추가 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> </project>
XML
복사

App 클래스 편집

package com.devkuma.app; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class App { private static final Logger log = LoggerFactory.getLogger(App.class); public static void main(String[] args) { log.info("Hello!"); // 추가 System.out.println("Hello World!"); } }
Java
복사

실행

동일하게
$ C:\Users\jinmuk\my-app>java -cp ./target/test-version-1.jar com.devkuma.app.App
Java
복사
하던 중간에 NoClassDefFoundError 에러가 발생
찾아보니 추가된 jar이 존재하면 옵션으로 jar 경로를 다 적어줘야 했다.
(java -cp /test/lib/mysql-connector-java-5.1.14-bin.jar:/test/lib/Test-0.0.1-SNAPSHOT.jar kr.co.test.MainApplication)
uber-jar 방법 찾음
// Maven Build 시에 내가 작성한 소스 + 사용했던 jar 까지 한번에 묶는 방식 <project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> ... </project> // 출처 : https://huskdoll.tistory.com/561
XML
복사

페이즈

maven 빌드에는 라이프 사이클 개념이 있다. 라이프 사이클에는 몇 가지 페이즈가 있다.

라이프 사이클

1.
default 프로젝트 빌드 및 배포 담당
2.
clean 프로젝트의 빌드 자원 삭제 담당
3.
site 프로젝트 사이트 생성(문서)을 담당

default의 페이즈

validate
compile
test
package
verify
install
deploy

mvn 명령 및 페이즈

1. jar packaging $ mvn package // package 페이즈를 실행하게 되면 그 결과로 jar 파일 생성 // package 실행시 validate -> compile -> test -> etc 가 실행됨 2. test $ mvn test // 테스트 실행 // validate -> compile -> etc 가 실행 3. 그 외 $ mvn clean deploy // 위는 clean -> deploy 실행 // deploy 원격저장소에 복사
Java
복사

프로젝트 생성 (archetype:generate)

프로젝트 생성은 터미널을 열고 "cd {작업디렉토리}" 입력한 후 시작한다.
$ mvn archetype:generate // 프로젝트 템플릿 목록 불러오기 1000개이상 // 목록 생성 이후 enter 키를 누르면 maven-archetype-quickstart 라는 템플릿이 선택된다. ... // maven-archtype-quickstart 버전 1 : 1.0-alpha-1 2 : 1.0-alpha-2 3 : 1.0-alpha-3 4 : 1.0-alpha-4 5 : 1.0 6 : 1.1 Choose a number : 1~6 // 선택하면된다. 버전이 많다 잘찾아보고 하면된다. ... // 그룹 ID : 그룹 ID라는 프로젝트를 생성하는 개인 또는 단체를 의미 ID이다. Define value for property 'groupId': {이름 정하기} -> com.example ... // 아티팩트 ID : 아티팩트 ID는 만드는 프로젝트의 ID이다. 개발 프로그램에 할당되는 ID라고 생각하면 된다. Define value for property 'artifactId': {프로그램 이름} -> SampleMevenApp ... // 버전 : 프로그램의 버전을 지정한다. 기본적으로 "1.0-SNAPSHOT"라고 되어 있기 때문에, 이것은 그대로 할 것이기에, 아무것도 입력하지 않고 Enter 또는 Return를 누룬다. Define value for property 'version': 1.0-SNAPSHOT : {개발 버전} -> default 1.0-SNAPSHOT ... // 패키지 : 프로그램을 배치할 패키지를 지정한다. 디폴트로 그룹 ID가 그대로 설정되어 있는 것이다. 특히 문제가 없으면 그대로 Enter 또는 Return를 누른다. Define value for property 'package': com.devkuma : {배치 패키지 경로} -> 디폴트는 그룹ID ... // 입력확인 Confirm properties configuration : groupId : com.devkuma artifactId : SampleMavenApp version : 1.0-SNAPSHOT package : com.devkuma Y : //지금까지 입력한 내용이 표시된다. //문제가 없으면 그대로 Enter를 누르면 프로젝트를 만들어진다. // 문제가 있는 경우는 "n"을 입력하고 Enter/Return를 누르면 다시 입력 할 수 있다.
Java
복사

프로그램 생성 (mvn package)

$ cd {폴더명} -> 위의 예제 기준 {SampleMavenApp} $ mvn package // 실행가능한 형태인 jar 파일로 만드는 방법 /* 그럼 target 디렉토리 생성 및 SampleMavenApp 이 target 디렉토리 안에 생성된다. 또한 classes 경로에 따라서 실행을 시켜주면된다. ..여담 왜 맥이 편한지 알것같다. 경로가 눈으로 보여서 더 편한 것 같다. window는 그런기능없나?.. 경로 보기 불편... */
Java
복사

프로그램 실행

$ cd target // target 디렉토리 이동 $ java -classpath SampleMavenApp-1.0-SNAPSHOT.jar com.devkuma.App // 실행 //이는 SampleMavenApp-1.0-SNAPSHOT.jar에서 com.devkuma.App 클래스를 실행한다.
Java
복사

maven goal

package가 골을 의미한다. 결국 프로그램을 완성한다는 packaging을 한다는 의미로 받아들일 수 있기 때문이라고 생각한다.
좀 더 살펴보면 Maven에서 goal은 "처리의 역할"을 나타낸다. 어떤 역할 처리를 시킬 것인지를 지정한다. 이것이 골이다.
우리는 Maven 프로젝트를 생성할때 archetype:generate 를 실행했다. 이것도 골이다. (정확하게는 archetype은 플러그인으로 플러그인의 generate라는 목표를 시행한 것)
결국 각 명령 마다의 골이 있고 지금의 단계에서는 기본 골만 알아두기로 한다.
기본 골은 위의 package, compile, test-compile, test, clean 등이 있다.

maven의 핵심 pom.xml

Maven의 핵심은 프로젝트 관리다. 프로젝트 관리에는 라이브러리, 프레임워크 등을 이용하는 경우도 있고 프로젝트의 버전을 관리하는 것도 있다. 이 모든 것이 프로젝트 관리이다. 이것을 이해하기 위해서는 Maven 명령어만 알아서는 안된다. 중요한 "빌드 파일" 을 이해할 필요가 있다.
pom.xml이란?
Pom은 "Project Object Model"의 약자다 프로젝트 객체 모델의 약자로, 프로젝트의 다양한 정보를 처리하기 위한 객체 모델이다. pom.xml은 말그대로 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> </project> ... // 불필요한 것을 제거한 후 <project ... 중략 ...> <modelVersion>4.0.0</modelVersion> <groupId>그룹 ID</groupId> <artifactId>아티팩트 ID</artifactId> <version>버전</version> <packaging>jar</packaging> <name>이름</name> <properties> ...... 속성 정보 ...... </properties> <dependencies> ...... 의존 라이브러리 정보 ...... </dependencies> </project> /* pom.xml은 <project> 라는 루트 태그 내에서 모든 정보를 기술한다. <project>는 xmlns / xmlns:xsi / sxi : schemaLocation 세세한 것들이 속성으로 여러 붙어 있는데, 이들은 모두 정해진 값이므로, 복사해서 쓰면 된다고 생각하면 된다. 필요에 따라 수정할 부분은 없다. ...여담 옛날에 처음 spring 프로젝트를 만질때 xmlns / xmlns:xsi / sxi :schemaLocation을 외워 서 사용했다. 바보같은 삽질을 했다.... 그 당시 블로그 등을 찾아볼 수준이라 정보력이 좋 지 못했다. 그래서 이걸 알아야하는데 방법이 없어서 이렇게 사용했다... 누구를 가르쳐줄때는 꼭 이점을 알려줘야겠다. */
XML
복사

프로젝트 기본 속성

<project> 태그 이후 프로젝트에 대한 기본 속성을 설정하는 태그들이 있다. 이것은 어떤 프로젝트도 대부분 필요하며, 역할을 어느정도 기억해두자
// pom 모델 버전이다. "4.0.0" 라고 설정한다. 당분간이 버전이 바뀔 것은 없다. /* ...여담 https://maven.apache.org/pom.html 여기 들어가면 quick overview에서 버전을 볼 수 있다. 아직 4.0.0 버전이다. 가끔 다른 버전 충돌도 있다. 기억해두면 좋다. */ <modelVersion>4.0.0</modelVersion> ... // 그룹 ID이다. 프로젝트를 만들 때 입력했다. 제작자와 회사, 단체 등을 식별하기 위한 것이다. <groupId> 그룹 ID </groupId> ... // 아티팩트 ID는 프로젝트에 할당한 고유 ID 이다. <artifactId>아티팩트 ID</artifactId> ... // 프로그램 버전이다. 기본적으로 1.0-SNAPSHOT이 설정되어 있다. <version> 버전 </version> ... // 패키지 종류로 jar 또는 zip을 지정한다. Web 어플리케이션의 개발은 war를 지정할 수도 있다. <packaging>jar</packaging> ... // 프로그램 이름이다. 아티팩트 ID를 그대로 지정하는 것이 많을 것이다. <name>이름</name> ... // 프로젝트와 관련된 Web 사이트의 주소이다. // 기본적으로 Apache Maven의 Web 사이트의 주소가 지정되어 있다. <url>주소</url> ... // pom.xml에서 사용하는 속성 값 등을 모아 둔다. 이것은 필요에 따라 기술한다. // 기본적으로는 아래에 하나만 포함되어 있다. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> // 인코딩 // custom 하는 방법 <properties> ...... 속성 정보 ...... </properties> ... // "의존 라이브러리"라고 하는 것은 이 프로그램이 참조하는 라이브러리이다. // Java 기본 시스템 라이브러리는 제외한다. <dependencies> ...... 의존 라이브러리 정보 ...... </dependencies> /* 최후에 <properties><dependencies>를 제외하고, 프로젝트를 만들 때 입력한 것이 많다. 각각의 항목은 프로젝트를 만들 때 자동으로 기록되어 있기 때문에, 자신이 편집하는 일은 거의 없다. 역할 정도 알고 있으면 충분하다. */
XML
복사

<dependencies>와 <dependency>

기본적으로 생성된 pom.xml의 기술에서 하나 뿐인 매우 태그가 복잡한 부분이 이것이다. 필자도 처음 spring을 할때 설정 방법을 몰라서 엄청 고생하고 boot를 공부하고 메커니즘을 알았다...
"이것은 이미 언급한 바와 같이 의존 라이브러리 정보를 기술해 두기 위한 것이다. 하지만, 이 기술하는 태그가 많은 계층적으로 되어 있기 때문에, 상당히 이해하기 어려울지도 모른다. 이 태그는 기본적으로 다음과 같은 형태로 기술되어 있다."
<dependencies> <dependency>... 생략 ...</dependency> // 하나씩 의존성이 추가된다. <dependency>... 생략 ...</dependency> ...... 중략 ...... </dependencies> /* <dependencies>은 의존 라이브러리를 한곳에 모아 기술하기 위한 것이다. 각각의 의존 라이브러리 정보는 <dependency> 태그를 사용하여 작성한다. 이 <dependency> 태그를 필요한만 큼 <dependencies> 태그 안에 기술한다. ...여담 <dependencies> 얘 안에 </dependency> 얘가 들어간다. 또한 </dependency> 얘안에 그룹, 아티팩트, 버전, 스코프가 들어간다. */ // 최종형태 <dependencies> <dependency> <groupId>그룹 ID</groupId> <artifactId>아티팩트 ID</artifactId> <version>버전</version> <scope>범위</scope> </dependency> </dependencies>
XML
복사

DarchetypeAtifactId 지정

Maven은 우리에게 다양한 프로그램을 만들 수 있도록 도와준다. 하지만 우리가 만들고 싶은 프로그램의 기능은 다양하고 추가해야하는 라이브러리, 프레임워크 등이 다르고 이를 작성하는 단계 또한 다르다. 그래서 자신이 만들고자 하는 프로그램을 어떻게 만들지에 대해서 알아야한다.

특정 프로젝트 만들기 (java)

"Maven으로 프로젝트를 만들 때에 "mvn archetype:generate"라는 커멘드를 실행했었다. 이것은 프로젝트 생성의 가장 기본이 되는 것이다. 하지만 이것을 실행하면, 템플릿 목록이 길게 나열된다. "여기에서 사용하는 템플릿을 선택"하는 것이지만, 이미 1000개 이상의 항목이 있기 때문에 선택하기에 매우 힘들다."
"프로젝트를 만들 때, 사용하는 템플릿을 미리 지정해 둘 수 있다. 이것은 - DarchetypeArtifactId라는 옵션을 사용한다."
$ mvn archetype:generate -DarchetypeArtifactId={아티팩트ID}
Java
복사
"우연히 같은 아티팩트 ID 템플릿이 여러 개가 있는 것 같은 경우도 있다. 이럴 때는 그룹 ID를 지정하는 -DarchetypeGroupId라는 옵션도 준비되어 있다."
$ mvn archetype:generate -DarchetypeGroupId={그룹ID} -DarchetypeArtifactId={아티팩트ID}
Java
복사

기본은 maven-archetype-quickstart

// java 프로그램을 개발할 때는 기본적으로 아래와 같다. $ mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart /* 입력 groupId : com.example artifactId : mavenQuickstartJava version : {1.0-SNAPSHOT} // 기본값 package : // groupId을 따라감 */
Java
복사
실행 결과

플러그인 (plugin)

작성한 프로젝트를 Maven 명령으로 빌드 jar 파일에 통합할 수 있었다. 하지만 jar 파일은 다루기 번거롭고 -classpath에서 jar 파일을 지정하여, 메인 클래스를 실행해야 했다. (아래의 형태)
$ java -classpath .\target\mavenQuickstartJava-1.0-SNAPSHOT.jar com.example.App
Java
복사
여기서 메인 클래스를 찾아 실행하는 점이 불편하여 "좀 더 간단하게 실행할 수 없을까"라고 생각했다. 이를 간단하게 실행하는 방법이 plugin이다.
Maven은 다양한 기능이 플러그인으로 추가되어 있다. 그 중 프로그램의 실행은 "exec-maven-plugin"이라는 플러그인으로 구현되어있다.

<plugin> 태그

// pom.xml의 <project> 태그 내부에 정의 <build> <plugins> <plugin> ... 생략 ... </plugin> -> 이부분에 세부적인 플러그인 기제 </plugins> </build> ... <plugin> <groupId>그룹 ID</groupId> <artifactId>아티팩트 ID</artifactId> <version>버전</version> <configuration> ...... 설정 정보 ...... </configuration> </plugin>
XML
복사

exec-maven-plugin Java 실행

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> // 가장 최신 버전 (2021-03-01 기준) <configuration> <mainClass>com.example.App</mainClass> // 내 프로젝트 기준 </configuration> </plugin>
XML
복사
// 매우간단하게 실행 가능 $ mvn exec:java // 이전 실행 방법과 비교 $ java -classpath .\target\mavenQuickstartJava-1.0-SNAPSHOT.jar com.example.App
Java
복사

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

빌드도 마치고 실행도 되는데 왜 다시 실행 가능한 jar을 만들어야할까?
// 다음과 같이 실행해보자 $ java -jar .\target\mavenQuickstartJava-1.0-SNAPSHOT.jar ... result : .\target\mavenQuickstartJava-1.0-SNAPSHOT.jar에 기본 Manifest 속성이 없습니다. 라고 나온다.. 이말인 의미는 jar파일이 실행가능한 상태가 아니라는 의미다.
Java
복사
"Jar 파일의 생성은 maven-jar-plugin이라는 플러그인에 의해 이루어 진다. 이 플러그인에 manifest파일 작성을 위한 설정 정보를 추가하면 다음과 같은 형태가 된다."
manifest = maven-jar-plugin ← 얘가 만들어준다!!!!!!
// manifest 파일 설정 <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> // (2021-03-01 기준) <configuration> <archive> <manifest> // 여기 manifest 태그!! <mainClass>com.example.App</mainClass> // 풀 패키지 경로 com.example.App <addClasspath>true</addClasspath> <addExtensions>true</addExtensions> <packageName>com.example</packageName> </manifest> </archive> </configuration> </plugin> /* "설정 정보를 작성하는 <configuration>안에, 아카이브에 관한 설정인 <archive> 태그가 있다. 그 안에 manifest 파일에 대한 <manifest> 태그가 있고, 여기에 manifest에 대한 정보를 작성 한다." */
XML
복사
Search
태그
설명
클래스 패스(Class-Path 값)을 추가할지 여부를 지정한다. 이것은 true로 하면 된다.
확장 정보가 포함된다. 이것은 <dependencies>에 작성된 라이브러리 정보를 내보내는 위한 것이다. 이것도 true 하면 된다.
Jar 패키지(Package)을 출력한다.
// manifest 설정이후 결과 PS C:\Users\Desktop\mavenQuickstartJava> java -jar target\mavenQuickstartJava-1.0-SNAPSHOT.jar result : Hello World!
Java
복사
최종 버전 보기 pom.xml
MANIFEST.MF 파일을 이용하는 방법

Web 응용 프로그램 생성

JSP 기반 보기
Spring boot 기반 보기
Spring legacy
알아두면 좋은 was

자체 라이브러리 프로젝트 생성

프로젝트 생성 및 실행
maven을 다 배운 것은 아니다. 확실한건 이제는 maven 사용을 무서워 하지 않아도 된다는 점이다. 앞으로도 더 많이 배워야하고 특히 maven 외에 다른 빌드툴을 공부해야 할 필요성이 있다고 느끼고 있다.