Tagged: maven

Maven 저장소 URL 변경하기

Maven 3 을 쓰다보면  Update나 Build 시에 Maven은 어딘서가 의존성 패키지를 다운받는다. 다운받은 파일을 어디에 저장할 것인가 를 지정하는것이 localRepository 이다.

문제는 어딘가에서 받아오는 저장소 URL 이 간혹 접속이 불가할 경우가 문제가 된다. 나 같은 경우에 일하고 있는 사무실 환경에서는 어찌된 영문인지 Maven이 패키지를 제대로 가지고 오지 못하고 있었다. 원인은 “Connection Time Out” 으로서 “https://repo.maven.apache.org/maven2” 에 접속이 되지 않아 발생 했다. 자세히 보니 https 로 접속이 안되는 문제였다.

이와같이 접속이 불가능 할 경우에는 Maven 저장소 URL 을 바꿀 필요가 있다.

pom.xml 에서 바꾸기

일차적인 방법으로는 프로젝트의 pom.xml 파일에서 저장소 위치를 지정하는 것이다. 먼저 저장소 위치가 어떻게 되는지 알수가 있다. 그것은 Eclipse 에서 pom.xml 을 열면 편집영역 하단에 “Effective POM” 탭이 보인다. 여기서 중간쯤에 보면 다음과 같은 저장소 URL 이 보인다.

Maven 3 에서 기본 세팅된 저장소 URL 을 살펴 볼수 있다.

아니면 pom..xml 이 있는 프로젝트 디렉토리에서 다음과 같은 명령어로 Effective POM 상태를 출력해 볼 수 있다.

이제 기본적인 저장소 URL 을 알았으니 이것을 바꿔보자. pom.xml 탭을 클릭해 다음과 같이 바꿔보자.

이렇게 하면 Maven의 기본 저장소 URL을 변경이 된다.

Maven settings.xml 설정 파일에서 바꾸기

만일 프로젝트가 아주 많이 있다면 일일이 프로젝트마다 앞에 방법대로 pom.xml 을 수정한다는 것이 바보같은 짓이된다. 이럴때에는 Maven의 설정 파일인 settings.xml 에서 설정 해주면 된다.

다음과 같이 설정 해준다.

이렇게 변경 후 저장하고 Eclipse 를 재시작하면 모든 프로젝트에 Effective POM 을 보면 저장소 위치가 변경된 것을 확인할 수 있다.

Maven 다중 모듈 프로젝트 구성

STS Eclipse를 이용하면 손쉽게 Spring MVC 프로젝트를 구성할 수 있다. Spring MVC 프로젝트에는 Java 파일과 Web Content 파일을 모두 포함한다. 이를 Dynamic Content, Static Content 등로 구분하기도 한다.

문제는 이렇게 하나의 프로젝트에 모든 것을 담을 경우에 다음과 같은 문제가 발생할 수 있다.

  • 분리 배포가 불가능 하다. 요즘에는 WAS 앞에 Web 서버를 따로 두어 Static Content 를 서비스 하는 아키텍쳐가 많은데 하나의 프로젝트에 모든 것을 담게 되면 분리 배포가 어렵다.

단 하나의 큰 문제인데 이 문제를 가볍게 여길 수 없다. 실제 프로젝트를 할때에 이것을 간과해 나중에 아주 힘들어지는 경우가 허다 하다.

그래서 Spring MVC 기반의 프로젝트를 할때에는 Dynamic Content, Static Content를 분리해 진행하는 것이 좋은데, Maven 에서는 이를 ‘다중 모듈 프로젝트 구성’ 이라는 기능으로 제공하고 있다.

Root 프로젝트 생성

다중 모듈 프로젝트를 생성하는 첫번째는 Root 프로젝트 생성이다. 이름에서도 알수 있듯이 이 모든 모듈 프로젝트에 뿌리가 되는 프로젝트를 말한다.

이는 ‘Maven Project’ 를 통해서 생성 할 수 있다.

Maven Project 생성
Maven Project 생성

위와같이 Maven Project를 통해서 생성할때 한가지 주의해야 하는 것이 있는데, Pakaging 형태를 pom으로 해야만 한다. Root 프로젝트는 하위 프로젝트에 기반을 제공하는 것으로 별도 was 배포용 패키지를 만들지 않는다.

Root Project 에 pom Packaging
Root Project 에 pom Packaging

이렇게 하면 Root Project가 생성이 된다.

이 상태를 그대로 두고 Static Content를 위한 하위 프로젝트를 먼저 생성한다.

하위 프로젝트 생성(Static Content)

