레이블이 gradle인 게시물을 표시합니다. 모든 게시물 표시
레이블이 gradle인 게시물을 표시합니다. 모든 게시물 표시

2017년 12월 3일 일요일

spring boot + gradle + proguard + 실행가능한 jar

spring boot + gradle + proguard를 사용하여 웹어플리케이션의 실행가능한 jar를 만드는 방법을 소개한다.


1.
spring boot를 사용하면 보통 gradle을 빌드도구로 사용하게 되고, 웹어플리케이션을 만들 때 보통 실행가능한 jar를 만들어서 쓰곤 한다. 아래와 같이 build.gradle을 구성하고 gradle assemble 명령어로 실행가능한 jar를 만든다.

buildscript {
    repositories {
     mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'

springBoot {
    executable = true
} 

2.
만들어진 jar를 보면 BOOT-INF/clesses에 내가 만든 클래스들이, BOOT-INF/lib에 내가 사용하는 라이브러리들이 포함된다.

여기서 내가 만든 클래스들을 proguard로 난독화를 적용하고 싶으면 proguard가 제공하는 gradle 플러그인을 이용하면 손쉽게 만들수 있다.

buildscript {
    repositories {
     mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE")
        classpath("net.sf.proguard:proguard-gradle:5.3.3")
    }
}

def proguardJarPath = jar.archivePath.absolutePath.replace(".jar", "-proguard.jar")

task proguard(type: proguard.gradle.ProGuardTask, dependsOn: jar) {
    configuration "proguard.conf"

    injars jar.archivePath.absolutePath
    outjars proguardJarPath

    libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
    libraryjars project.configurations.compile
}


3.
그런데 난독화된 jar를 실행가능한 jar에 포함시키려면 gradle 설정이 조금 더 필요하다. 실행가능한 jar를 만드는 gradle의 spring boot 플러그인의 bootRepackage 태스크가 사용하게 되는 jar를 난독화된 jar로 바꿔줘야 한다.

bootRepackage {
 withJarTask = proguardJar
}

이때 withJarTask에 대입이 가능한 값은 Jar 타입의 gradle 태스크여야 한다. ProGuardTask는 Jar 타입이 아니다. 그래서 proguardJar라고 내가 만든 Jar 타입의 태스크가 필요하다. 이미 난독화된 jar 파일이 있으므로 zipTree로 파일 구조를 유지하면서 새로운 jar 파일을 만들어야 한다.

task proguardJar(type: Jar, overwrite: true, dependsOn: proguard) {
 from zipTree(proguardJarPath)
}

4.
다 합치면 아래와 같은 gradle 설정이 된다.




2016년 12월 16일 금요일

maven central에 없는 라이브러리 github에서 가져오기

개발셀에서 Gephi라는 프로그램의 Toolkit을 쓸 일이 생겨서 Toolkit으로 오픈된 라이브러리를 이용해서 커맨드라인으로 파일을 변환하는 자바 어플리케이션의 개발환경을 구축하게 되었다.

1.
라이브러리는 github에서 제공되고 있었는데, 다운로드를 받아보니 Fat Jar 형태였다. 즉, 라이브러리에서 직접 제공하는 자바 클래스와 실행을 위해 필요한 다른 라이브러리의 클래스까지 모두 하나의 jar로 압축되어 있었다.

2.
담당 개발자가 POC처럼 이것저것 해볼때는 fat jar를 다운받아서 로컬에서 이클립스 프로젝트를 구성하여 사용하였는데, 이걸 다시 github에 올리기 전에 빌드를 gradle로 구성하기로 했다.

3.
우선 Gephi Toolkit이 maven에 올라가져 있길래 gradle dependency에 추가했다.

```
dependencies {
// gephi toolkit
compile group: 'org.gephi', name: 'gephi-toolkit', version: '0.9.1'
}
```

4.
수많은 다른 라이브러리들을 하나씩 내려받다가 2개 라이브러리를 내려받지 못해서 에러가 발생했다. 찾아보니 정말로 maven central에 각각의 라이브러리는 있지만 찾고 있는 버전은 등록되어 있지 않았다. stax-utils-snapshot-20100402.jar, trove-2.1.0.jar이 그것들이다.

5.
검색을 좀 해보니 당연히 나만 이런 것이 아니었고, 해결책으로는 
들이 이미 덧글로 달려있었다. 2개만 별도로 다운로드 하라는 것은 그 2개의 라이브러리가 가지고 있을지도 모르는 depencency는 무시하게 될 것이다. 그래서 all 버전을 사용하기로 결정했다.

6.
그렇다고 all 버전을 git에 올릴 수는 없었다. 그래서 github에 제공된 링크를 통해서 gradle 빌드시점에 다운로드 받는 방법을 찾아보기로 했다. 조금 검색해보니 Gradle Download Task라는 plugin을 찾을 수 있었다. Java 컴파일 하기전에 다운로드 받도록 gradle 파일을 구성했다.

```
apply plugin: 'de.undercouch.download'

import de.undercouch.gradle.tasks.download.Download

task downloadGephiToolkit(type: Download) {
    src 'http://github.com/gephi/gephi-toolkit/releases/download/v0.9.1/gephi-toolkit-0.9.1-all.jar'
    dest 'lib/'
    overwrite false
}

compileJava.dependsOn downloadGephiToolkit
```

7.
그리고 gradle의 dependency도 아래처럼 변경하고, 마지막으로 gradle 파일이 이렇게 된 이유를 설명하는 주석을 달아두었다.

```
dependencies {
// gephi toolkit
compile name: 'gephi-toolkit-0.9.1-all'

//XXX 아래처럼 선언하면 stax-utils와 trove를 maven에서 찾다가 에러난다. 그래서 gephi-toolkit-0.9.1-all을 사용한다.
// compile group: 'org.gephi', name: 'gephi-toolkit', version: '0.9.1'
}
```