본문으로 건너뛰기

JSP Project에 CI/CD를 할 수 있도록 설정하기 (feat. JSP + Gradle Project 만들기)

 · reading-time-plural · 

CI/CD 가 무엇인지 아는데 불구하고 JSP 를 이용해 제작된 웹 애플리케이션 제품을 만들면서 수동으로 배포하는 것에 대해 아쉬움을 느낄 때가 많았다. 그동안 개발부터 배포까지 Full Workload를 자동화 해보고 싶었는데 이번 기회에 제작을 시도해보려고 한다.

처음이라 그런가 2 ~ 3주 정도 삽질을 하게 되었었으며 열심히 삽질한 결과를 자세히 리포팅 해보도록 하겠다.

note
  1. 해당 글에서 CI/CD 가 무엇인지 다루지 않습니다.
  2. IntellJ IDEA IDE를 이용하여 프로젝트를 설정합니다.

근데 CI/CD 에서 어떻게 Build 하지?

사실 CI/CD 는 별거 없다 지속적으로 통합/배포 하기를 위해서 project source code를 가져오고 build 하고 이후 추가 적업을 끼워 넣어서 진행하면 된다.

사실 Pipelines 아라고 말하는 게 더 명확할 수 있다.

근데 문제는... CI/CD 환경에서 Build 작업을 진행하기 위해서는 CLI 으로 Buuld를 할 수 있어야 하는데 이 부분을 어떻게 할지 몰랐다.

CI/CD 를 위해서 가장 첫 번째 관문은 IDE 외에서 빌드가 수행돼야 하는 점이었던 것이다.

이 부분에서 가장 많이 시간을 소비하게 되었는데 살면서 IDE에 의존해서 빌드와 Release를 진행했었지 CLI으로 빌드 해본 적이 없었기 때문이다.

이 부분에 대해서 많은 리처시가 필요했는데 결론적으로는 jsp 프로젝트에 Gradle을 사용하는 것이였다.

찾으면서 알게된 것으로 JSP의 Framework인 spring , spring boot 은 기본적으로 Gradle이 붙어있다고 한다.

요즘 시대에 동적인 웹 페이지를 위해 jsp 생짜로 개발하는 개발자는 많지 않을 것이다. 이 때문에 Framework를 이용하지 않고 jsp 자체에 Gradle를 사용하는 Docs와 레퍼런스가 굉장히 적었다.

더구나 JSP가 오래된 기술이라서 이런 기술에 CI/CD 를 구성하는 글도 찾기가 어려웠다.

그래서 해당 글에서는 IntellJ IDEA 으로 구성된 JSP Project에 Gradle 를 부착하여 Build 하는 것이 주된 내용이 될 것이다.

Empty Project 생성

모듈을 포함한 Project 생성시 모듈 디렉토리가 생성되지 않기 때문에 Empty Project부터 생성합니다.

모듈 생성

왼쪽에서 Gradle를 클릭 후 반드시 Web으로 생성해야한다.

note

Java 모듈로 선택 후 나중에 프레임워크 지원 추가웹 서비스 를 추가하는 방법은 Gradle에서 Build 된 .war 이 정상적으로 동작하지 않는다. 해결 방법은 추가적인 R&D가 필요해 보임.

caution

Empty Project에 모듈을 추가하는 거므로 저장 경로를 주의하기 바란다!

설정의 속성의 다음과 같습니다.

속성설명
GroupIdGradle를 고유하게 식별하는 값이다. 주로 도메인 주소를 거꾸로 적는 것으로 알고 있다.
ArtifactIdBuild되는 아티펙트 이름이다. 주로 module의 이름이며 IntellJ에서 알아서 module와 같은 이름으로 지정해 준다. 나중에 Gradle Script으로 변경가능
버전아티펙트 뒤에 - + 0.1으로 조립되는 값이다. 나중에 Gradle Script으로 변경가능

하이어라키 구조

생성된 하이어라키 창이다. 중요한 부분만 짚도록 하겠다.

디렉토리내용
build.libsGradle에서 Build 파일이 저장되는 위치
main.javajsp의 servlet
main.webappjsp web이다 jsp 파일이 들어간다
test.javaunit test에 필요한 코드를
build.gradleGradle의 Build 및 Task와 라이브러리 종속성 추가를 위한 Script를 작성하는 곳
gradlew유닉스용 실행 스크립트
gradlew.bat원도우용 실행 배치 스크립트
settings.gradleGradle이 사용되는 rootProject를 지정하는 곳
info

gradlew or gradlew.bat 가 있기 때문에 로컬 PC마다 Gradle이 install 되어있지 않아도 build.gradle가 실행 가능한 것이다.

실행 환경 구성

빌드 자동화 툴인 Gradle을 사용하기 때문에 더 이상 IntellJ의 아티팩트를 Tomcat에 배치하지 않아도 된다.

앞으로 Gradle에서 build .war 파일을 사용할 것이다.

build된 파일의 경로를 알기 위해서 1회 buiild를 진행하도록 하겠다.

1회 build 실행

Gradle의 build를 실행하니 build\libs 경로에 .war 파일이 생성되는 것을 확인할 수 있다.

tip

옆에서 클릭된 Tasks들은 하나의 명령어 들이다 즉, CLI를 이용해 실행이 가능하다.
IDE에서 클릭하면 IDE가 해주는거 같아 보이지만 백단에서는 모두 shell기반으로 실행되고 있다.

CLI으로 실행 방법이 궁금하면?
PowerShell으로는 실행되지 않았습니다.
  1. 해당 프로젝트의 gradlew 이 있는 위치로 이동한다.
  2. gradlew [원하는 Tasks 입력] 을 실행한다.
  3. 실행 결과 화면