Static Content 를 위한 하위 프로젝트는 오로지 CSS, Java Script, Images 만을 위한 것이여서 Spring Mvc 샘플 프로젝트를 만들 필요는 없다. 간단하게 Maven Module 로 제작하면 된다.

앞에서 생성한 Root Project 에서 마우스 오른쪽 버튼을 눌러 Maven Module 생성하기를 시작한다. 그리고 다음과 같이 ‘maven-archetype-webapp’ 를 선택해준다.

Maven 으로 webapp 생성
Maven 으로 webapp 생성

이렇게 하면 Root Project 밑에 디렉토리로 하위 프로젝트가 위치하는게 보이고 이와 별도로 이클립스에 프로젝트로도 보인다.

Root 와 Static 프로젝트 모습
Root 와 Static 프로젝트 모습

Static 프로젝트에 pom.xml 를 보면 Root 프로젝트와 연결된 설정이 보인다.

이제 Static 의 디렉토리 구조를 바꾼다. 이는 이전에 글을 참고 하면 잘 나와 있는데 여기서는 WebContent 디렉토리만 인식시켜주면 되기 때문에 pom.xml 에 설정해주고 파일을 옮기면 된다.

그리고 Static 파일을 위한 디렉토리를 생성한 다음에 가짜 파일을 하나 만든다.

Static 파일을 위한 CSS, JS, Images 디렉토리 생성
Static 파일을 위한 CSS, JS, Images 디렉토리 생성

이렇게 한 후에 Build 를 하면 WebContent 이하 디렉토리 내용이 war 파일로 작성되어 진다. war 파일이긴하지만 Static만 있으면 되기 때문에 이 Static 파일만 담기도록 해보자. pom.xml 을 다음과 같이 수정 한다.

** 위와같이 설정해도 원하는데로 동작하지 않습니다. 아신다면 덧글 남겨 주시면 고맙겠습니다. **

이렇게 한 후에 SystemVLabs-Static 에 빌드를 하면 WebContent 디렉토리에 내용들이 war로 만들어진다. 또, RootProject 에서 빌드를 하면 하위 모듈로등록된 SystemVLabs-Static 도 빌드가 되면 정상적으로 프로젝트가 세팅된 것이다.

하위 프로젝트 생성(Dynamic Content)

이제 Dynamic Content 를 위한 하위 모듈 프로젝트를 생성해야 한다. 이는 여러 방법이 존재하는데, 내가 보기에 가장 손쉬운 방법을 설명하고자 한다.

먼저 STS Eclipse 의 Spring MVC 샘플 프로젝트를 생성한다. 그러면 기존의 RootProject와는 별도로 프로젝트가 생길 것이다.

Spring5 샘플 프로젝트
Spring5 샘플 프로젝트

이제 이것을 export 를 해주는데, File System 으로 export 를 한다.

Export를 File System 으로 한다.
Export를 File System 으로 한다.

대상 디렉토리는 RootProject 로 지정한다.

Spring5의 RootProject 로 Export
Spring5의 RootProject 로 Export

이렇게 한 후에 RootProject 를 ReFresh 하면 방금 Export 한 Spring5 디렉토리가 보인다.

이제 기존의 Spring5 프로젝트는 디스크에서 삭제도 체크해  삭제한다. 그리고 이제 프로젝트를 Import 한다.

Existing Project into Workspace
Existing Project into Workspace

“Existing Projects into Workspace” 를 선책하고 Next,

Export된 Spring5 디렉토리 지정
Export된 Spring5 디렉토리 지정

이렇게 하면 RootProject 하위가 아닌 독립된 프로젝트로 나타난다.

마지막으로 RootProject 의 pom.xml 에 방금 등록한 하위 모듈 프로젝트로 등록해 준다.

그리고 새로 등록한 하위 모듈 프로젝트의 pom.xml 에는 parent 모듈을 등록해 준다.

이렇게 함으로써 Dynamic Content 를 하위 모듈 프로젝트 등록은 다 된 것이다.

 

Tomcat plugin 을 이용한 배포.

만일 WAS 서버를 Tomcat 을 이용해 개발을 하고 있다면 Maven tomcat7 플러그인을 이용해서 배포를 할 수 있다. 참고로 이클립스의 tomcat add-on 과는 다른 것이다. 이것은 Tomcat 에서 제공하는 Manager 기능을 이용한 것이다.

그리고 이 문서의 내용은 Tomcat 8 버전에서도 이용 가능 하다.

Tomcat 설정

Tomcat 의 Manager 기능을 이용하는 것이여서 Tomcat Manager 설정을 먼저 해줘야 한다. 아시겠지만 Manager 접근을 위해서는 인증 설정을 해줘야 하는데 이 인증은 Tomcat 의 ㅊCATALINA_HOME/conf/tomcat-users.xml 파일을 다음과 같이 설정 해준다.

