메이븐의 특징 중 하나는 메이븐이 참조 라이브러리 의존관계를 체계적으로 관리해준다는 것이다. 메이븐이 의존성을 다루는 의존성 관리 메커니즘에는 의존성 전이(Transitive Dependencies)라는 게 있는데,  
A가 B에 의존하고 B가 C에 의존한다고 할 때, 즉 A -> B -> C 관계에서 A는 B에 대한 의존관계만 설정하면 메이븐이 알아서 C까지도 가져와서 적절한 스코프에 포함시켜 준다는 것이다.

그러나, B의 type이 war 이면 의존성 전이 메커니즘은 작동하지 않는다.

 <dependency>
   <groupId>mycom</groupId>
   <artifactId>B</artifactId>
   <version>1.0</version>
   <type>war</type>
 </dependency>

그러니까 메이븐이 자동으로 B.war가 의존하는 C.jar를 포함시켜주지 않는다는 얘기다.
게다가 B.war에 포함된 클래스들(WEB-INF/classes) 또한 A의 의존성에 포함되지 않는다. A의 소스가 B.war의 클래스를 참조한다면 컴파일시 에러가 발생할 것이다.

이클립스에서 A프로젝트의 빌드패스에 B 웹프로젝트를 추가하면 이클립스는 B 웹프로젝트의 빌드패스에 포함된 C.jar와 B 웹프로젝트의 클래스들을 A프로젝트에 자동으로 추가해준다.

아쉽지만 메이븐에서는 이게 자동으로 안된다.

Posted by 에코지오
,
WAS를 start/stop/restart하거나 웹어플리케이션을 deploy/undeploy/redeploy하는 작업을 자동으로 처리하기 위해 쓸 수 있는 방법은 어떤게 있을까?

1. 스크립트 실행
작업을 정의한 스크립트를 실행한다. 아마 이게 제일 속편한 방법일지도 모른다.
Ant에서는 telnet, exec, sshexec 등의 타스크를 이용하여 실행하면 된다.

Ant sshexec 타스크를 통해서 원격지의 Tomcat을 start하는 예제

<target name="remote-tomcat-start">
  <sshexec host="${ssh.hostname}"
  port="${ssh.port}"
  username="${ssh.username}"
  passphrase=""
  trust="true"
  keyfile="${ssh.key.file}"
  command="${tomcat.home}/bin/startup" />
  <sleep seconds="${sleep.time}" />
</target>


2. WAS에서 제공하는 Ant 타스크 또는 Maven 플러그인 이용
대부분의 WAS가 어드민화면을 통하지 않고 여러가지 작업을 수행할 수 있는 수단을 제공한다.

Tomcat에서 제공하는 deploy 타스크를 이용하여 war를 deploy하는 Ant 예제

    <target name="install" description="Install application in Tomcat"
        depends="package-web">
        <deploy url="${tomcat.manager.url}"
            username="${tomcat.username}"
            password="${tomcat.password}"
            path="/${webapp.name}"
            war="file:${webapp.dist}/${webapp.war}"/>
    </target>


3. Cargo 이용
Cargo는 WAS 마다 다른 형태의 API를 래핑하여 표준적인 방법으로 WAS를 핸들링할 수 있게 해준다. 그러나 아직 지원하는 WAS가 많지 않다.

Ant에서 cargo 타스트를 이용하여 Tomcat을 start하는 예제

  <cargo containerId="tomcat5x" home="${tomcat.home}" output="${tomcatlog.dir}/output.log"
      log="${tomcatlog.dir}/cargo.log" action="start">
    <configuration home="${tomcatconfig.dir}">
      <property name="cargo.servlet.port" value="8080"/>
      <property name="cargo.logging" value="high"/>
      <deployable type="war" file="${mywarfile}"/>
    </configuration>
  </cargo>
Posted by 에코지오
,

자바에서 웹어플리케이션은 JEE 스펙에서 정의한 디렉토리 구조를 갖는 war 파일의 형태로 컨테이너에 배포됩니다. 메이븐에서는 웹어플리케이션을 package 단계에서 기본적으로 war 파일로 포장합니다.

그런데 꼭 war라는 아카이브 파일로만 배포할 수 있는 건 아닙니다. maven-war-plugin 플러그인에는 war:war 골뿐만 아니라 war:exploded나 war:in-place도 있습니다.

웹어플리케이션을 배포하기 위한 패키징 유형을 3가지로 나눌 수 있습니다.

1. package(archive) : 아카이브(war,ear) 파일로 배포
- 아카이브는 결국 WAS에 의해 압축이 풀림
- 파일이 많을 경우 압축해제 시간 오래걸릴 수 있음
- 리모트 서버에 배포시 한개의 파일만 전송하면 됨
- WAS에서 제공하는 업로드를 통한 배포기능 활용가능

2. exploded(expanded) : 아카이브를 압축해제한 디렉토리 형태 구조
- 압축 및 해제 과정이 불필요
- 별도의 디렉토리에 원본 소스를 복사하여 만듬
- 파일이 많은 경우 복사 시간 오래걸릴 수 있음
- 원본 소스를 건드리지 않고 배포를 원하는 경우 적합
- 리모트 서버에 배포시 파일이 많은 경우 전송 시간이 오래걸릴 수 있음.(rsync는 빠르다?)

3. in-place : 소스 디렉토리(전체 또는 일부)를 그대로 배포
- 추가적인 복사 과정 불필요
- 로컬 서버에 배포하는 경우에 적합
- WAS가 런타임시 생성하는 파일이 소스와 섞일 수 있음

Posted by 에코지오
,

maven-war-plugin 플러그인에서 웹소스의 기본 디렉토리 경로는 src/main/webapp이다.
이 경로를 warSourceDirectory 옵션을 통해 바꿀수가 있다.

   <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1-alpha-2</version>
    <configuration>
     <warSourceDirectory>${project.basedir}/web</warSourceDirectory>
    </configuration>
   </plugin>

근데 문제는 경로를 ${project.basedir}/web 이런식으로 절대 경로로 줄 경우 M2Eclipse 플러그인이 요상한 WTP 경로를 만들어 내기도 한다.(그랬다가 안그랬다가 -.-;;)

org.eclipse.wst.common.component 파일을 열어보면 source-path가 아래처럼 자동수정이 된다.

<wb-resource deploy-path="/" source-path="/eclipse-3.3/workspace/MyProject/web"/>

이클립스에서 project view 나 package view 에서 프로젝트 모습이 이상하게 바뀐다..

이럴 땐 <warSourceDirectory>web</warSourceDirectory> 이런식으로 웹소스 디렉토리 경로를 상대경로로 주면 된다.
 

ps. 로컬에서 다시 재연해보니 soure-path의 경로가 안바뀌고 그대로 있다. 요상타... -.-;;
 

Posted by 에코지오
,