일반 jsp 빌드 프로세스

일반 적인 jsp 프로젝트에서 빌드를 하고 배포한다면 아래와 같은 프로세스로 진행된다.

  1. Tomcat 9.0.37 의 실행/디버그 구성이 실행됨
  2. 실행 전 에서 단계에서 아티팩트가 빌드됨
    • IDE 자체 방식으로 .war 파일이 생성됨
  3. Deploy at the server startip 의 파일이 Server으로 배포됨
    • build된 .war 파일이 애플리케이션 컨텍스트 경로로 Tomcat에 배포됨

우리는 여기서 Gradle으로 build 하도록 하고 .war 의 경로만 바꾸면 된다.

Gradle 빌드 프로세스

새로운 실행/디버그 구성을 만들도록 하겠다. 구성 편집을 클릭한다.

왼쪽 상단의 + 버튼을 클릭하여 Tomcat 로컬을 클릭한다.

배포탭을 클릭한뒤 하단의 + 클릭 후 Gradle 작업 실행을 클릭한다.

현재 사용하는 모듈을 선택한다.

우리는 Tasks중 build를 실행할 것이므로 작업에 build를 입력한 뒤 확인을 클릭한다.

이제 build된 .war 경로를 지정해 줘야 한다. 오른쪽의 + 클릭 후 외부 소스를 클릭한다.

이전에 build된 파일 경로를 선택한다.

\build\libs\.war

note

현재 스크린샷은 위에서 가이드한 ProjectName과 Module 이름이 다르게 되어있습니다.

최종 반영된 프로세스이다.

실행

정상적으로 실행되는 것을 확인할 수 있다.

WEB-INF 추가하기

Gradle jsp Project는 \WEB-INF\web.xml 을 포함하고 있지 않기 때문에 알아서 만들어줘야 한다.

WEB-INF 생성

web.xml 생성

web.xml 기본 스키마 작성

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>

Gradle dependencies 추가

Gradle을 사용하기 때문에 일일이 프로젝트에 라이브러리를 연결하지 않아도 빌드툴이 알아서 라이브러리 종속성을 추가할 수 있다.

기본적으로 jsp build를 위해 필요한 library들이 있다.

javax.servlet:javax.servlet-api:4.0.1

javax.servlet으로 컴파일 해서 war 파일을 생성한다는 의미입니다.

해당 라이브러리가 없으면 컴파일에 실패합니다.

info

javax.servlet 으로 컴파일 해서 war 파일을 생성한다는 의미 입니다.

javax:javaee-api:8.0.1

Java EE이다. 가장 많이 사용되는 부분은 jsp에서 out 함수 사용시 이용된다.

혹은 compile group: 'javax', name: 'javaee-api', version:'7.0' 도 가능하다.

Java EE 추가 이유
PrintWriter out = response.getWriter();
out.println("<html><head></head><body></body></html>");

response.getWriter() 는 javax에 포함되는 함수입니다.

Java EE를 라이브러리로 추가하지 않고 사용시 IDE상에서는 오류를 뱉지만 Tomcat내부에는 해당 함수가 있기 때문에 실제 동작에서는 문제가 없습니다.

하지만, IDE에서 제공하는 자동완성과 오류체크를 위해서는 해당 라이브러리를 IDE에 추가하는 방법이 옳습니다.

최종 Gradle dependencies script

dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
// servlet api
compile 'javax.servlet:javax.servlet-api:4.0.1'
// java EE (jsp에서 out함수때 사용됨)
compile 'javax:javaee-api:8.0.1'
}

이외 주의할 것

IDE가 기본적으로 스캐폴드로 잡아주는 스트럭처를 유지하고 싶다면

git에서 Empty Folder는 형상관리 되지 않습니다.

IDE가 기본적으로 스캐폴드로 잡아주는 스트럭처를 유지하고 싶다면 java 및 test 모듈, resource에 *.txt 와 같은 파일을 한 개 라도 포함하여 유지하도록 한다.

note

사실 굳이 추천하지 않는 이상한 가이드 입니다.
IDE가 기본적으로 잡아주는 스트럭처를 다 이해하지 못해서 어떻게든 기본 구조를 가져고 싶은 경우에 눈물을 흘리며 해당 전략을 사용하도록 한다.

Gradle Module 인식 못하는 경우

build.gradle 파일에서 Gradle 프로젝트 가져오기를 클릭하면 됩니다.

마무리

글의 내용이 JSP Project에 Gradle을 도입하는 것을 중점으로 작성되었다.

CI/CD 는 특정 이벤트 발생 시 추가적으로 작업해주는 Agent 머신이라고 생각해도 된다. 머신이기 때문에 GUI와 같이 사람으로 하는 작업을 명령할 줄 알아야 하는데 JSP Project에서 이 방법을 몰라서 고생 고생하여 Gradle 을 사용하는 방법으로 진행되었다.

이제 원하는 CI/CD Service를 이용해서 JSP Project를 Build 하고 추가 적업을 진행할 수 있을 것이다.

읽어주셔서 감사합니다 :)

Reference

  1. Eclipse에서 디렉터리 구조와 사용되는 라이브러리 및 JSP를 이용하여 빌드자동화 도구인 그레이드 사용법이 잘 나와있음
  2. 톰캣 9.0 버전 이상 servlet-api 오류 해결 방법
  3. Spring boot를 통해서 JSP를 연결해야하는 이유
  4. Spring Boot와 jsp 연동법
    1. 해당 링크로 성공함
    2. application properties(application.yaml) 설정법만 확인
  5. library 종속성 추가: jetty 서버를 이용한 방법
  6. Docker tomcat 8.5 컨테이너에 웹 어플리케이션(war) 배포하기