Tomcat 방화벽 설정

앞서 설정을 한다고 해도 원격에서 Manager 접속은 불가능 하다. 왜냐하면 Tomcat 자체에 Manager 접속을 로컬호스트만 허용하도록 되어 있기 때문이다. 이것은 “CATALINA_HOME/webapps/manager/META-INF/context.xml” 파일에 설정되어 있다.

위 설정을 보면 ‘192.168.96.2,192.168.96.3’ 두개의 원격아이피가 허용되어 있다.

이 설정은 매우 중요하다. 모든 설정이 정상인데도 배포 실패가 나온다면 이 설정을 잘 살펴봐냐 한다.

Maven 설정(pom.xml)

이제 pom.xml 설정을 해야 한다. Maven 에서는 Tomcat Manager 에 원격 접속해 배포할수 있도록 도와주는 플러그인을 제공하는데 그 설정은 다음과 같다.

package tomcat7:[deploy|undeploy|redeploy]

tomcat7 maven 플러그인은 위 주제와 같이 사용하면 된다. Maven Build 시에 위 내용을 입력하면 설정한 Manager URL 로 배포 파일을 업로드 해주는데 이때 업로드 되는 파일 이름은 path 설정 이름으로 된다.

스프링 디렉토리 구조 재정의하기

이클립스(Eclipse)에서 STS 를 설치하면 아주 간단하게 Spring MVC 샘플 프로젝트를 생성할 수 있다. 이 샘플 프로젝트의 디렉토리는 다음과 같다.

Directory Structure of Spring MVC
Directory Structure of Spring MVC

엄밀히 말하면 사실 이 디렉토리 구조는 Maven 이 관리 한다. Maven 에서는 기본적으로 Java 소스 디렉토리, Resource 디렉토리, webapp 디렉토리를 위와  같이 정의해 놓고 있다. STS 의 Spring MVC 샘플 프로젝트도 Maven을 기반으로 만들어 졌기 때문에 위와 같은 디렉토리 구조를 가진다.

하지만 한국에서는 다음과 같은 디렉토리 구조를 주로  사용한다.

완성된 디렉토리 구조
완성된 디렉토리 구조

webapp 의 루트(root) 디렉토리를 WebContent 로 바꾸고 스프링의 설정 파일인 root-context.xml, servlet-context.xml 를 Resource 디렉토리의 config 디렉토리 아래로 옮겨준다.

이러한 구조로 바꾸기 위해서는 Maven 설정을 만줘져야 하는데, 이클립스를 이용하면 손쉽게 위와같은 구조로 변경할 수 있다.

WebContent 디렉토리 생성

webapp 디렉토리를 WebContent 로 바꾸기 위해서는 먼저 디렉토리를 만들어야 한다. 이클립스에서 프로젝트 아이콘에서 오른쪽 버튼을 클릭해서 WebContent 를 만들어 준다.

생성이 되었다면 이제 기존의 webapp 디렉토리 아래에 모든 디렉토리와 파일을 WebContent 디렉토리로 옮겨준다. 그리고 webapp 디렉토리를 삭제해 준다.

webapp 파일 옮기기
webapp 파일 옮기기

이렇게 옮겨 놓고 보면 pom.xml 파일이 오류가 난다. 오류의 내용은 다음과 같다.

Maven 에서 정해진 위치에 있어야 할 web.xml 이 없기 때문에 나오는 오류다. 따라서 Maven 에서 web.xml 디렉토리 위치를 바꿔 주면 되는데 먼저 pom.xml 에 maven-war-plugin 를 추가해 준다.

그리고 이클립스에 설정으 바꿔 줍니다. 프로젝트이름에서 마오스 오른쪽 클릭 후에 ‘Properties -> Deployment Assembly’ 를 보면 /src/main/webapp 이 보인다. 이것을 삭제하고 WebContent 를 추가해준다.

WebContent 를 위한 이클립스 설정
WebContent 를 위한 이클립스 설정

이렇게 한 후에 pom.xml 파일의 오류가 사라지는것을 볼 수 있다. 만일 그렇지 않다면 Maven Update 를 한번 해준다.

이제 Maven 을 이용해서 프로젝트를 빌드 해본다. 성공적으로 빌드가 됐다면 다음과 같이 나온다.

webapp 디렉토리 변경후에 빌드 성공한 디렉토리 구조
webapp 디렉토리 변경후에 빌드 성공한 디렉토리 구조

Spring 설정을 WebContent 와 분리

