728x90

목차

     

    Maven에서 Gradle로 마이그레이션 하게 된 이유

    레거시로 무거워진 솔루션을 맡게 되면서 Maven의 한계를 경험하게 되었다. 극복하기 위해 발전된 빌드 도구인 Gradle을 알게 되었고 마이그레이션을 하기로 결심한 계기가 되었다. 조금 더 자세한 내용은 아래 게시글에서 확인하자!

    https://jfbta.tistory.com/269

     

    Maven이 아닌 Gradle을 사용하자!

    목차 "Maven이 아닌 다른 빌드 도구를 찾다!" 그 동안 개발을 하면서 빌드 도구에 중요성을 인지하지 못했다. 하지만 담당하게 된 빅데이터 모니터링 웹 프로젝트의 빌드 속도가 5분 이상이 걸려 Ja

    jfbta.tistory.com

     

    gradle 설치 및 환경변수 설정

    Maven에서 Gradle로 변경할 때 gradle init 명령어를 사용하면 완벽하진 않지만 대부분 변환시켜준다. 이 명령어를 사용하기 위해 Gradle 설치와 환경변수 설정이 필요하다.

    설치는 공식사이트(https://gradle.org/releases/)에서 하면된다.

    원하는 경로에 설치한다. 필자는 C:\gradle-8.1.1 -> 이 경로에 설치하였다.

    설치 후 환경변수가 중요한데 환경변수는 키보드에서 윈도우 + Pause를 동시에 누른다. 그럼 Windows 11 기준 다음과 같은 화면이 나타날 것이다.

    고급 시스템 설정 버튼을 클릭하자.

    '환경 변수' 버튼을 클릭하자.

    '새로 만들기' 버튼 클릭 한다. 이후 변수 이름에 'GRADLE_HOME'과 변구 값: 설치한 경로를 작성하고 '확인'

    다시 시스템 변수 목록에 Path를 더블클릭 하고 제일 앞에 '%GRADLE_HOME%\bin;'를 입력한 후 '확인'

    cmd를 관리자 권한으로 실행한 후 명령어 'gradle -v'를 입력해서 설치와 설정이 되었는지 확인할 수 있다.

     

    Maven -> Gradle로 변환하기

    cmd 관리자 권한 실행 후 변환할 Maven 프로젝트의 pom.xml이 위치한 경로로 이동한다.

    이동 후 gradle init 명령어를 입력하면 3개의 질문을 던질 것이다.

    1. Found a Maven build. Generate a Gradle build from this? (default: yes) [yes, no]
    2. Select build script DSL:
       1: Groovy
       2: Kotlin
    Enter selection (default: Groovy) [1..2] 
    3. Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no]

    1. Maven 빌드를 찾았으며 Gradle로 빌드할 것인지 묻는 것이다. yes를 선택하자.

    2. DSL언어는 Groovy로 선택했다.(원하는 것으로 선택)

    3. 새로운 API를 사용할 것인지 묻는 것인데 잘 모르니 default로 선택하자!

    여기까지 따라왔다면 gradle 업데이트 후 프로젝트 빌드를 실행하면 정상적으로 될 수도 오류가 발생할 수도 있다. 발생한 오류는 추가적으로 조치해야 한다. 필자는 spring webmvc 환경에서 일부 문법 오류가 발생하였다.

    변경 전 Maven 코드

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
           http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.test.project</groupId>
        <artifactId>project-web</artifactId>
        <name>project-web</name>
        <packaging>war</packaging>
        <version>3.1.0-SNAPSHOT</version>
    
        <dependencies>
            <!-- ================== -->
            <!--  외부 라이브러리 설정 -->
            <!-- ================== -->
    
            <dependency>
                <groupId>commons-httpclient</groupId>
                <artifactId>commons-httpclient</artifactId>
                <version>3.1</version>
                <scope>system</scope>
                <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/commons-httpclient-3.1.jar</systemPath>
            </dependency>
    
            <!-- =================== -->
            <!--  JDBC Dependencies  -->
            <!-- =================== -->
    
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>${postgresql.version}</version>
            </dependency>
    
            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>${hikaricp.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <!-- ========== -->
            <!--  Test API  -->
            <!-- ========== -->
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
                <scope>test</scope>
            </dependency>
    
            
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
    
        </dependencies>
    
    
        <build>
            <defaultGoal>install</defaultGoal>
            <directory>${basedir}/target</directory>
            <finalName>ROOT</finalName>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.1.0</version>
                    <executions>
                        <execution>
                            <id>default-war</id>
                            <phase>package</phase>
                            <goals>
                                <goal>war</goal>
                            </goals>
                            <configuration>
                                <warSourceDirectory>src/main/webapp</warSourceDirectory>
                                <webResources>
                                    <resource>
                                        <directory>src/main/webapp/WEB-INF</directory>
                                        <filtering>true</filtering>
                                        <targetPath>WEB-INF</targetPath>
                                        <includes>
                                            <include>app.properties</include>
                                            <inclide>config-prd.properties</inclide>
                                            <inclide>config-dev.properties</inclide>
                                        </includes>
                                    </resource>
                                </webResources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.20.1</version>
                    <configuration>
                        <systemPropertyVariables>
                            <io.springfox.staticdocs.outputDir>${swagger.output.dir}</io.springfox.staticdocs.outputDir>
                            <io.springfox.staticdocs.snippetsOutputDir>${swagger.snippetOutput.dir}</io.springfox.staticdocs.snippetsOutputDir>
                        </systemPropertyVariables>
                    </configuration>
                </plugin>
    
    
            </plugins>
    
            <testResources>
                <testResource>
                    <directory>src/main/webapp</directory>
                </testResource>
                <testResource>
                    <directory>src/main/webapp/WEB-INF</directory>
                </testResource>
            </testResources>
        </build>
    
    
    </project>
    

     

    자동 변환(gradle init)

    /*
     * This file was generated by the Gradle 'init' task.
     */
    
    plugins {
        id 'java-library'
        id 'maven-publish'
    }
    
    repositories {
        mavenLocal()
        maven {
            url = uri('https://repo.maven.apache.org/maven2/')
        }
    }
    
    dependencies {
        api 'org.postgresql:postgresql:42.2.19'
        api 'com.zaxxer:HikariCP:2.6.2'
        testImplementation 'org.springframework:spring-test:4.3.2.RELEASE'
        providedCompile 'org.projectlombok:lombok:1.18.10'
        system 'commons-httpclient:commons-httpclient:3.1'
    }
    
    group = 'com.test.project'
    version = '3.1.0-SNAPSHOT'
    description = 'project-web'
    java.sourceCompatibility = JavaVersion.VERSION_1_8
    
    publishing {
        publications {
            maven(MavenPublication) {
                from(components.java)
            }
        }
    }

     

    프로젝트 환경에 맞게 변경

    /*
     * This file was generated by the Gradle 'init' task.
     */
    
    plugins {
        id 'java-library'
        id 'war'
    }
    
    group = 'com.test.project'
    archivesBaseName = 'ROOT'
    //version = '3.3.0-SNAPSHOT'
    
    java {
        sourceCompatibility = '8'
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'org.postgresql:postgresql:42.2.19'
        implementation('com.zaxxer:HikariCP:2.6.2') {
            exclude group: 'org.slf4j', module: 'slf4j-api'
            exclude group: 'org.slf4j', module: 'slf4j-log4j12'
        }
        
        testImplementation 'org.springframework:spring-test:4.3.2.RELEASE'
        
        providedCompile 'org.projectlombok:lombok:1.18.10'
        annotationProcessor 'org.projectlombok:lombok:1.18.10'
    
        implementation fileTree(dir: 'src/main/webapp/WEB-INF/lib', includes: ['*.jar'])
    }
    
    tasks {
        war {
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
        }
    }
    

    - lombok에러가 발생하여 annotationProcessor를 추가

    - slf4j와 logback 라이브러리 충돌 이슈로 exclude 옵션 추가(https://jfbta.tistory.com/274)

     

    [Error] ClassCastException: org.slf4j.impl.Log4jLoggerAdapter cannot be cast to ch.qos.logback.classic.Logger

    이 에러가 발생한 원인은 logback, slf4j 라이브러리가 충돌하면서 cast(* 한 타입의 값을 다른 타입의 값으로 변환)할 수 다는 에러가 발생한 것이다. 필자는 Maven에서 Gradle로 마이그레이션 하는 과정

    jfbta.tistory.com

    - war실행 시 dupblicate에러로 EXLUDE 문법 추가(https://jfbta.tistory.com/275)

     

    [Error] is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/8.1.1/dsl/org.gr

    Maven에서 Gradle로 마이그레이션 하는 과정에서 해당 에러가 발생하였다. 굉장히 쉽게 해결할 수 있었다. tasks { war { duplicatesStrategy = DuplicatesStrategy.EXCLUDE } } tasks { war { duplicatesStrategy = DuplicatesStrategy

    jfbta.tistory.com

     

     

    외부라이브러리 참조 문법이 system 'shared:3.1' -> 이런 형식으로 변환되었다. 잘못된 문법이어서 아래 방식으로 변경해야한다.

    // 변경 전
    system 'org.uengine.metaworks:metaworks-dwr:1.0.1'
    system 'commons-httpclient:commons-httpclient:3.1'
    // 변경 후
    implementation fileTree(dir: 'src/main/webapp/WEB-INF/lib', includes: ['*.jar'])

     

    Intellij 실행 환경세팅

    1) pom.xml 제거

    2) Libraries 설정

    - Ctrl + Alt + Shift  + S로 세팅 팝업을 열고 intellij 로컬 설치된 Maven 라이브러리 모두 삭제

    3) Gradle 라이브러리 Load

    - build.gradle 파일을 열고 우클릭 후 'Link Gradle Project'를 클릭

     

    4) Artifacts와 Facets 설정

    - Gradle을 load하면 아래 이미지와 같이 'Gradle : project : ROOT.war'와 ' Gradle : project : ROOT.war (exploded)'가 자동으로 생성된다. 이것을(빨강박스) 제외한 기존에 등록된 Artifacts와 Facets를 모두 제거

     

    5) Project 설정

    gradle로 구성된 프로젝트 파일 구조

    - Project 탭으로 이동해서 Compiler output에 out폴더 path 설정(파일 구조 이미지 참고)

    ex) ~\IdeaProjects\spring-webmvc\out

    6) Modules 설정

    - Deployment Descriptors 탭에서 + 클릭 후 web.xml 선택

    ex) \src\main\webapp\WEB-INF\web.xml

    - Web Resource Directories 탭에서 + 클릭 후 webapp 선택

    exm) \src\main\webapp

     

    Tomcat 설정

     

     

     

    Tomcat 테스트 - war 배포 파일 생성

     

    마이그레이션 전과 후 성능 비교

    1) 비교용 프로젝트 스펙

    - 개발 환경 : Spring webmvc, Tomcat, (Maven -> Gradle)

    - 파일  사이즈 : 대략 500MB

     

    2) 빌드 소요시간 비교

    jenkins 설정까지 마친 후 빌드 시간을 비교해보았다. 기존 maven으로 빌드한 경우 5분 16초가 걸렸다. 반면에 Gradle을 적용한 이후엔 2분 51초로 약 2분 25초나 낭비되는 시간이 줄었다.

    728x90
    TOP