maven 을 쓰고 있다면 간단한 명령으로 바로 tomcat 에 바로 디플로이 해서 테스트 해볼 수 있습니다.

mvn tomcat:run

만 하면 바로 실행할 수가 있습니다. 그런데 맘에 들지 않습니다. application root 때문입니다. http://localhost:8080/{war_name} 으로 실행이 되기 때문입니다. http://localhost:8080 으로 바꾸고 싶다면 간단하게 옵션을 줘서 바꿀 수가 있습니다.

mvn tomcat:run -Dmaven.tomcat.path=/

역시 간단하게 됩니다. 따로 옵션 주고 싶은 것도 추가해 주면 됩니다.

mvn tomcat:run -Dspring.profiles.active=local -Dmaven.tomcat.path=/

그런데 위와 같이 실행하면 tomcat version 6 으로 동작합니다. 최근에는 tomcat version 7 을 많이 쓰지요. tomcat 을 tomcat7 으로 바꿔서 명령을 날리면 동작하지 않습니다. 역시 간단하게 바꾸는 방법이 있습니다. 두가지 방법이 있지만 IDE 를 사용해서 개발하는 팀원하고 맞추기 위해서는 (저는 기본적으로 IDE 는 프로젝트 설정할 때만 사용합니다) pom.xml 을 바꾸는 것을 올바른 방법이 아니라고 생각해서 다른 방법을 택합니다.

OSX 기준으로 maven 을 brew 를 이용해서 깔았다면 /usr/local/Cellar/maven/3.3.1/libexec/conf/settings.xml 를 열어서

<pluginGroups>
  <!-- pluginGroup
   | Specifies a further group identifier to use for plugin lookup.
  <pluginGroup>com.your.plugins</pluginGroup>
  -->
  <pluginGroup>org.apache.tomcat.maven</pluginGroup>
</pluginGroups>

와 같은 식으로 <pluginGroup>org.apache.tomcat.maven</pluginGroup> 를 추가해 줍니다. 그리고 다시

mvn tomcat7:run

와 같이 실행하면 tomcat version 7 으로 실행이 되는 것을 확인할 수가 있습니다.

 Emacs 와 JDEE 와 Maven 과의 결합의 마지막을 해결했습니다. 그 전의 세팅을 보시고 싶으시면 


    2 번까지 끝을 내고 나니 Emacs 내에서 maven 컴파일과 빌드를 하고 싶더군요. (당장은 mvn install 만 되게) 딱히 다른 사람들이 만든 것은 내 필요에 부합하지 않은 것 같기도 하고 지원도 더 이상 하지 않는 것 같기에 직접 만들게 됐습니다. jdee 프로젝트 안에 있는 jde-make 를 변경했습니다. 간단하게 되더군요. 적당한 곳 (~/.emacs.d 안에)에 jde-mvn.el 을 복사하시고 .emacs 안에서 

(require 'jde-mvn)


 을 해주시면 됩니다. 그리고 세부 설정을 위해서 


(custom-set-variables

 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(ecb-options-version "2.40")
 '(jde-build-function (quote jde-mvn))
 '(jde-global-classpath (quote 
     ("/Users//work/android/\
      sdk/platforms/android-17/android.jar" 
      "/Users//.emacs.d/\
      jdee/build/classes")))
 '(jde-mvn-enable-find t)
 '(js2-auto-indent-p t)
 '(js2-cleanup-whitespace t)
 '(js2-enter-indents-newline t)
 '(js2-global-externs (quote ("$" "Ext")))
 '(js2-mirror-mode nil)
 '(slime-complete-symbol-function 
   (quote slime-fuzzy-complete-symbol))
 '(tab-width 2))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )


 와 같이 jde 설정을 해주시면 완료입니다. 

 필요한 파일은 https://github.com/crazia/jdee-mvn 에 올려두었습니다.
   저번에 올린 Emacs 와 JDEE 를 가지고 안드로이드를 개발하는 방법에 대해서 글을 올렸습니다. 그런데 최근 화두는 어떻게 하면 Mavenpom.xml 을 이용해서 JDEE 의 개발환경에 접목을 시킬까 하는 것이였습니다. 아.. 진짜 힘들었습니다. 그래도 몇가지 테스트와 노력을 끝으로 드디어 성공했습니다. 

참고한 사이트입니다. 


여기에서 근본적인 pom-parser.el 을 다운 받을 수 있었습니다. 그런데 제대로 동작을 하지 않더군요. 이유는 maven 의 실행 옵션들이 변해서 그렇답니다. 


