https://jiandson.co.kr/event/bookconcert/boot-spring-boot



스프링 부트 관련한 책을 내고 하는 첫번째 방어전 입니다.

많은 분들의 도전을 기다리고 있습니다. ^^


스프링 부트와 관련한 이런저런 이야기를 하고 나눌 수 있기를 기대하고 있습니다.


2018/08/27(월) 19:30 역삼역 부근(이라기에는 좀 멀리 있는) 마루 180 에서 세미나를 진행합니다.


10일 밖에 남지 않았지만... 어떤 이야기를 해야할까 아직도 고민중입니다.



800페이지에 가까운 책을 한번 훑어봤다.
말그대로 훑어봤다. @_@

클라우드 파운드리(Cloud Foundry, CF)나 쿠버네티스 정도가 아니면  "클라우드 네이티브 애플리케이션" 개발은 어렵다는 성철님의 의견에 동의하게 된다.

이제 스터디 일정에 맞춰 예제 작성해보며 직접 부대껴보는 시간을 가져야겠다.

클라우드 네이티브 애플리케이션을 만들어보자꾸나.

[springboot] 2.0 을 사용하면서 패키징과 관련된 문제가 발생한다면

스프링 부트 2.0 을 사용하면서 패키징과 관련된 찝찝한 느낌을 받고 있는 요즘이다.

그 주요 원인은 스프링 부트 그레이들 플러그인 2.0 때문이다. 스프링 부트 그레이들 플러그인 2.0이 되면서 기존에 있던 bootRepackagebootJarbootWar 으로 변경(Spring Boot’s new Gradle plugin)되면서 부터다.

실행가능한 jar와 war를 만드는데 사용했던 bootRepackage를 배포파일에 따라서 각각 JarbootJarWarbootWar로 확장하는 과정에서 이런 상황이 발생했다.

핵심요점만 이야기하자면 bootJarbootWar를 비활성화하면 패키징 태스크가 실행되지 않는다.

//bootJar 비활성화시
bootJar.enabled = false
jar.enabled = true

//bootWar 비활성화시
bootWar.enabled = false
war.enabled = true

위와 같은 형태로 상위 태스크를 활성화시켜줘야지만 패키징 태스크가 실행된다. 이러한 사실을 알게된 것은

가 있었고, 오늘은 EBS(AWS Elastic Beanstalk)에서 "구성 파일(.ebextensions)을 사용하여 고급 환경 사용자 지정" 기능을 사용하기 위해서 프로젝트 내에 .ebextensions 디렉터리를 war 파일 패키징시 이동하기 위해 그레이들내에서 다음과 같이 선언했는데 .ebextensions 디렉터리가 패키징에서 누락된 것을 발견했다.

build.gradle
project(":api-module") {
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'war'

    war {
        from('./src/main/ebextensions') {
            into('.ebextensions')
        }
    }

    dependencies {
        compile project(":core-module")

        compile('org.springframework.boot:spring-boot-starter-data-rest')
        compile('org.springframework.boot:spring-boot-starter-hateoas')
        compile('org.springframework.boot:spring-boot-starter-web-services')
        compile('org.springframework.boot:spring-boot-starter-webflux')
        compile('org.springframework.data:spring-data-rest-hal-browser')

        compileOnly "org.springframework.boot:spring-boot-configuration-processor"

        testCompile('org.springframework.boot:spring-boot-starter-test')
        testCompile('io.projectreactor:reactor-test')
    }
}

위와 같이 모듈을 정의했는데, war 태스크를 정의한 부분이 무시됐다. (이런!!)

하지만 그렇다고 분노하거나 노여워하지 말자(그건 내가 다 했으니…​).

여기서 대응할 수 있는 방법은 크게 2가지가 있다.

  • 새로추가된 booWar 태스크를 사용하는 경우

  • 기존 war 태스크를 유지하는 경우

Note

스프링 부트를 기반으로 할 때는 실행가능하게 패키징(Repackaging)을 하는 bootJarbootWar를 사용한다고 생각하면 마음의 평화가 찾아올 듯 하다.

추천방법: 새로 추가된 booWar 태스크를 사용하는 경우

project(":api-module") {
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'war'

    bootWar {
        from('./src/main/ebextensions') {
            into('.ebextensions')
        }
    }

    dependencies {
        compile project(":core-module")

        compile('org.springframework.boot:spring-boot-starter-data-rest')
        compile('org.springframework.boot:spring-boot-starter-hateoas')
        compile('org.springframework.boot:spring-boot-starter-web-services')
        compile('org.springframework.boot:spring-boot-starter-webflux')
        compile('org.springframework.data:spring-data-rest-hal-browser')

        compileOnly "org.springframework.boot:spring-boot-configuration-processor"

        testCompile('org.springframework.boot:spring-boot-starter-test')
        testCompile('io.projectreactor:reactor-test')
    }
}

