2016년 8월 23일 화요일

gradle로 application 배포zip 파일 만들기

회사 업무 중에 linux에서 stand alone으로 실행되는 java 프로그램이 하나 있다. 이걸 개발하고 빌드하고 배포해서 실행하는 일련의 과정이 옛날의 방식으로 되어 있어서 최근 몇일동안 요즘의 방식을 적용하면서 자동화를 했다.

1. ant -> gradle
이전에는 ant로 빌드 task를 하나씩 정의해서 순서대로 실행되도록 depends를 걸고 실행해서 jar 파일을 만들었다.
이제는 gradle로 빌드환경을 바꿔서 gradle의 java 플러그인이 가진 convention을 활용하여 별도로 정의한 task 없이 jar task에 속성이나 메서드를 정의해서 jar를 만들게 변경했다. 이변경을 통해서 ant xml 파일의 수십줄의 보통의 빌드스크립트를 삭제할 수 있었다.

```
apply plugin: 'java'
apply plugin: 'eclipse'

sourceCompatibility = 1.7
targetCompatibility = 1.7

compileJava.options.encoding = 'UTF-8'

jar {
baseName 'sds-genomics-analysis'
    manifest {
        attributes 'Main-Class': 'aaa.bbb.ccc.DddMain'
    }
    exclude (['spring/**', 'properties/**', 'logback.xml'])
}
```

2. dependency
이전에는 라이브러리에 대한 dependency를 관리하지 않고 있었다. 필요한 라이브러리가 있을 때마다 jar 파일을 다운로드 받아서 lib 폴더에 넣고 classpath에 추가했었다. 물론 jar파일까지 git repo에 커밋했어야 했다.
이제는 gradle을 적용하면서 사내 nexus를 repository로 지정하고 dependency를 선언하여 빌드시점에 자동으로 다운로드 받도록 변경했다. 당연히 jar 파일들은 git repo에서 빠지게 되었다. 이제 라이브러리 버전업을 큰 걱정없이 시도해볼 수 있게 되었다.

3. distZip
jar 라이브러리파일, xml 설정파일, 프러퍼티파일, 시작/종료 쉘스크립트파일을 적절한 폴더구조로 만들어서 배포판을 만드는 것도 모두 ant에 xml로 정의된 스크립트로 존재했었다.
이제는 gradle의 distZip task를 활용해서 간단하게 배포판 zip파일을 만든다.

처음에는 gradle의 application 플러그인을 적용했었다. application 플러그인은 startScripts task와 distZip task를 가지고 있는데, 각각 시작 쉘스크립트 파일을 만들고, 배포 zip파일을 convention을 따라 만들어준다. 그런데 startScripts가 시작 쉘스크립트만 만들고 종료 쉘스크립트는 만들지 않고, 만들어지는 쉘스크립트 내용도 내맘대로 구성하는 것이 잘 안되서 나만의 distZip을 만들어서 사용했다. 그리고 쉘스크립트는 실행권한을 주기 위해서 zip으로 만들때 755권한을 준다.
```
task distZip(type: Zip){
def baseDir = { archiveName - ".zip" }
into("/") {
// shell 파일은 실행권한을 주기 위해 별도로 포함시킨다.
from(project.file("src/dist")) {
        exclude('**/*.sh')
    }
from(project.file("src/dist")) {
        include('**/*.sh')
        fileMode = 0755
    }
}
into("conf"){
from(project.file("src/main/resources")) {
        exclude('sqlmap')
    }
}
into("lib") {
    from(jar)
    from(project.configurations.runtime)
}
}
```

4. start.sh
이전에는 시작 쉘스크립트에 실행디렉토리 위치가 하드코딩되어 있었다.
이제는 쉘스크립트가 실행되는 위치를 인식해서 경로를 찾아내도록 변경하였다. $0 파라미터를 사용하는 것이 기본 아이디어인데, 심볼릭링크 제거를 위해 readlink를 사용하고, 부모 디렉토리를 얻기 위해 dirname을 2번 사용했다.
```
#!/bin/sh
APP_PATH=$(dirname `readlink -f $0`)
APP_PATH=$(dirname $APP_PATH)
echo $APP_PATH
```


댓글 없음:

댓글 쓰기