-
1. 그레이들 멀티프로젝트 - 셋업하기스프링개발자/301 - 아키텍처 2020. 8. 30. 02:11
[배경]
반복되는 코드 줄이기 쉽다.
여러 어플리케이션을 하나의 git repo에서 관리하기 쉽다.
참고: https://docs.gradle.org/current/userguide/multi_project_builds.html
1. Intellij IDEA 프로젝트 생성
Spring Initializr를 쓴다. 특별한 것은 없고 대략의 설정은 다음과 같다;
group: com.example
Type: Gradle Config (Generate a Gradle build file.)
Artifact: monorepo
Packaging: Jar
프로젝트를 처음 설정하면 나오는 다음의 tip들을 yes 한다;
configure automatically
auto import
다음의 오류가 떴다. 나의 현재 gradle 버전이 오래되서 plugin을 못쓴다는 말인데
나의 gradle버전을 확인해보니 정말 5.2.1. 플러그인을 쓰기 위해 최신으로 업데이트 해준다.
gradle wrapper를 다운받아서 root 디텍토리에 넣으면 된다. 6.4.1 폴더가 생겼다.
짜잔, 회색으로 나왔던 키워드들이 흰색으로 변함(인식함)
첫 키워드 plugins를 ctrl+click 해보면
새로 받은 gradle 6.4.1에서 인식
2. Multi-Module 만들기
Gradle project with Java
다음의 이름들로 모듈 2개 생성: main-application, weather-application
main 메소드가 들어가 있는 어플리케이션 클래스를 만든다.
package com.example.monorepo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); } }
import를 하였음에도, 아래 그림의 9번째 줄에 컴파일 에러가 생긴다.
gradle refresh를 누르면 3번,4번줄에 있는 import 또한 회색으로 변하면서 인식하지 못한다.
이것은 root폴더에 있는 build.gradle이 main-application에 적용되지 못해서 생기는 문제다.
main-application폴더에 build.gradle이 root폴더의 것을 덮어쓰고 있기 때문이다.
3. Gradle subprojects
subproject가 이 글의 핵심키워드이다.
root 폴더에 있는 build.gradle이 모든 subproject들에 적용되도록 gradle subprojects 를 추가한다.
그 안에 dependency 정보를 넣어준다. 앞으로 생성되는 subproject들에 공통적으로 여기의 의존성이 자동적용된다.
subprojects { group 'com.example.monorepo' apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' apply plugin: "jacoco" repositories { jcenter() mavenCentral() mavenLocal() maven { url "https://oss.sonatype.org/content/repositories/snapshots" } maven { url 'http://repo.hortonworks.com/content/repositories/releases/' } maven { url "https://repo.spring.io/plugins-release/" } maven { url "https://repo.spring.io/libs-release/" } } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" mavenBom "io.pivotal.spring.cloud:spring-cloud-services-dependencies:${springCloudServicesVersion}" } } dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.cloud:spring-cloud-config-server' implementation 'org.springframework.cloud:spring-cloud-starter-config' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } } }
이후에 gradle re-import를 하면, 메인클래스 9번째 줄의 빨간줄이 없어진것을 볼 수 있다.
마지막으로, main-application에 포트넘버와 이름을 설정한다
server.port=8080 spring.application.name=main-application
weather-application또한 다음과 같이 설정한다
server.port=8081 spring.application.name=weather-application
4. 눈으로 확인해보자
MainApplication을 실행한다
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8080
WeatherApplication또한 실행한다 8081포트에서 실행되었다.
하나의 repository에 있기 때문에 의존성 및 자원관리도 쉽고 효율적이다.
5. Gitrepo initial commit
다음의 이름으로 repo를 생성하였다. https://github.com/2ndPrince/monorepo
Intellij Terminal에서 코드를 push하자
예전 글(https://2ndprince.tistory.com/11?category=880036)에서 발췌
이렇게 해서 하나의 git repository 안에 multiple application이 잘 동작하는 프로젝트 완성!
의존성을 쉽게 관리 할 수 있음
모든 소스코드
https://github.com/2ndPrince/monorepo/tree/monorepo_first
[TroubleShooting]
1. 어플리케이션이 잘 작동되고 있는데, run텝에 error trace들이 생긴다.
2020-08-29 13:04:28.579 ERROR 16496 --- [ main] c.n.d.s.t.d.RedirectingEurekaHttpClient : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://localhost:8761/eureka/} com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect ... com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
eureka서버를 찾지 못해서 나오는 에러인데, 당장 어플리케이션 구동에는 문제가 없다.
root build.gradle에서 다음의 implementation을 지우고, 어플리케이션을 다시 동작하면 문제가 사라진다.
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
하지만, 곧 eureka application을 만들거라서 의존성을 냅두자. autoconfigure로 가져온 bean 중에 euraka server와 client를 밝혀줘야 되는게 있는데, 우리가 정보를 주지 않아서 그렇다.
'스프링개발자 > 301 - 아키텍처' 카테고리의 다른 글
5. 그레이들 멀티프로젝트 - 데이터베이스 셋업 및 활용(1) - Entity, CollectionTable, 데이터베이스값 불러오기 (0) 2020.10.05 4. 그레이들 멀티프로젝트 - 유레카서버와 페인클라이언트 Eureka FeignClient (0) 2020.08.31 3. 그레이들 멀티프로젝트 - RestTemplate (0) 2020.08.30 2. 그레이들 멀티프로젝트 - 공통자원 활용(compile project) (0) 2020.08.30 스프링개발자 301 - 프로젝트 아키텍처 (0) 2020.08.13