기존 war 태스크를 유지하는 경우

Note

톰캣과 같은 WAS에 war 파일을 배포한다면 실행가능하게 패키징을 필요로 하지 않으니 bootWar를 비활성화 하자.

project(":api-module") {
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'war'

    bootWar.enabled = false // (1)
    war.enabled = true  // (2)

    war {
        from('./src/main/ebextensions') {
            into('.ebextensions')
        }
    }

    dependencies {
        compile project(":core-module")

        compile('org.springframework.boot:spring-boot-starter-data-rest')
        compile('org.springframework.boot:spring-boot-starter-hateoas')
        compile('org.springframework.boot:spring-boot-starter-web-services')
        compile('org.springframework.boot:spring-boot-starter-webflux')
        compile('org.springframework.data:spring-data-rest-hal-browser')

        compileOnly "org.springframework.boot:spring-boot-configuration-processor"

        testCompile('org.springframework.boot:spring-boot-starter-test')
        testCompile('io.projectreactor:reactor-test')
    }
}
  1. bootWar를 비활성화한다.

  2. war를 활성화한다.

정리

  • 기술을 사용할 때는 참고문서를 보자.

참고문헌


http://www.yes24.com/24/goods/62112463

나올 듯 안나올 것만 같았던 책이 드디 세상에 모습을 드러냈습니다. 스프링 부트에 대한 참고서 처럼 이용하시면 되겠습니다.

예제: https://github.com/ihoneymon/boot-spring-boot

스프링 부트와 관련된 질문을 이슈로 등록해주시면,
답변드릴 수 있는 부분에서는 성심성의껏 답변드리겠습니다. +_+)

버전은 당연히 2.0 에 맞춰져 있습니다.

#bootspringboot

P.S. 혹시나 다음에 쓸 지도 모를 이야기는... Boot MSA!! 입니다.

그게 언제가 될지는 아무도 모릅니다. 음트트


스프링 부트를 사용하면 스프링 부트 레퍼런스 문서를 정말 많이 보게 됩니다. 영어라 막막할 떄가 있습니다.

그럴 때 옆에 두고 펼쳐보면 조금은 도움이 되는 책이라고 생각합니다.


오탈자

많은 과정을 거치면서 책에 오탈자를 수정하지만 책으로 출간해도 오탈자가 들어가 있는 경우가 많습니다. 저도 새로운 책을 사면 오탈자를 찾느라 책의 내용은 머리에 담지 못하고는 합니다. 오탈자를 찾으실 경우에는 다음에 있는 정오표에 기입해주시면 다음 인쇄에서는 수정하여 나올 수 있도록 노력하겠습니다.


찾아보기(index)

많은 과정을 거치면서 책에 오탈자를 수정하지만 책으로 출간해도 오탈자가 들어가 있는 경우가 많습니다. 저도 새로운 책을 사면 오탈자를 찾느라 책의 내용은 머리에 담지 못하고는 합니다. 오탈자를 찾으실 경우에는 다음에 있는 정오표에 기입해주시면 다음 인쇄에서는 수정하여 나올 수 있도록 노력하겠습니다.



P.S. 8월 말에 50여 분을 모시고 1~2시간 내외의 세미나를 진행할 계획입니다.

[spring-boot] gradle multi module 사용하면서 gradle plugin bootJar.enabled=false 선언했을 때 jar 파일 생성안된다면

멀티 모듈을 가지는 스프링 부트 기반의 멀티프로젝트를 구성하는 과정에서 조금 당황스런 상황을 겪었다.

bootJar.enabled=false

빌드 했을 때 위처럼 선언된 공통 모듈이 빌드된 배포본에 포함되지 않는 상황이 발생했다.

Note

인텔리제이에서 테스트 러너를 그레이들로 설정하지 않으면 당황스런 순간을 맞이하게 된다.

인텔리제이 기본 테스트 러너에서는 인텔리제이에서 컴파일한 build 디렉터리를 기반으로 테스트를 진행해서 별다른 문제가 없지만 그레이들 빌드 테스트의 경우에는 컴파일 및 빌드를 하면서 테스트가 진행되는데 위에서 언급한 bootJar.enabled=false만 선언된 모듈은 jar 파일을 생성하지 않기 때문에 이를 참조하는 하위 모듈에서 관련된 파일을 읽어오지 못하게 된다.

이와 관련된 문제를 찾아보다가 발견한 한줄기 빛!

마지막 댓글을 보면

bootJar.enabled=false
jar.enabled=true

jar.enabled=true 옵션을 추가하면 Jar 파일 생성이 진행된다. 우후!

스프링 부트에서 bootRepackage 에서 bootJar 로 변경되면서 뭔가 이상한 짓을 한 듯 하다.

Note

BootJar 문서를 살펴보면 확장하면서 재정의한 영향으로 보인다. jar.enabled 옵션을 활성화한다.

+ Recent posts