WebContent 이름에서 보이듯이 이 디렉토리는 Web 관련 파일들만 모아놓기위한 것이다. Web 관련 파일이라면 CSS, JS, Images, JSP 로 대표되는 Web Frontend 파일을 말한다. 하지만 자세히 보면 Spring 에 관련된 파일 들도 있어서 이것을 Resource 디렉토리로 옮겨 놓는게 적절해 보인다.

먼저 src/main/resources 디렉토리에 ‘spring’ 이름의 디렉토리를 생성해준다. 디렉토리를 생성했는데 패키지 아이콘이 나온다면 ‘Build Path’ 에서 Exclude 해주면 된다. 그리고 spring-root.xml, spring-context.xml 두개의 파일을 모두 resources/spring 으로 옮겨주고 기존의 WEB-INF/spring 디렉토리는 삭제해준다.

Spring 설정파일 옮기기
Spring 설정파일 옮기기

Web.xml 파일에서 spring 설정 파일의 경로를 변경해 준다.

그리고 pom.xml 파일을 다음과 같이 변경해 준다.

 

이렇게 디렉토리를 변경하는 이유는 앞에서 잠깐 언급했지만 Web 컨텐츠와 Spring 설정파일들을 분리하는데 있다. 또, 이렇게 함으로써 자바 관련 파일과 Web 컨텐츠 파일을 손쉽게 분리해서 배포할 수 있게 된다.

pom.xml Plugin execution not covered by lifecycle configuration 오류

앞에서 mave timestamp 의 TimeZone 변경을 위해서 build-helper-maven-plugin 를 사용했는데 Eclipse 에서 다음과 같이 오류가 난다.

build-helper-maven-plugin Eclipse 오류
build-helper-maven-plugin Eclipse 오류

위 오류내용은 다음과 같다.

Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:build-helper-maven-plugin: 1.11:timestamp-property (execution: timestamp-property, phase: validate)

Eclipse 는 오류를 표시했지만 maven 은 정상적으로 동작한다. 이는 Ecliplse 의 m2e 커넥터의 lifecycle mapping 정보를 명확하게 해야하는데 이것이 없어서 오류로 표시하는 것이다. 다음 URL 에 관련 내용이 있다.

내용을 보면 <pluginManagement> 를 이용해서 lifecycle-mapping 을 설정해주어야 한다. 위 내용을 기반으로  build-helper-maven-plugin 의 execution 에 대해서 mapping 을 지정해주면 해결된다.

위와 같이 설정을하면 Eclipse 의 오류가 사라진다.

 

Maven timestamp 에 timezone 변경하기

maven 은 build timestamp 를 변수로 지원한다. 하지만 자세히 보면 이 timestamp 는 UTC timezone 에 맞춰져 있다. maven 에서 timestamp 는 기본적으로 UTC timezone 을 기반으로 한다. 그런데 이것을 다른 timezone 으로 변경할려면 어떻게 해야할까?

build-helper-maven-plugin

maven 에선 많은 plugin 을 지원한다. build-helper-maven-plugin 은 우리가 필요하는 기능인 timestamp 에 timezone 변경을 지원한다. 변경된 timezone 의 시간을 표시할 변수와 timestamp format, timezone 등을 지정하면 여기서 지정한 변수를 사용할 수 있게 된다.

위와같이 current.time 변수에 한국시간의 timezone 으로 지정한 timestamp 값을 할당해주고 maven-war-plugin 에서 warName 태그에서 current.time 변수를 사용해주면 된다.

war 파일이름에 TimeStamp 찍기

Maven 을 이용하면 자동으로 컴파일을 해주고 war 파일로 만들어 준다. 그런데, 이때에 war 파일에 TimeStamp 를 찍을 수 있다. war  파일명이 project.name-timestamp.war 형식으로 파일을 작성하도록 할수 있다. 방법도 대략 두가지 방법이 있다.

maven 자체 기능

maven 3.0 이상이라면 자체 기능을 이용할 수 있다. properties 에 timestamp 와 maven.build.timestamp.format 을 지정하고 build 영역에서 파일명을 지정해주면 된다. 예를들면 다음과 같다.

위와같이 설정하고 maven build 를 하면 다음과 같이 출력되는 것을 볼수가 있다.

maven-war-plugin 으로 war 파일명 지정

이것은 사실 위 방법을 쓴다면 사용할 일이 별로 없다. 하지만 war 파일을 생성할때에 많은 옵션을 주고 싶다면 이 플러그인을 사용하는게 좋다. 이를 사용하면 build 영역에서 finalName 을 지정하지 않고 이 플러그인에서 지정해주면 된다.

결과는 처음과 같다.