위 사이트를 참조하시면 어떻게 변경해야 하는지 알 수가 있습니다. 위 까지만 적용하면 다 될 줄 알았는데 제가 기본적으로 jde-global-classpath 에 넣어둔 것이 사라지면서 에러가 발생하더군요. 그래서 기존에 있는 클래스 패스를 포함하는 버젼으로 수정했습니다. 
    올려둔 파일을 다운 받으시고 ~/.emacs.d/ 에 복사하시고 maven 프로젝트가 있는 곳 (정확히는 pom.xml 파일이 있는 곳)에 다음과 같은 파일 prj.el 을 만들어 주시면 됩니다. 


(jde-project-file-version "1.0")
(jde-set-variables
'(jde-compile-option-command-line-args
(quote ("-Xlint:all" "-Xlint:-serial"))))
(require 'pom-parser)
  (with-pom ()
  (pom-set-jde-variables *pom-node*))


 프로젝트를 만들다 보면 너무나 당연하게 디펜던시를 가지는 프로젝트가 생기게 됩니다. 메이븐은 기본적으로 디펜던시를 가져다가 프로젝트를 만들게 되는데 이를 수동으로 해야할 필요가 생긴다면  어떻게 할 것인가? 하는 문제가 있습니다. 즉 

   

    A : 실행파일이 만들어지는 프로젝트 
    B : A 가 참조하는 프로젝트
    C : B 가 참조하는 프로젝트 

    A - 
      - B -
          - C

    

이런식으로 아마 만들어지는 것이 지금까지의 일반적인 방법일 것입니다. 그러나 메이븐에서 관리를 하게 된다면 조금 다른 식이 됩니다. 

   

P (parent) 가 존재해서 

    P - A
      - B
      - C 



같은 식으로 프로젝트가 존재하게 됩니다. 그리고 각각은 pom.xml 만 수정해서 프로젝트를 관리할 수가 있습니다. 

    그래서 수정해야 할 부분을 따라하기로 만들어 보기로 합니다. 

    1. 부모 (parent) 프로젝트 생성 
 


$ mvn archetype:generate

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 186: 186
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
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: 6: 6
Define value for property 'groupId': : upper
Define value for property 'artifactId': : top
Define value for property 'version':  1.0-SNAPSHOT: : 1.0.0
Define value for property 'package':  upper: : 
Confirm properties configuration:
groupId: upper
artifactId: top
version: 1.0.0
package: upper
 Y: : Y



186 번을 선택하시고 나머지 것들은 대충 입력해서 만들어 줍니다. 제 경우에는 

     

       groupId: upper
       artifactId: top
       version: 1.0.0


 와 같이 만들어 줬습니다. 

    2. 부모 프로젝트의 pom.xml 변경 
       
       

       <groupId>upper</groupId>
       <artifactId>top</artifactId>
       <version>1.0.0</version>
       <packaging>pom</packaging>


      <packaging> 태그의 내용을 pom 으로 바꿉니다.


    3. 하위 프로젝트 생성 
      1. 에서 생성한 프로젝트의 위치로 이동합니다.

$ cd $PARENT-BASE
$ mvn archetype:generate
 
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 186: 186
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
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: 6: 6
Define value for property 'groupId': : upper
Define value for property 'artifactId': : project-a
Define value for property 'version':  1.0-SNAPSHOT: : 1.0.0
Define value for property 'package':  upper: : 
Confirm properties configuration:
groupId: upper
artifactId: project-a
version: 1.0.0
package: upper
 Y: : Y

       
다음 프로젝트 생성 

$ mvn archetype:generate

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 186: 186
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
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: 6: 6
Define value for property 'groupId': : upper
Define value for property 'artifactId': : project-b
Define value for property 'version':  1.0-SNAPSHOT: : 1.0.0
Define value for property 'package':  upper: : 
Confirm properties configuration:
groupId: upper
artifactId: project-b
version: 1.0.0
package: upper
 Y: : Y


그리고 다음 프로젝트도 생성해줍니다. 
       

$ mvn archetype:generate
 
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 186: 186
Choose org.apache.maven.archetypes:maven-archetype-quickstart version: 
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: 6: 6
Define value for property 'groupId': : upper
Define value for property 'artifactId': : project-c
Define value for property 'version':  1.0-SNAPSHOT: : 1.0.0
Define value for property 'package':  upper: :   
Confirm properties configuration:
groupId: upper
artifactId: project-c
version: 1.0.0
package: upper
 Y: : Y


각각에 맞춰서 생성해줍니다. 

이렇게 하면 자동으로 부모 프로젝트의 pom.xml 이 변경됩니다. 

 

 <modules>
    <module>project-a</module>
    <module>project-b</module>
    <module>project-c</module>
  </modules>



하단에 위와 같은 내용이 추가 됐습니다. 그리고 project-a 의 pom.xml 을 열어보면 

 

<parent>
    <groupId>upper</groupId>
    <artifactId>top</artifactId>
    <version>1.0.0</version>
  </parent>


와 같은 보통때는 안보이는 내용이 추가 됐습니다. 다시 자세히 설명하자면 부모 프로젝트의 <package> 내용을 pom 으로 바꾸고 <modules> 내용을 추가하고 , 추가되는 프로젝트의 pom.xml 에 <parent> 관련된 부분을 추가 해주면 복합 모듈 프로젝트로 변경되는 것입니다. 

.
├── pom.xml
├── project-a
│   ├── pom.xml
│   └── src
│       ├── main
│       │   └── java
│       │       └── upper
│       │           └── App.java
│       └── test
│           └── java
│               └── upper
│                   └── AppTest.java
├── project-b
│   ├── pom.xml
│   └── src
│       ├── main
│       │   └── java
│       │       └── upper
│       │           └── App.java
│       └── test
│           └── java
│               └── upper
│                   └── AppTest.java
├── project-c
│   ├── pom.xml
│   └── src
│       ├── main
│       │   └── java
│       │       └── upper
│       │           └── App.java
│       └── test
│           └── java
│               └── upper
│                   └── AppTest.java
└── src
    ├── main
    │   └── java
    │       └── upper
    │           └── App.java
    └── test
        └── java
            └── upper
                └── AppTest.java

31 directories, 12 files


프로젝트의 트리 내용입니다. 


   4. 하위 프로젝트 끼리 연결 시키기 

project-b 는 project-c 를 참조하고 project-a 는 project-b 를 참조합니다. 그렇다면 각각의 project-a 와 project-b 의 pom.xml 을 열어서 

project-a 의 pom.xml 에는 
   

   <dependency>
      <groupId>upper</groupId>
      <artifactId>project-b</artifactId>
      <version>1.0.0</version>
    </dependency>


 을 추가해 주고 

 project-b 의 pom.xml 에는 
 

  <dependency>
      <groupId>upper</groupId>
      <artifactId>project-c</artifactId>
      <version>1.0.0</version>
    </dependency>


 만 추가해 주면 됩니다. 물론 이 내용들은 <dependencies> 태그 안에 위치해야 하는 것은 기본입니다. 


결론적으로 말해서 maven 은 초기의 거리낌이 느껴지는 것과는 달리 순수하게 command-line 으로 관리할 수 있는 프로젝트 관리 모듈입니다. 저 같이 이클립스보다는 이맥스(emacs) 가 손에 익은 사람들이 자바 프로젝트를 깔끔하게 관리할 수 있게 많은 기능들을 제공합니다. 
    

자바 프로젝트 관리툴인 Maven 을 설치하고 프로젝트를 만들기 시작했는데 정말 초! 난감하더군요. 이걸 대체 어떻게 시작하는 것인가 하고 말이죠. 

Leingen 이라는 툴과 많이 비슷하더군요. (레인젠 은 클로져 프로젝트 관리 툴) 즉 프로젝트 만들고 관리해 주는 것이라고는 알겠는 데 정말 시작하기가 막막 하더군요.

일단 설치하고 나서 바로 실행해 줍니다.

$ mvn archetype:generate



저는 여기서 바로 압도 당하게 됐습니다. 수백개의 (정말 수백개의!! : 566 개) 프로젝트 유형이 나오더군요. 사실 이런게 뭐가 중요하겠습니까? 여기서 무엇을 선택할지 잘 모르는 분들을 위해서 글을 쓰는 것입니다.

 
그림에 보면 맨 마지막에 '186' 이라고 쓰여져 있지요? 그냥 186 을 입력하면 quick-start 버젼으로 프로젝트를 생성하는 것입니다. 그리고 

 

groupId=com.temp
artifactId=Example


로 입력하시면 바로 프로젝트가 생성됩니다.  이제 바로 이거 저거 테스트를 만들어 보시면 됩니다. 

 

+ Recent posts